Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf7ddbb7

Browse files
authored
feat: add CoderVPN protocol definition & implementation (#14855)
closes#14731Defines and implements the CoderVPN control protocol, which will be used to communicate with desktop client applications.
1 parent38d8e3a commitf7ddbb7

File tree

7 files changed

+3554
-0
lines changed

7 files changed

+3554
-0
lines changed

‎Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ gen: \
488488
agent/proto/agent.pb.go\
489489
provisionersdk/proto/provisioner.pb.go\
490490
provisionerd/proto/provisionerd.pb.go\
491+
vpn/vpn.proto\
491492
coderd/database/dump.sql\
492493
$(DB_GEN_FILES)\
493494
site/src/api/typesGenerated.ts\
@@ -517,6 +518,7 @@ gen/mark-fresh:
517518
agent/proto/agent.pb.go\
518519
provisionersdk/proto/provisioner.pb.go\
519520
provisionerd/proto/provisionerd.pb.go\
521+
vpn/vpn.proto\
520522
coderd/database/dump.sql\
521523
$(DB_GEN_FILES)\
522524
site/src/api/typesGenerated.ts\
@@ -600,6 +602,12 @@ provisionerd/proto/provisionerd.pb.go: provisionerd/proto/provisionerd.proto
600602
--go-drpc_opt=paths=source_relative\
601603
./provisionerd/proto/provisionerd.proto
602604

605+
vpn/vpn.pb.go: vpn/vpn.proto
606+
protoc\
607+
--go_out=.\
608+
--go_opt=paths=source_relative\
609+
./vpn/vpn.proto
610+
603611
site/src/api/typesGenerated.ts:$(wildcard scripts/apitypings/*)$(shell find ./codersdk$(FIND_EXCLUSIONS) -type f -name '*.go')
604612
go run ./scripts/apitypings/>$@
605613
./scripts/pnpm_install.sh

‎vpn/serdes.go

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package vpn
2+
3+
import (
4+
"context"
5+
"encoding/binary"
6+
"io"
7+
"sync"
8+
9+
"google.golang.org/protobuf/proto"
10+
11+
"cdr.dev/slog"
12+
)
13+
14+
// MaxLength is the largest possible CoderVPN Protocol message size. This is set
15+
// so that a misbehaving peer can't cause us to allocate a huge amount of memory.
16+
constMaxLength=0x1000000// 16MiB
17+
18+
// serdes SERializes and DESerializes protobuf messages to and from the conn.
19+
typeserdes[SrpcMessage,RreceivableRPCMessage[RR],RRany]struct {
20+
ctx context.Context
21+
logger slog.Logger
22+
conn io.ReadWriteCloser
23+
sendCh<-chanS
24+
recvChchan<-R
25+
closeOnce sync.Once
26+
wg sync.WaitGroup
27+
}
28+
29+
func (s*serdes[_,R,RR])recvLoop() {
30+
s.logger.Debug(s.ctx,"starting recvLoop")
31+
defers.closeIdempotent()
32+
deferclose(s.recvCh)
33+
for {
34+
varlengthuint32
35+
iferr:=binary.Read(s.conn,binary.BigEndian,&length);err!=nil {
36+
s.logger.Debug(s.ctx,"failed to read length",slog.Error(err))
37+
return
38+
}
39+
iflength>MaxLength {
40+
s.logger.Critical(s.ctx,"message length exceeds max",
41+
slog.F("length",length))
42+
return
43+
}
44+
s.logger.Debug(s.ctx,"about to read message",slog.F("length",length))
45+
mb:=make([]byte,length)
46+
ifn,err:=io.ReadFull(s.conn,mb);err!=nil {
47+
s.logger.Debug(s.ctx,"failed to read message",
48+
slog.Error(err),
49+
slog.F("num_bytes_read",n))
50+
return
51+
}
52+
msg:=R(new(RR))
53+
iferr:=proto.Unmarshal(mb,msg);err!=nil {
54+
s.logger.Critical(s.ctx,"failed to unmarshal message",slog.Error(err))
55+
return
56+
}
57+
select {
58+
cases.recvCh<-msg:
59+
s.logger.Debug(s.ctx,"passed received message to speaker")
60+
case<-s.ctx.Done():
61+
s.logger.Debug(s.ctx,"recvLoop canceled",slog.Error(s.ctx.Err()))
62+
}
63+
}
64+
}
65+
66+
func (s*serdes[S,_,_])sendLoop() {
67+
s.logger.Debug(s.ctx,"starting sendLoop")
68+
defers.closeIdempotent()
69+
for {
70+
select {
71+
case<-s.ctx.Done():
72+
s.logger.Debug(s.ctx,"sendLoop canceled",slog.Error(s.ctx.Err()))
73+
return
74+
casemsg,ok:=<-s.sendCh:
75+
if!ok {
76+
s.logger.Debug(s.ctx,"sendCh closed")
77+
return
78+
}
79+
mb,err:=proto.Marshal(msg)
80+
iferr!=nil {
81+
s.logger.Critical(s.ctx,"failed to marshal message",slog.Error(err))
82+
return
83+
}
84+
iferr:=binary.Write(s.conn,binary.BigEndian,uint32(len(mb)));err!=nil {
85+
s.logger.Debug(s.ctx,"failed to write length",slog.Error(err))
86+
return
87+
}
88+
if_,err:=s.conn.Write(mb);err!=nil {
89+
s.logger.Debug(s.ctx,"failed to write message",slog.Error(err))
90+
return
91+
}
92+
}
93+
}
94+
}
95+
96+
func (s*serdes[_,_,_])closeIdempotent() {
97+
s.closeOnce.Do(func() {
98+
iferr:=s.conn.Close();err!=nil {
99+
s.logger.Error(s.ctx,"failed to close connection",slog.Error(err))
100+
}else {
101+
s.logger.Info(s.ctx,"closed connection")
102+
}
103+
})
104+
}
105+
106+
func (s*serdes[_,_,_])Close()error {
107+
s.closeIdempotent()
108+
s.wg.Wait()
109+
returnnil
110+
}
111+
112+
func (s*serdes[_,_,_])start() {
113+
s.wg.Add(2)
114+
gofunc() {
115+
defers.wg.Done()
116+
s.recvLoop()
117+
}()
118+
gofunc() {
119+
defers.wg.Done()
120+
s.sendLoop()
121+
}()
122+
}
123+
124+
funcnewSerdes[SrpcMessage,RreceivableRPCMessage[RR],RRany](
125+
ctx context.Context,logger slog.Logger,conn io.ReadWriteCloser,
126+
sendCh<-chanS,recvChchan<-R,
127+
)*serdes[S,R,RR] {
128+
return&serdes[S,R,RR]{
129+
ctx:ctx,
130+
logger:logger.Named("serdes"),
131+
conn:conn,
132+
sendCh:sendCh,
133+
recvCh:recvCh,
134+
}
135+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp