Skip to content

Commit 3ddc6b8

Browse files
committed
server side support for garbage fetch feature
1 parent afcda1c commit 3ddc6b8

File tree

1 file changed

+29
-4
lines changed

1 file changed

+29
-4
lines changed

handler/handler.go

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ package handler
22

33
import (
44
"context"
5+
"encoding/binary"
56
"errors"
67
"fmt"
78
"io"
89
"log"
10+
"math/rand/v2"
911
"net"
1012
"net/http"
13+
"strconv"
1114
"strings"
1215
"sync"
1316

@@ -170,6 +173,25 @@ func (s *ProxyHandler) HandleRequest(wr http.ResponseWriter, req *http.Request,
170173
s.forward(req.Context(), username, wrapH1RespWriter(wr), wrapH1ReqBody(resp.Body))
171174
}
172175

176+
func (s *ProxyHandler) HandleGetRandom(wr http.ResponseWriter, req *http.Request, username string) {
177+
if len(req.URL.Path) <= 1 || req.URL.Path[0] != '/' {
178+
http.Error(wr, "Incorrect requested random data length", http.StatusBadRequest)
179+
}
180+
length, err := strconv.ParseInt(req.URL.Path[1:], 10, 64)
181+
if err != nil || length < 0 {
182+
http.Error(wr, "Incorrect requested random data length", http.StatusBadRequest)
183+
}
184+
var seed [32]byte
185+
binary.NativeEndian.PutUint64(seed[0:], rand.Uint64())
186+
binary.NativeEndian.PutUint64(seed[8:], rand.Uint64())
187+
binary.NativeEndian.PutUint64(seed[16:], rand.Uint64())
188+
binary.NativeEndian.PutUint64(seed[24:], rand.Uint64())
189+
rng := rand.NewChaCha8(seed)
190+
wr.Header().Set("Content-Length", strconv.FormatInt(length, 10))
191+
wr.WriteHeader(http.StatusOK)
192+
io.Copy(wr, io.LimitReader(rng, length))
193+
}
194+
173195
func (s *ProxyHandler) isLoopback(req *http.Request) (string, bool) {
174196
s.outboundMux.RLock()
175197
originator, found := s.outbound[req.RemoteAddr]
@@ -185,8 +207,8 @@ func (s *ProxyHandler) ServeHTTP(wr http.ResponseWriter, req *http.Request) {
185207
return
186208
}
187209

188-
isConnect := strings.ToUpper(req.Method) == "CONNECT"
189-
if (req.URL.Host == "" || req.URL.Scheme == "" && !isConnect) && req.ProtoMajor < 2 ||
210+
method := strings.ToUpper(req.Method)
211+
if (req.URL.Host == "" || req.URL.Scheme == "" && method != "CONNECT") && req.ProtoMajor < 2 ||
190212
req.Host == "" && req.ProtoMajor == 2 {
191213
http.Error(wr, auth.BAD_REQ_MSG, http.StatusBadRequest)
192214
return
@@ -213,9 +235,12 @@ func (s *ProxyHandler) ServeHTTP(wr http.ResponseWriter, req *http.Request) {
213235
ctx = ddto.FilterParamsToContext(ctx, req, username)
214236
req = req.WithContext(ctx)
215237
delHopHeaders(req.Header)
216-
if isConnect {
238+
switch method {
239+
case "CONNECT":
217240
s.HandleTunnel(wr, req, username)
218-
} else {
241+
case "GETRANDOM":
242+
s.HandleGetRandom(wr, req, username)
243+
default:
219244
s.HandleRequest(wr, req, username)
220245
}
221246
}

0 commit comments

Comments
 (0)