package yamux import ( "fmt" "io" "os" "time" ) // Config is used to tune the Yamux session type Config struct { // AcceptBacklog is used to limit how many streams may be // waiting an accept. AcceptBacklog int // EnableKeepalive is used to do a period keep alive // messages using a ping. EnableKeepAlive bool // KeepAliveInterval is how often to perform the keep alive KeepAliveInterval time.Duration // MaxStreamWindowSize is used to control the maximum // window size that we allow for a stream. MaxStreamWindowSize uint32 // LogOutput is used to control the log destination LogOutput io.Writer } // DefaultConfig is used to return a default configuration func DefaultConfig() *Config { return &Config{ AcceptBacklog: 256, EnableKeepAlive: true, KeepAliveInterval: 30 * time.Second, MaxStreamWindowSize: initialStreamWindow, LogOutput: os.Stderr, } } // VerifyConfig is used to verify the sanity of configuration func VerifyConfig(config *Config) error { if config.AcceptBacklog <= 0 { return fmt.Errorf("backlog must be positive") } if config.KeepAliveInterval == 0 { return fmt.Errorf("keep-alive interval must be positive") } if config.MaxStreamWindowSize < initialStreamWindow { return fmt.Errorf("MaxStreamWindowSize must be larger than %d", initialStreamWindow) } return nil } // Server is used to initialize a new server-side connection. // There must be at most one server-side connection. If a nil config is // provided, the DefaultConfiguration will be used. func Server(conn io.ReadWriteCloser, config *Config) (*Session, error) { if config == nil { config = DefaultConfig() } if err := VerifyConfig(config); err != nil { return nil, err } return newSession(config, conn, false), nil } // Client is used to initialize a new client-side connection. // There must be at most one client-side connection. func Client(conn io.ReadWriteCloser, config *Config) (*Session, error) { if config == nil { config = DefaultConfig() } if err := VerifyConfig(config); err != nil { return nil, err } return newSession(config, conn, true), nil }