Bind implements the linux syscall bind(2) for sockets backed by tcpip.Endpoint.
(_ *kernel.Task, sockaddr []byte)
| 853 | // Bind implements the linux syscall bind(2) for sockets backed by |
| 854 | // tcpip.Endpoint. |
| 855 | func (s *sock) Bind(_ *kernel.Task, sockaddr []byte) *syserr.Error { |
| 856 | if len(sockaddr) < 2 { |
| 857 | return syserr.ErrInvalidArgument |
| 858 | } |
| 859 | |
| 860 | family := hostarch.ByteOrder.Uint16(sockaddr) |
| 861 | var addr tcpip.FullAddress |
| 862 | |
| 863 | // Bind for AF_PACKET requires only family, protocol and ifindex. |
| 864 | // In function AddressAndFamily, we check the address length which is |
| 865 | // not needed for AF_PACKET bind. |
| 866 | if family == linux.AF_PACKET { |
| 867 | var a linux.SockAddrLink |
| 868 | if len(sockaddr) < linux.SockAddrLinkSize { |
| 869 | return syserr.ErrInvalidArgument |
| 870 | } |
| 871 | a.UnmarshalBytes(sockaddr) |
| 872 | |
| 873 | addr = tcpip.FullAddress{ |
| 874 | NIC: tcpip.NICID(a.InterfaceIndex), |
| 875 | Addr: tcpip.AddrFrom16Slice(append( |
| 876 | a.HardwareAddr[:header.EthernetAddressSize], |
| 877 | []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}..., |
| 878 | )), |
| 879 | Port: socket.Ntohs(a.Protocol), |
| 880 | } |
| 881 | } else { |
| 882 | if s.minSockAddrLen() > len(sockaddr) { |
| 883 | return syserr.ErrInvalidArgument |
| 884 | } |
| 885 | |
| 886 | var err *syserr.Error |
| 887 | addr, family, err = socket.AddressAndFamily(sockaddr) |
| 888 | if err != nil { |
| 889 | return err |
| 890 | } |
| 891 | |
| 892 | if !s.checkFamily(family, true /* exact */) { |
| 893 | return syserr.ErrAddressFamilyNotSupported |
| 894 | } |
| 895 | |
| 896 | addr = s.mapFamily(addr, family) |
| 897 | } |
| 898 | |
| 899 | // Issue the bind request to the endpoint. |
| 900 | err := s.Endpoint.Bind(addr) |
| 901 | if _, ok := err.(*tcpip.ErrNoPortAvailable); ok { |
| 902 | // Bind always returns EADDRINUSE irrespective of if the specified port was |
| 903 | // already bound or if an ephemeral port was requested but none were |
| 904 | // available. |
| 905 | // |
| 906 | // *tcpip.ErrNoPortAvailable is mapped to EAGAIN in syserr package because |
| 907 | // UDP connect returns EAGAIN on ephemeral port exhaustion. |
| 908 | // |
| 909 | // TCP connect returns EADDRNOTAVAIL on ephemeral port exhaustion. |
| 910 | err = &tcpip.ErrPortInUse{} |
| 911 | } |
| 912 |
nothing calls this directly
no test coverage detected