connaxis

package module
v0.0.0-...-7a23388 Latest Latest
Warning

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

Go to latest
Published: Apr 30, 2026 License: MIT Imports: 31 Imported by: 0

README

connaxis

Go LICENSE

connaxis is a Linux-first event-driven networking framework for Go with integrated TLS/kTLS, WebSocket/WSS, long-lived connection support, and reproducible protocol validation workflows. It uses direct epoll / kqueue syscalls instead of the standard Go net server path, and follows a model similar to libuv and libevent.

The project targets high-connection-count workloads such as gateways, proxies, and long-lived connection services. It is primarily built and validated for Linux; on macOS and BSD, the goal is basic end-to-end path validation rather than feature parity with Linux.

Positioning

connaxis is positioned as a Linux-first Go networking runtime for gateway/proxy and long-lived connection scenarios, with integrated TLS/kTLS and WS/WSS support.

In more conventional Go server designs, HTTP/TLS/WebSocket handling is typically built on blocking per-connection goroutine paths, and WebSocket deployments often end up with separate read/write goroutines per connection. connaxis aims to keep these long-lived protocol paths on the event-driven side instead, reducing per-connection goroutine, scheduling, and stack-memory overhead.

Compared with projects that mainly optimize plain TCP event-loop throughput, connaxis focuses on protocol integration and validation:

  • event-driven core for TCP/HTTP/WebSocket workloads
  • built-in TLS support with kTLS integration path
  • reproducible compatibility validation workflows

Compared with projects such as evio, gnet, and netpoll, connaxis puts more emphasis on TLS/kTLS, WS/WSS, and reproducible validation workflows than on plain TCP event-loop throughput alone.

This project is not positioned as a replacement for OpenSSL, and it does not claim full parity with OpenSSL on all TLS edge-case behaviors.

See:

  • docs/README.md
  • docs/test/README.md

Project Status

  • Active development
  • Public module path: github.com/bernardhu/connaxis
  • CI: go test ./... and go vet ./... via GitHub Actions

Community / Governance

  • Contributing guide: CONTRIBUTING.md
  • Contributor roadmap: ROADMAP.md
  • Security policy: SECURITY.md
  • Code of Conduct: CODE_OF_CONDUCT.md
  • Changelog: CHANGELOG.md

Features

  • event-loop based architecture with low overhead
  • per-loop listener model with SO_REUSEPORT enabled by default
  • TCP-focused runtime model
  • optional TLS / kTLS integration path
  • WebSocket / WSS support (via plugin package)

Getting Started

Installing

Requires Go 1.24.2.

go get github.com/bernardhu/connaxis

New Contributors Start Here

If you want to make a first contribution:

  1. Read CONTRIBUTING.md for the contribution rules and validation steps.
  2. Read ROADMAP.md for the current task buckets and change boundaries.
  3. Run one of the examples in examples/README.md to get a local mental model.
  4. Run go test ./... before and after your change.

Recommended first-change areas:

  • docs and example fixes
  • focused tests for protocol edge cases
  • narrow validation or benchmark script improvements

Before making a large runtime or API change, read:

  • design/constraints.en.md
  • docs/API_BOUNDARY.md
  • design/README.en.md

Usage

Example echo server that binds to port 5000:

package main

import (
	"flag"
	"log"

	"github.com/bernardhu/connaxis"
	"github.com/bernardhu/connaxis/connection"
	"github.com/bernardhu/connaxis/eventloop"
)

var path string

type handler struct {
}

func (h *handler) OnReady(s eventloop.IServer) {
	log.Printf("ready: listen on %v (loops: %d)", s.GetListenAddrs(), s.GetWorkerNum())
}

func (h *handler) OnClosed(c connection.AppConn, err error) {}

func (h *handler) OnConnected(c connection.ProtoConn) {
	c.SetPktHandler(h)
}

func (h *handler) ParsePacket(c connection.ProtoConn, in *[]byte) (int, int) {
	return len(*in), len(*in)
}

func (h *handler) OnData(c connection.ProtoConn, in *[]byte) ([]byte, bool) {
	out := *in
	return out, false
}

func (h *handler) Stat(bool) {}

func main() {
	flag.StringVar(&path, "p", "connaxis.conf", "config file path")

	flag.Parse()
	var h handler
	if err, _ := connaxis.Serve(&h, path); err != nil {
		log.Fatal(err)
	}
}

User should provider a handler, which ParsePacket tell the eventloop the packet length and expected length, and OnData which handle the data.

Also a config file should be provided in JSON format, like:

{
	"ncpu": -1,
	"lbStrategy": "rr",
	"sslPem": "",
	"sslKey": "",
	"sslMode": "",
	"bufSize": 1048576,
	"chanSize": 8192,
	"listenAddrs": ["tcp://:5000?reuseport=false"]
}

Examples

See examples/README.md for runnable echo/TLS/HTTP/FastHTTP/WebSocket examples.

Configuration

See docs/config/CONFIG.md for config fields and defaults.

Public Package Surface

The intended public package surface is:

  • github.com/bernardhu/connaxis
  • github.com/bernardhu/connaxis/connection
  • github.com/bernardhu/connaxis/eventloop
  • github.com/bernardhu/connaxis/websocket
  • github.com/bernardhu/connaxis/evhandler

Packages under internal/ are implementation details. Listener/dial/server wiring in the root package is also implementation detail, not a separately supported framework module.

Further docs:

  • docs/config/HTTP_ADAPTERS.md
  • docs/config/METRICS.md
  • ROADMAP.md
  • design/constraints.en.md
  • design/performance_methodology.en.md

Changelog

See CHANGELOG.md.

Concurrency / Thread-safety

  • Handler callbacks run on the event-loop goroutine.
  • connection.EngineConn.Recvbuf() and Read/Write/FlushN are not goroutine-safe; only use them from handler callbacks (or other code running on the owning loop).
  • To send from other goroutines, use connection.AppConn.AddCmd(...). The []byte payload is copied; you may reuse it after the call returns.

Contact

  • General questions and feature requests: GitHub Issues
  • Direct contact: bernard.hu@gmail.com

License

connaxis source code is available under the MIT License.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type DialParam

type DialParam struct {
	Addr     string
	Cert     string
	Key      string
	Typ      string
	SslType  int
	Duration time.Duration
	On       func(string, string, uint64)
	Close    func(string, string, uint64)
	Probe    func(string) []byte
	Handler  connection.IPktHandler
}

type Dialer

type Dialer struct {
	// contains filtered or unexported fields
}

func (*Dialer) AddBuf

func (d *Dialer) AddBuf(buf []byte) int

func (*Dialer) Addr

func (d *Dialer) Addr() string

func (*Dialer) BufLen

func (d *Dialer) BufLen() int

func (*Dialer) Close

func (d *Dialer) Close()

func (*Dialer) Flush

func (d *Dialer) Flush() error

func (*Dialer) GetID

func (d *Dialer) GetID() uint64

func (*Dialer) LastFlush

func (d *Dialer) LastFlush() int64

func (*Dialer) SetWatcher

func (d *Dialer) SetWatcher(watch IDialWatch)

func (*Dialer) Underlying

func (d *Dialer) Underlying() connection.EngineConn

type DialerMng

type DialerMng struct {
	// contains filtered or unexported fields
}

func (*DialerMng) KeepAlive

func (m *DialerMng) KeepAlive()

func (*DialerMng) OnClose

func (m *DialerMng) OnClose(itf interface{})

func (*DialerMng) OnOpen

func (m *DialerMng) OnOpen(itf interface{})

func (*DialerMng) Polling

func (m *DialerMng) Polling()

func (*DialerMng) Stat

func (m *DialerMng) Stat(now int64, print bool)

type DialerStatus

type DialerStatus struct {
	// contains filtered or unexported fields
}

type EVEndpoint

type EVEndpoint struct {
	Address string
	Net     string
	Reuse   bool
	Ctx     context.Context
}

func (*EVEndpoint) GetContext

func (ep *EVEndpoint) GetContext() interface{}

func (*EVEndpoint) IsReuse

func (ep *EVEndpoint) IsReuse() bool

func (*EVEndpoint) Network

func (ep *EVEndpoint) Network() string

func (*EVEndpoint) String

func (ep *EVEndpoint) String() string

type EvConfig

type EvConfig struct {
	Ncpu                      int                     `json:"ncpu"`
	LbStrategy                string                  `json:"lbStrategy"`
	SslPem                    string                  `json:"sslPem"`
	SslKey                    string                  `json:"sslKey"`
	SslOcspStaple             string                  `json:"sslOcspStaple"`
	SslMode                   string                  `json:"sslMode"`
	TlsEngine                 string                  `json:"tlsEngine"`
	KTLSPolicy                string                  `json:"ktlsPolicy"`
	TlsMinVersion             uint16                  `json:"tlsMinVersion"`
	TlsMaxVersion             uint16                  `json:"tlsMaxVersion"`
	TlsNextProtos             []string                `json:"tlsNextProtos"`
	TlsSessionTicketsDisabled bool                    `json:"tlsSessionTicketsDisabled"`
	TlsSessionTicketSeed      string                  `json:"tlsSessionTicketSeed"`
	TlsSessionTicketContext   string                  `json:"tlsSessionTicketContext"`
	ListenAddrs               []eventloop.IEVEndpoint `json:"listenAddrs"`
	PollWait                  int                     `json:"pollWait"`
	TwInterval                int                     `json:"twInterval"`
	DialKeepAlive             bool                    `json:"dialKeepAlive"`
	DialPolling               bool                    `json:"dialPolling"`

	PktSizeLimit    int  `json:"pktSizeLimit"`
	BufSize         int  `json:"bufSize"`
	ChanSize        int  `json:"chanSize"`
	MaxAcceptFD     int  `json:"maxAcceptFD"`
	IdleCheckInt    int  `json:"idleCheckInt"`
	IdleLimit       int  `json:"idleLimit"`
	CliSendBufLimit int  `json:"cliSbufLimit"`
	PrintStat       bool `json:"printStat"`

	IDGen eventloop.IDGenerator
}

func GetDefaultConfig

func GetDefaultConfig() *EvConfig

type IDialWatch

type IDialWatch interface {
	OnUpdate(bool)
}

type LoadBalance

type LoadBalance int

LoadBalance sets the load balancing method.

const (
	// RoundRobin requests that connections are distributed to a loop in a
	// round-robin fashion.
	RoundRobin LoadBalance = iota

	// Random requests that connections are randomly distributed.
	Random

	// LeastConnections assigns the next accepted connection to the loop with
	// the least number of active connections.
	LeastConnections

	Hash
)

type Server

type Server struct {
	// contains filtered or unexported fields
}

func Serve

func Serve(h eventloop.IHandler, fname string) (error, *Server)

Serve starts handling events for the specified addresses.

Addresses should use a scheme prefix and be formatted like `tcp://192.168.0.10:9851`.

Only the "tcp" network scheme is supported.

func ServeByConfig

func ServeByConfig(h eventloop.IHandler, config *EvConfig, standalone bool) (error, *Server)

func (*Server) AddDialer

func (s *Server) AddDialer(para *DialParam, max int)

func (*Server) Close

func (s *Server) Close(d *Dialer)

func (*Server) DialerUpdate

func (s *Server) DialerUpdate(op, key, addr string)

func (*Server) GetDials

func (s *Server) GetDials() int32

func (*Server) GetListenAddrs

func (s *Server) GetListenAddrs() []net.Addr

func (*Server) GetLoad

func (s *Server) GetLoad() int32

func (*Server) GetWorkerNum

func (s *Server) GetWorkerNum() int

func (*Server) Lookup

func (s *Server) Lookup(id uint64) *Dialer

func (*Server) SelectLoop

func (s *Server) SelectLoop(id int) eventloop.IEVLoop

func (*Server) Stop

func (s *Server) Stop()

Directories

Path Synopsis
benchmark
cmd
ktlscheck command
examples
echo command
fasthttp command
http command
httpws command
prometheus command
tcphttpws command
tls_echo command
websocket command
tls

Jump to

Keyboard shortcuts

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