-
Notifications
You must be signed in to change notification settings - Fork 100
/
client_wrapper.go
115 lines (101 loc) · 3.74 KB
/
client_wrapper.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package goquic
// #cgo CXXFLAGS: -DUSE_OPENSSL=1 -std=gnu++11
// #cgo LDFLAGS: -pthread -lgoquic -lquic -lssl -lcrypto -lstdc++ -lm
// #cgo darwin LDFLAGS: -framework CoreFoundation -framework Cocoa
// #include <stddef.h>
// #include "src/adaptor.h"
// #include "src/adaptor_client.h"
import "C"
import (
"net"
"time"
"unsafe"
)
type QuicConn interface { // implements net.Conn
Close() error
SetDeadline(t time.Time) error
SetReadDeadline(t time.Time) error
SetWriteDeadline(t time.Time) error
Writer() *ClientWriter
}
// TODO(hodduc) multi-stream support ?
type QuicClient struct {
addr *net.UDPAddr
conn QuicConn
session *QuicClientSession
createQuicClientSession func() OutgoingDataStreamCreator
taskRunner *TaskRunner
proofVerifier *ProofVerifier
}
type QuicClientSession struct {
quicClientSession_c unsafe.Pointer
quicClientStreams map[*QuicClientStream]bool
streamCreator OutgoingDataStreamCreator
}
func (s *QuicClientSession) NumActiveRequests() int {
return int(C.quic_client_session_num_active_requests(s.quicClientSession_c))
}
func CreateQuicClient(addr *net.UDPAddr, conn QuicConn, createQuicClientSession func() OutgoingDataStreamCreator, taskRunner *TaskRunner, proofVerifier *ProofVerifier) (qc *QuicClient, err error) {
return &QuicClient{
addr: addr,
conn: conn,
taskRunner: taskRunner,
createQuicClientSession: createQuicClientSession,
proofVerifier: proofVerifier,
}, nil
}
func (qc *QuicClient) StartConnect() {
addr := CreateIPEndPoint(qc.addr)
qc.session = &QuicClientSession{
quicClientSession_c: C.create_go_quic_client_session_and_initialize(
C.GoPtr(clientWriterPtr.Set(qc.conn.Writer())),
C.GoPtr(taskRunnerPtr.Set(qc.taskRunner)),
C.GoPtr(proofVerifierPtr.Set(qc.proofVerifier)),
(*C.uint8_t)(unsafe.Pointer(&addr.packed[0])),
C.size_t(len(addr.packed)),
C.uint16_t(addr.port)), // Deleted on QuicClient.Close(),
quicClientStreams: make(map[*QuicClientStream]bool),
streamCreator: qc.createQuicClientSession(),
}
}
func (qc *QuicClient) EncryptionBeingEstablished() bool {
v := C.go_quic_client_encryption_being_established(qc.session.quicClientSession_c)
return (v != 0)
}
func (qc *QuicClient) IsConnected() bool {
v := C.go_quic_client_session_is_connected(qc.session.quicClientSession_c)
return (v != 0)
}
func (qc *QuicClient) CreateReliableQuicStream() *QuicClientStream {
stream := &QuicClientStream{
userStream: qc.session.streamCreator.CreateOutgoingDynamicStream(), // Deleted on qc.Close()
session: qc.session,
}
stream.wrapper = C.quic_client_session_create_reliable_quic_stream(qc.session.quicClientSession_c, C.GoPtr(quicClientStreamPtr.Set(stream)))
qc.session.quicClientStreams[stream] = true
return stream
}
func (qc *QuicClient) ProcessPacket(self_address *net.UDPAddr, peer_address *net.UDPAddr, buffer []byte) {
self_address_p := CreateIPEndPoint(self_address)
peer_address_p := CreateIPEndPoint(peer_address)
C.go_quic_client_session_process_packet(
qc.session.quicClientSession_c,
(*C.uint8_t)(unsafe.Pointer(&self_address_p.packed[0])),
C.size_t(len(self_address_p.packed)),
C.uint16_t(self_address_p.port),
(*C.uint8_t)(unsafe.Pointer(&peer_address_p.packed[0])),
C.size_t(len(peer_address_p.packed)),
C.uint16_t(peer_address_p.port),
(*C.char)(unsafe.Pointer(&buffer[0])), C.size_t(len(buffer)),
)
}
func (qc *QuicClient) SendConnectionClosePacket() {
C.go_quic_client_session_connection_send_connection_close_packet(qc.session.quicClientSession_c)
}
func (qc *QuicClient) Close() (err error) {
if qc.session != nil {
C.delete_go_quic_client_session(qc.session.quicClientSession_c)
qc.session = nil
}
return nil
}