]>
Commit | Line | Data |
---|---|---|
bae9f6d2 JC |
1 | package yamux |
2 | ||
3 | import ( | |
4 | "fmt" | |
5 | "io" | |
6 | "os" | |
7 | "time" | |
8 | ) | |
9 | ||
10 | // Config is used to tune the Yamux session | |
11 | type Config struct { | |
12 | // AcceptBacklog is used to limit how many streams may be | |
13 | // waiting an accept. | |
14 | AcceptBacklog int | |
15 | ||
16 | // EnableKeepalive is used to do a period keep alive | |
17 | // messages using a ping. | |
18 | EnableKeepAlive bool | |
19 | ||
20 | // KeepAliveInterval is how often to perform the keep alive | |
21 | KeepAliveInterval time.Duration | |
22 | ||
23 | // ConnectionWriteTimeout is meant to be a "safety valve" timeout after | |
24 | // we which will suspect a problem with the underlying connection and | |
25 | // close it. This is only applied to writes, where's there's generally | |
26 | // an expectation that things will move along quickly. | |
27 | ConnectionWriteTimeout time.Duration | |
28 | ||
29 | // MaxStreamWindowSize is used to control the maximum | |
30 | // window size that we allow for a stream. | |
31 | MaxStreamWindowSize uint32 | |
32 | ||
33 | // LogOutput is used to control the log destination | |
34 | LogOutput io.Writer | |
35 | } | |
36 | ||
37 | // DefaultConfig is used to return a default configuration | |
38 | func DefaultConfig() *Config { | |
39 | return &Config{ | |
40 | AcceptBacklog: 256, | |
41 | EnableKeepAlive: true, | |
42 | KeepAliveInterval: 30 * time.Second, | |
43 | ConnectionWriteTimeout: 10 * time.Second, | |
44 | MaxStreamWindowSize: initialStreamWindow, | |
45 | LogOutput: os.Stderr, | |
46 | } | |
47 | } | |
48 | ||
49 | // VerifyConfig is used to verify the sanity of configuration | |
50 | func VerifyConfig(config *Config) error { | |
51 | if config.AcceptBacklog <= 0 { | |
52 | return fmt.Errorf("backlog must be positive") | |
53 | } | |
54 | if config.KeepAliveInterval == 0 { | |
55 | return fmt.Errorf("keep-alive interval must be positive") | |
56 | } | |
57 | if config.MaxStreamWindowSize < initialStreamWindow { | |
58 | return fmt.Errorf("MaxStreamWindowSize must be larger than %d", initialStreamWindow) | |
59 | } | |
60 | return nil | |
61 | } | |
62 | ||
63 | // Server is used to initialize a new server-side connection. | |
64 | // There must be at most one server-side connection. If a nil config is | |
65 | // provided, the DefaultConfiguration will be used. | |
66 | func Server(conn io.ReadWriteCloser, config *Config) (*Session, error) { | |
67 | if config == nil { | |
68 | config = DefaultConfig() | |
69 | } | |
70 | if err := VerifyConfig(config); err != nil { | |
71 | return nil, err | |
72 | } | |
73 | return newSession(config, conn, false), nil | |
74 | } | |
75 | ||
76 | // Client is used to initialize a new client-side connection. | |
77 | // There must be at most one client-side connection. | |
78 | func Client(conn io.ReadWriteCloser, config *Config) (*Session, error) { | |
79 | if config == nil { | |
80 | config = DefaultConfig() | |
81 | } | |
82 | ||
83 | if err := VerifyConfig(config); err != nil { | |
84 | return nil, err | |
85 | } | |
86 | return newSession(config, conn, true), nil | |
87 | } |