MCPcopy Create free account
hub / github.com/subtrace/subtrace / Bind

Method Bind

cmd/run/socket/socket.go:392–462  ·  view source on GitHub ↗

Bind binds the socket to the given address. Internally, it uses a dummy temporary socket in order to check if the address is bindable and also reserve the address for future operations.

(addr netip.AddrPort)

Source from the content-addressed store, hash-verified

390// temporary socket in order to check if the address is bindable and also
391// reserve the address for future operations.
392func (s *Socket) Bind(addr netip.AddrPort) (syscall.Errno, error) {
393 if !s.FD.IncRef() {
394 return unix.EBADF, nil
395 }
396 defer s.FD.DecRef()
397
398 prev := s.Inode.state.Load()
399 switch prev.state {
400 case StatePassive:
401 break
402 case StateConnected, StateConnecting, StateListening:
403 return unix.EINVAL, nil
404 case StateClosed:
405 return unix.EBADF, nil
406 }
407
408 if s.Inode.Domain == unix.AF_INET && !addr.Addr().Is4() {
409 return unix.EINVAL, nil
410 }
411 if s.Inode.Domain == unix.AF_INET6 && !addr.Addr().Is6() {
412 return unix.EINVAL, nil
413 }
414
415 next := &ImmutableState{state: StatePassive}
416 next.passive.bind = prev.passive.bind
417 if next.passive.bind == nil {
418 var err error
419 next.passive.bind, err = newTempBindSocket(s.Inode.Domain)
420 if err != nil {
421 return 0, fmt.Errorf("create temp bind socket: %w", err)
422 }
423 }
424
425 if !next.passive.bind.IncRef() {
426 return unix.EBADF, nil
427 }
428 defer next.passive.bind.DecRef()
429
430 var sa unix.Sockaddr
431 switch s.Inode.Domain {
432 case unix.AF_INET:
433 sa = &unix.SockaddrInet4{Addr: addr.Addr().As4(), Port: int(addr.Port())}
434 case unix.AF_INET6:
435 sa = &unix.SockaddrInet6{Addr: addr.Addr().As16(), Port: int(addr.Port())}
436 }
437
438 if err := unix.Bind(next.passive.bind.FD(), sa); err != nil {
439 if prev.passive.bind == nil {
440 unix.Close(next.passive.bind.FD())
441 }
442 next := &ImmutableState{state: StatePassive}
443 next.passive.bind = prev.passive.bind
444 if !errors.As(err, &next.passive.errno) {
445 return 0, fmt.Errorf("bind: %w", err)
446 }
447 if !s.Inode.state.CompareAndSwap(prev, next) {
448 return unix.ERESTART, nil
449 }

Callers 2

handleBindMethod · 0.80
bindEphemeralFunction · 0.80

Calls 7

newTempBindSocketFunction · 0.85
IncRefMethod · 0.80
DecRefMethod · 0.80
LoadMethod · 0.80
AddrMethod · 0.80
FDMethod · 0.80
CloseMethod · 0.45

Tested by

no test coverage detected