MCPcopy Create free account
hub / github.com/Hidden-Node/GooseRelayVPN-AndroidClient / openSession

Method openSession

internal/exit/exit.go:569–677  ·  view source on GitHub ↗

openSession dials the upstream target, creates a Session for the given ID, registers it under the given owner, and spawns the bidirectional pump goroutines.

(id [frame.SessionIDLen]byte, target string, owner [frame.ClientIDLen]byte)

Source from the content-addressed store, hash-verified

567// registers it under the given owner, and spawns the bidirectional pump
568// goroutines.
569func (s *Server) openSession(id [frame.SessionIDLen]byte, target string, owner [frame.ClientIDLen]byte) (*session.Session, error) {
570 var upstream net.Conn
571 var res *dialResult
572 if s.cfg.UpstreamProxy != "" {
573 // Let the SOCKS5 proxy handle DNS so the target hostname is resolved
574 // on the proxy side (e.g. through WARP), not locally on the VPS.
575 conn, err := s.dial("tcp", target, 15*time.Second)
576 if err != nil {
577 return nil, err
578 }
579 upstream = conn
580 } else {
581 var err error
582 res, err = dialWithDNSCache(s.dns, s.dial, "tcp", target, 15*time.Second)
583 if err != nil {
584 return nil, err
585 }
586 upstream = res.Conn
587 }
588 // Disable Nagle's algorithm so small writes (TLS handshake records, HTTP
589 // request lines) hit the wire immediately instead of waiting up to 40 ms
590 // to coalesce. Interactive workloads dominate this tunnel; throughput-bound
591 // flows already buffer at the kernel level.
592 if tcpConn, ok := upstream.(*net.TCPConn); ok {
593 _ = tcpConn.SetNoDelay(true)
594 }
595 if s.debugTiming {
596 if res != nil {
597 log.Printf("[timing] %x dial dns=%dms cached=%v tcp=%dms target=%s",
598 id[:4], res.DNS.Milliseconds(), res.DNSCached, res.TCP.Milliseconds(), target)
599 } else {
600 log.Printf("[timing] %x dial via proxy target=%s", id[:4], target)
601 }
602 }
603 dialedAt := time.Now()
604 sess := session.New(id, target, false)
605 sess.OnTx = func() {
606 s.mu.Lock()
607 s.txReady[id] = struct{}{}
608 s.mu.Unlock()
609 s.kick(owner)
610 }
611
612 s.mu.Lock()
613 s.sessions[id] = sess
614 s.sessionOwners[id] = owner
615 s.upstreams[id] = upstream
616 s.firstReply[id] = struct{}{}
617 s.lastActivity[id] = time.Now()
618 s.mu.Unlock()
619 s.stats.sessionsOpen.Add(1)
620
621 log.Printf("[exit] new session %x owner=%x -> %s", id[:4], owner[:4], target)
622
623 // Upstream → session.EnqueueTx (downstream direction).
624 go func() {
625 defer upstream.Close()
626 bufP := s.upstreamReadPool.Get().(*[]byte)

Callers 2

routeIncomingMethod · 0.95
routeIncomingNoBackoffFunction · 0.80

Calls 9

kickMethod · 0.95
NewFunction · 0.92
dialWithDNSCacheFunction · 0.85
CloseMethod · 0.80
EnqueueTxMethod · 0.80
RequestCloseMethod · 0.80
ReadMethod · 0.45
StopMethod · 0.45
WriteMethod · 0.45

Tested by 1

routeIncomingNoBackoffFunction · 0.64