Skip to content

Commit 357e554

Browse files
committed
First cut at -13
1 parent 0a3e19f commit 357e554

File tree

16 files changed

+1332
-862
lines changed

16 files changed

+1332
-862
lines changed

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@ certificates.
3737

3838
## Quick Start (untested but should be rightish)
3939

40-
4140
cd ${GOPATH}/src
4241
go get github.com/ekr/minq
4342
cd github.com/bifurcation/mint
43+
git remote add ekr https://github.com/ekr/mint
44+
git fetch ekr
45+
git checkout ekr/quic_record_layer
4446
cd ../../ekr/minq
4547
go test
4648

@@ -101,6 +103,9 @@ Multiple log levels can be separated by commas.
101103
## Mint
102104

103105
Minq depends on Mint (https://www.github.com/bifurcation/mint) for TLS.
104-
Currently Mint master should work, but occasionally I will have to be on
105-
a branch. Will try to keep this updated.
106+
Right now we are on the following branch:
107+
108+
https://github.com/ekr/mint/tree/quic_record_layer
109+
110+
This branch is more experimental than usual.
106111

bin/client/main.go

Lines changed: 98 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ var doHttp string
1717
var httpCount int
1818
var heartbeat int
1919
var cpuProfile string
20+
var resume bool
21+
var httpLeft int
22+
var zeroRtt bool
2023

2124
type connHandler struct {
2225
bytesRead int
@@ -44,9 +47,11 @@ func (h *connHandler) StreamReadable(s minq.RecvStream) {
4447
return
4548
case minq.ErrorStreamIsClosed, minq.ErrorConnIsClosed:
4649
log.Println("<CLOSED>")
50+
httpLeft--
4751
return
4852
default:
4953
log.Println("Error: ", err)
54+
httpLeft--
5055
return
5156
}
5257
b = b[:n]
@@ -78,6 +83,51 @@ func readUDP(s *net.UDPConn) ([]byte, error) {
7883
return b, nil
7984
}
8085

86+
func makeConnection(config *minq.TlsConfig, uaddr *net.UDPAddr) (*net.UDPConn, *minq.Connection) {
87+
usock, err := net.ListenUDP("udp", nil)
88+
if err != nil {
89+
log.Println("Couldn't create connected UDP socket")
90+
return nil, nil
91+
}
92+
93+
utrans := minq.NewUdpTransport(usock, uaddr)
94+
95+
conn := minq.NewConnection(utrans, minq.RoleClient,
96+
config, &connHandler{})
97+
98+
log.Printf("Client conn id=%v\n", conn.ClientId())
99+
100+
// Start things off.
101+
_, err = conn.CheckTimer()
102+
103+
return usock, conn
104+
}
105+
106+
func completeConnection(usock *net.UDPConn, conn *minq.Connection) error {
107+
for conn.GetState() != minq.StateEstablished {
108+
b, err := readUDP(usock)
109+
if err != nil {
110+
if err == minq.ErrorWouldBlock {
111+
_, err = conn.CheckTimer()
112+
if err != nil {
113+
return err
114+
}
115+
continue
116+
}
117+
return err
118+
}
119+
120+
err = conn.Input(b)
121+
if err != nil {
122+
log.Println("Error", err)
123+
return err
124+
}
125+
}
126+
127+
log.Printf("Connection established server CID = %v\n", conn.ServerId())
128+
return nil
129+
}
130+
81131
func main() {
82132
log.Println("PID=", os.Getpid())
83133
flag.StringVar(&addr, "addr", "localhost:4433", "[host:port]")
@@ -86,8 +136,17 @@ func main() {
86136
flag.IntVar(&httpCount, "httpCount", 1, "Number of parallel HTTP requests to start")
87137
flag.IntVar(&heartbeat, "heartbeat", 0, "heartbeat frequency [ms]")
88138
flag.StringVar(&cpuProfile, "cpuprofile", "", "write cpu profile to file")
139+
flag.BoolVar(&resume, "resume", false, "Test resumption")
140+
flag.BoolVar(&zeroRtt, "zerortt", false, "Test 0-RTT")
89141
flag.Parse()
90142

143+
if zeroRtt {
144+
resume = true
145+
if doHttp == "" {
146+
log.Printf("Need HTTP to do 0-RTT")
147+
return
148+
}
149+
}
91150
if cpuProfile != "" {
92151
f, err := os.Create(cpuProfile)
93152
if err != nil {
@@ -107,56 +166,46 @@ func main() {
107166
}
108167
serverName = host
109168
}
169+
config := minq.NewTlsConfig(serverName)
170+
171+
inner_main(&config, false)
172+
if resume {
173+
inner_main(&config, true)
174+
}
175+
}
176+
func inner_main(config *minq.TlsConfig, resuming bool) {
110177

111178
uaddr, err := net.ResolveUDPAddr("udp", addr)
112179
if err != nil {
113180
log.Println("Invalid UDP addr", err)
114181
return
115182
}
116-
usock, err := net.ListenUDP("udp", nil)
117-
if err != nil {
118-
log.Println("Couldn't create connected UDP socket")
183+
184+
usock, conn := makeConnection(config, uaddr)
185+
if conn == nil {
119186
return
120187
}
121188

122-
utrans := minq.NewUdpTransport(usock, uaddr)
123-
124-
config := minq.NewTlsConfig(serverName)
125-
conn := minq.NewConnection(utrans, minq.RoleClient,
126-
&config, &connHandler{})
127-
128-
log.Printf("Client conn id=%x\n", conn.ClientId())
129-
130-
// Start things off.
131-
_, err = conn.CheckTimer()
132-
133-
for conn.GetState() != minq.StateEstablished {
134-
b, err := readUDP(usock)
189+
if !resuming || !zeroRtt {
190+
err = completeConnection(usock, conn)
135191
if err != nil {
136-
if err == minq.ErrorWouldBlock {
137-
_, err = conn.CheckTimer()
138-
if err != nil {
139-
return
140-
}
141-
continue
142-
}
143-
return
144-
}
145-
146-
err = conn.Input(b)
147-
if err != nil {
148-
log.Println("Error", err)
149192
return
150193
}
151194
}
152195

153-
log.Println("Connection established")
196+
// Hopefully reduce the risk of reordering
197+
time.Sleep(100 * time.Millisecond)
154198

155199
// Make all the streams we need
156200
streams := make([]minq.Stream, httpCount)
157201
for i := 0; i < httpCount; i++ {
158202
streams[i] = conn.CreateStream()
203+
if streams[i] == nil {
204+
log.Println("Couldn't create stream")
205+
return
206+
}
159207
}
208+
httpLeft = httpCount
160209

161210
udpin := make(chan []byte)
162211
stdin := make(chan []byte)
@@ -185,6 +234,22 @@ func main() {
185234
}()
186235
}
187236

237+
if doHttp != "" {
238+
req := "GET " + doHttp + "\r\n"
239+
for _, str := range streams {
240+
str.Write([]byte(req))
241+
str.Close()
242+
}
243+
}
244+
245+
if resuming && zeroRtt {
246+
log.Println("Completing connection after we sent 0-RTT send in 0-RTT")
247+
err = completeConnection(usock, conn)
248+
if err != nil {
249+
return
250+
}
251+
}
252+
188253
if doHttp == "" {
189254
// Read from stdin.
190255
go func() {
@@ -199,14 +264,7 @@ func main() {
199264
stdin <- b
200265
}
201266
}()
202-
} else {
203-
req := "GET " + doHttp + "\r\n"
204-
for _, str := range streams {
205-
str.Write([]byte(req))
206-
str.Close()
207-
}
208267
}
209-
210268
for {
211269
select {
212270
case u := <-udpin:
@@ -219,6 +277,9 @@ func main() {
219277
log.Println("Error", err)
220278
return
221279
}
280+
if doHttp != "" && httpLeft == 0 {
281+
return
282+
}
222283
case i := <-stdin:
223284
if i == nil {
224285
// TODO([email protected]) close the apropriate stream(s)

codec.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,18 +195,22 @@ func encode(i interface{}) (ret []byte, err error) {
195195
return ret, nil
196196
}
197197

198+
func uintDecodeIntBuf(val []byte) uint64 {
199+
tmp := uint64(0)
200+
for b := 0; b < len(val); b++ {
201+
tmp = (tmp << 8) + uint64(val[b])
202+
}
203+
return tmp
204+
}
205+
198206
func uintDecodeInt(r io.Reader, size uintptr) (uint64, error) {
199207
val := make([]byte, size)
200208
_, err := io.ReadFull(r, val)
201209
if err != nil {
202210
return 0, err
203211
}
204212

205-
tmp := uint64(0)
206-
for b := uintptr(0); b < size; b++ {
207-
tmp = (tmp << 8) + uint64(val[b])
208-
}
209-
return tmp, nil
213+
return uintDecodeIntBuf(val), nil
210214
}
211215

212216
func uintDecode(r io.Reader, v reflect.Value, encodingSize uintptr) (uintptr, error) {

0 commit comments

Comments
 (0)