@@ -2,10 +2,9 @@ package main
22
33import (
44 "crypto/md5"
5+ "crypto/tls"
56 "encoding/json"
67 "fmt"
7- "github.com/pyke369/golang-support/uconfig"
8- "github.com/pyke369/golang-support/ulog"
98 "math"
109 "math/rand"
1110 "net"
@@ -16,10 +15,14 @@ import (
1615 "strings"
1716 "sync"
1817 "time"
18+
19+ "github.com/pyke369/golang-support/dynacert"
20+ "github.com/pyke369/golang-support/uconfig"
21+ "github.com/pyke369/golang-support/ulog"
1922)
2023
2124const progname = "tcpsplice"
22- const version = "1.1 .0"
25+ const version = "1.2 .0"
2326
2427type Session struct {
2528 id , service , source , target , meta string
4043 sessionsLock sync.RWMutex
4144)
4245
43- func serviceHandler (service string , listener * net.TCPListener ) {
46+ func serviceHandler (service string , listener net.Listener ) {
4447 for {
45- if source , err := listener .AcceptTCP (); err == nil {
48+ if source , err := listener .Accept (); err == nil {
4649 remotes := config .GetPaths (fmt .Sprintf ("services.%s.remote" , service ))
4750 if len (remotes ) > 0 {
4851 go func () {
@@ -57,8 +60,10 @@ func serviceHandler(service string, listener *net.TCPListener) {
5760 idleTimeout := time .Second * time .Duration (config .GetDurationBounds (fmt .Sprintf ("services.%s.idle_timeout" , service ), 60 , 0 , 300 ))
5861 metaSize := int (config .GetSizeBounds (fmt .Sprintf ("services.%s.meta_size" , service ), 16 * 1024 , 0 , 64 * 1024 ))
5962 metaScan , _ := regexp .Compile (config .GetString (fmt .Sprintf ("services.%s.meta_scan" , service ), "[" ))
60- source .SetReadBuffer (int (incomingSize ))
61- source .SetWriteBuffer (int (incomingSize ))
63+ if tsource , ok := source .(* net.TCPConn ); ok {
64+ tsource .SetReadBuffer (int (incomingSize ))
65+ tsource .SetWriteBuffer (int (incomingSize ))
66+ }
6267 target .(* net.TCPConn ).SetReadBuffer (int (outgoingSize ))
6368 target .(* net.TCPConn ).SetWriteBuffer (int (outgoingSize ))
6469 session := & Session {
@@ -208,23 +213,25 @@ func monitorHandler(response http.ResponseWriter, request *http.Request) {
208213 services := map [string ]interface {}{}
209214 for _ , service := range config .GetPaths ("services" ) {
210215 service = strings .TrimPrefix (service , "services." )
211- s := map [string ]interface {}{}
216+ entries := map [string ]interface {}{}
212217 sessionsLock .RLock ()
213218 for id , session := range sessions {
214- s [id ] = map [string ]interface {}{
215- "started" : session .started .Unix (),
216- "duration" : time .Now ().Sub (session .started ) / time .Second ,
217- "source" : session .source ,
218- "target" : session .target ,
219- "bytes" : [2 ]int64 {session .sourceRead , session .targetRead },
220- "mean" : [2 ]float64 {session .sourceMeanThroughput , session .targetMeanThroughput },
221- "last" : [2 ]float64 {session .sourceLastThroughput , session .targetLastThroughput },
222- "meta" : session .meta ,
223- "done" : session .done ,
219+ if session .service == service {
220+ entries [id ] = map [string ]interface {}{
221+ "started" : session .started .Unix (),
222+ "duration" : time .Now ().Sub (session .started ) / time .Second ,
223+ "source" : session .source ,
224+ "target" : session .target ,
225+ "bytes" : [2 ]int64 {session .sourceRead , session .targetRead },
226+ "mean" : [2 ]float64 {session .sourceMeanThroughput , session .targetMeanThroughput },
227+ "last" : [2 ]float64 {session .sourceLastThroughput , session .targetLastThroughput },
228+ "meta" : session .meta ,
229+ "done" : session .done ,
230+ }
224231 }
225232 }
226233 sessionsLock .RUnlock ()
227- services [service ] = s
234+ services [service ] = entries
228235 }
229236 output ["services" ] = services
230237 response .Header ().Set ("Content-Type" , "application/json" )
@@ -242,9 +249,6 @@ func monitorHandler(response http.ResponseWriter, request *http.Request) {
242249 }
243250 }
244251 sessionsLock .RUnlock ()
245- } else {
246- response .Header ().Set ("Content-Type" , "text/html; charset=utf-8" )
247- response .Write (monitorContent )
248252 }
249253}
250254
@@ -315,21 +319,27 @@ func main() {
315319 for _ , service := range config .GetPaths ("services" ) {
316320 for _ , local := range config .GetPaths (fmt .Sprintf ("%s.local" , service )) {
317321 service = strings .TrimPrefix (service , "services." )
318- local = config .GetString (local , "" )
319- if address , err := net .ResolveTCPAddr ("tcp" , strings .TrimLeft (local , "*" )); err == nil {
320- if listener , err := net .ListenTCP ("tcp" , address ); err == nil {
321- logger .Info (map [string ]interface {}{"type" : "service" , "name" : service , "listen" : local })
322+ if parts := strings .Split (config .GetStringMatch (local , "_" , "^.*?(:\\ d+)?((,[^,]+){2})?$" ), "," ); parts [0 ] != "_" {
323+ if listener , err := net .Listen ("tcp" , strings .TrimLeft (parts [0 ], "*" )); err == nil {
324+ if len (parts ) > 1 {
325+ loader := & dynacert.DYNACERT {Public : parts [1 ], Key : parts [2 ]}
326+ listener = tls .NewListener (listener , dynacert .IntermediateTLSConfig (loader .GetCertificate ))
327+ logger .Info (map [string ]interface {}{"type" : "service" , "name" : service , "listen" : parts [0 ], "cert" : parts [1 ], "key" : parts [2 ]})
328+ } else {
329+ logger .Info (map [string ]interface {}{"type" : "service" , "name" : service , "listen" : parts [0 ]})
330+ }
322331 go serviceHandler (service , listener )
323332 } else {
324- logger .Warn (map [string ]interface {}{"type" : "service" , "name" : service , "listen" : local , "error" : err })
333+ logger .Warn (map [string ]interface {}{"type" : "service" , "name" : service , "listen" : parts [ 0 ] , "error" : err })
325334 }
326- } else {
327- logger .Warn (map [string ]interface {}{"type" : "service" , "name" : service , "listen" : local , "error" : err })
328335 }
329336 }
330337 }
331338
332- http .Handle ("/" , baseHandler (http .HandlerFunc (monitorHandler )))
339+ http .Handle ("/sessions.json" , baseHandler (http .HandlerFunc (monitorHandler )))
340+ http .Handle ("/abort/" , baseHandler (http .HandlerFunc (monitorHandler )))
341+ http .Handle ("/" , baseHandler (http .StripPrefix ("/" , Resources (6 * time .Hour ))))
342+
333343 if parts := strings .Split (config .GetStringMatch ("monitor.listen" , "_" , "^(?:\\ *|\\ d+(?:\\ .\\ d+){3}|\\ [[^\\ ]]+\\ ])(?::\\ d+)?(?:(?:,[^,]+){2})?$" ), "," ); parts [0 ] != "_" {
334344 server := & http.Server {Addr : strings .TrimLeft (parts [0 ], "*" )}
335345 if len (parts ) > 1 {
0 commit comments