MCPcopy Index your code
hub / github.com/subtrace/subtrace / Connect

Method Connect

cmd/run/socket/socket.go:76–387  ·  view source on GitHub ↗
(addr netip.AddrPort)

Source from the content-addressed store, hash-verified

74}
75
76func (s *Socket) Connect(addr netip.AddrPort) (syscall.Errno, error) {
77 if !s.FD.IncRef() {
78 return unix.EBADF, nil
79 }
80 defer s.FD.DecRef()
81
82 prev := s.Inode.state.Load()
83 switch prev.state {
84 case StatePassive:
85 break
86 case StateConnected:
87 return unix.EISCONN, nil
88 case StateConnecting:
89 flags, err := unix.FcntlInt(uintptr(s.FD.FD()), unix.F_GETFL, 0)
90 if err != nil {
91 return 0, fmt.Errorf("fcntl: %w", err)
92 }
93 if isBlocking := flags&unix.O_NONBLOCK == 0; isBlocking {
94 // TODO: can this even happen? If the socket is a blocking socket, how
95 // can it ever end up in the connecting state? The connect(2) manpage
96 // doesn't prescribe any explicit behavior.
97 return unix.EALREADY, nil
98 } else {
99 return unix.EINPROGRESS, nil
100 }
101 case StateListening:
102 return unix.EINVAL, nil // TODO: what does linux say if you try to connect a listening socket?
103 case StateClosed:
104 return unix.EBADF, nil
105 }
106
107 proxy := newProxy(s.global, s.tmpl, true)
108 proxy.socket = s
109
110 flags, err := unix.FcntlInt(uintptr(s.FD.FD()), unix.F_GETFL, 0)
111 if err != nil {
112 return 0, fmt.Errorf("fcntl: %w", err)
113 }
114 isBlocking := flags&unix.O_NONBLOCK == 0
115
116 bind, errno, err := prev.getRemoteBindAddr()
117 if err != nil {
118 return 0, fmt.Errorf("get bind addr: %w", err)
119 }
120 if errno != 0 {
121 return errno, nil
122 }
123
124 slog.Debug("attempting socket connect", "sock", s, "addr", addr, "bind", bind, "isBlocking", isBlocking)
125
126 mid := &ImmutableState{state: StateConnecting}
127 mid.connecting.bind = prev.passive.bind
128 mid.connecting.peer = addr
129
130 if mid.connecting.bind == nil {
131 var err error
132 mid.connecting.bind, err = newTempBindSocket(s.Inode.Domain)
133 if err != nil {

Callers 1

handleConnectMethod · 0.45

Calls 15

newProxyFunction · 0.85
newTempBindSocketFunction · 0.85
bindEphemeralFunction · 0.85
newDummyListenerFunction · 0.85
IncRefMethod · 0.80
DecRefMethod · 0.80
LoadMethod · 0.80
FDMethod · 0.80
getRemoteBindAddrMethod · 0.80
ClosingIncRefMethod · 0.80
LockMethod · 0.80
AddMethod · 0.80

Tested by

no test coverage detected