Beispiel #1
0
        private void bind(IPEndPoint endpoint, int backlog)
        {
            Sockaddr servaddr = new SockaddrIn()
            {
                sa_family  = UnixAddressFamily.AF_INET,
                sin_family = UnixAddressFamily.AF_INET,
                sin_addr   = new InAddr()
                {
                    s_addr = BitConverter.ToUInt32(endpoint.Address.GetAddressBytes(), 0)
                },
                sin_port = Syscall.htons((ushort)endpoint.Port)
            };

            // Bind so we are attached
            var ret = Syscall.bind(listenerSocket, servaddr);

            if (ret < 0)
            {
                throw new IOException($"Failed to bind to endpoint: {Stdlib.GetLastError()}");
            }

            // start listening
            ret = Syscall.listen(listenerSocket, backlog);
            if (ret < 0)
            {
                throw new IOException($"Failed to set socket to listen: {Stdlib.GetLastError()}");
            }
        }
Beispiel #2
0
        public void SockaddrInTest()
        {
            var address1 = new SockaddrIn {
                sin_family = UnixAddressFamily.AF_INET,
                sin_port   = Syscall.htons(5678),
                sin_addr   = NativeConvert.ToInAddr(IPAddress.Loopback),
            };

            var storage  = address1.ToSockaddrStorage();
            var address2 = SockaddrIn.FromSockaddrStorage(storage);

            Assert.AreEqual(address1, address2);

            var sockaddr = Sockaddr.FromSockaddrStorage(storage);

            Assert.AreEqual(sockaddr.sa_family, address1.sa_family);

            var storage2 = storage.ToSockaddrStorage();

            Assert.AreEqual(storage, storage2);

            var storage3 = new SockaddrStorage(123);

            storage2.CopyTo(storage3);
            Assert.AreEqual(storage, storage3);

            Assert.AreEqual("{sin_family=AF_INET, sin_port=htons(5678), sin_addr=127.0.0.1}", address1.ToString());
        }
Beispiel #3
0
        public void IPv6()
        {
            if (!Socket.OSSupportsIPv6)
            {
                Assert.Ignore("OS does not support IPv6.");
            }

            var address = new SockaddrIn6 {
                sin6_family = UnixAddressFamily.AF_INET6,
                sin6_port   = Syscall.htons(0),
                sin6_addr   = NativeConvert.ToIn6Addr(IPAddress.IPv6Loopback),
            };

            WithSockets(UnixAddressFamily.AF_INET6, UnixSocketType.SOCK_STREAM, 0, (so1, so2) => {
                if (Syscall.bind(so1, address) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }

                var address1Stor = new SockaddrStorage();
                if (Syscall.getsockname(so1, address1Stor) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }
                var address1 = new SockaddrIn6();
                address1Stor.CopyTo(address1);

                // Check getsockname(socket, null)
                if (Syscall.getsockname(so1, null) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }

                var address2 = new SockaddrIn6();
                if (Syscall.getsockname(so1, address2) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }

                Assert.AreEqual(address1, address2);
                Assert.IsTrue(Syscall.ntohs(address1.sin6_port) != 0);
                address1.sin6_port = 0;
                Assert.AreEqual(address, address1);

                var address3 = new Sockaddr();
                if (Syscall.getsockname(so1, address3) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }
                Assert.AreEqual(address.sa_family, address3.sa_family);

                // Try to store a sockaddr_in6 into a Sockaddr. Should fail because sockaddr_in6 should be larger than sockaddr_in
                var address4 = new SockaddrIn();
                if (Syscall.getsockname(so1, address4) == 0)
                {
                    Assert.Fail("getsockname() should have failed");
                }
                Assert.AreEqual(Errno.ENOBUFS, Stdlib.GetLastError());
            });
        }
Beispiel #4
0
        [ExpectedException(typeof(ArgumentOutOfRangeException))]           // IPPROTO_UDP not supported
#endif
        public void SendToRecvFrom()
        {
            WithSockets(UnixAddressFamily.AF_INET, UnixSocketType.SOCK_DGRAM, UnixSocketProtocol.IPPROTO_UDP, (so1, so2) => {
                // Bind UDP socket so1 to 127.0.0.1 with dynamic port
                var address = new SockaddrIn {
                    sin_family = UnixAddressFamily.AF_INET, sin_port = Syscall.htons(0), sin_addr = new InAddr(127, 0, 0, 1)
                };
                if (Syscall.bind(so1, address) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }

                // Get actual port number using getsockname()
                var actualAddress = new SockaddrIn();
                if (Syscall.getsockname(so1, actualAddress) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }
                Assert.AreEqual(actualAddress.sa_family, UnixAddressFamily.AF_INET);
                var port = Syscall.ntohs(actualAddress.sin_port);
                Assert.IsTrue(port != 0);


                var remoteAddress = new SockaddrIn {
                    sin_family = UnixAddressFamily.AF_INET,
                    sin_port   = Syscall.htons(port),
                    sin_addr   = new InAddr(127, 0, 0, 1),
                };

                // Send and receive a few bytes
                long ret;
                var buffer1 = new byte[] { 42, 43, 44 };
                ret         = Syscall.sendto(so2, buffer1, (ulong)buffer1.Length, 0, remoteAddress);
                if (ret < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }

                var senderAddress = new SockaddrIn();
                var buffer2       = new byte[1024];
                ret = Syscall.recvfrom(so1, buffer2, (ulong)buffer2.Length, 0, senderAddress);
                if (ret < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }
                Assert.AreEqual(senderAddress.sa_family, UnixAddressFamily.AF_INET);
                Assert.AreEqual(senderAddress.sin_addr, new InAddr(127, 0, 0, 1));

                Assert.AreEqual(buffer1.Length, ret);
                for (int i = 0; i < buffer1.Length; i++)
                {
                    Assert.AreEqual(buffer1[i], buffer2[i]);
                }
            });
        }
Beispiel #5
0
        private unsafe static void Connect(IntPtr socket, IPEndPoint ipEndPoint)
        {
            var endPointAddressBytes = ipEndPoint.Address.GetAddressBytes();
            var inAddress            = new InAddr(endPointAddressBytes);

            var sa = new SockaddrIn
            {
                sin_family = AddressFamilies.AF_INET,
                sin_port   = WinSock.htons((ushort)ipEndPoint.Port),
                sin_addr   = inAddress
            };

            var errorCode = WinSock.connect(socket, ref sa, sizeof(SockaddrIn));

            if (errorCode == WinSock.Consts.SOCKET_ERROR)
            {
                WinSock.ThrowLastWsaError();
            }
        }
Beispiel #6
0
        /// <summary>
        /// Waits for a connection and accepts the socket
        /// </summary>
        /// <returns>The socket and endpoint.</returns>
        /// <param name="cancellationToken">Cancellation token.</param>
        public Task <KeyValuePair <long, EndPoint> > AcceptAsync(CancellationToken cancellationToken)
        {
            // TODO: Support the cancellationToken
            return(Task.Run(() => {
                var addr = new SockaddrIn();
                var ret = Syscall.accept(m_socket, addr);
                if (ret < 0)
                {
                    throw new IOException($"Failed to accept: {Stdlib.GetLastError()}");
                }

                // Dummy endpoint
                var endpoint = new IPEndPoint(IPAddress.Any, 0);
                // If we get a real endpoint, use that
                if (addr is SockaddrIn sain)
                {
                    endpoint = new IPEndPoint((long)sain.sin_addr.s_addr, sain.sin_port);
                }

                return new KeyValuePair <long, EndPoint>(ret, endpoint);
            }));
        }
Beispiel #7
0
        private static unsafe bool Bind(IntPtr listeningSocket, int listeningPort)
        {
            var endPointAddressBytes = IPAddress.Any.GetAddressBytes();
            var inAddress            = new InAddr(endPointAddressBytes);

            var sa = new SockaddrIn
            {
                sin_family = AddressFamilies.AF_INET,
                sin_port   = WinSock.htons((ushort)listeningPort),
                sin_addr   = inAddress
            };

            var errorCode = WinSock.bind(listeningSocket, ref sa, sizeof(SockaddrIn));

            if (errorCode == WinSock.Consts.SOCKET_ERROR)
            {
                WinSock.ThrowLastWsaError();
                return(false);
            }

            return(true);
        }
Beispiel #8
0
		public unsafe void SendMsgRecvMsgAddress ()
		{
			WithSockets (UnixAddressFamily.AF_INET, UnixSocketType.SOCK_DGRAM, UnixSocketProtocol.IPPROTO_UDP, (so1, so2) => {
				// Bind UDP socket so1 to 127.0.0.1 with dynamic port
				var address = new SockaddrIn {
					sin_family = UnixAddressFamily.AF_INET,
					sin_port = Syscall.htons (0),
					sin_addr = new InAddr (127, 0, 0, 1),
				};
				if (Syscall.bind (so1, address) < 0)
					UnixMarshal.ThrowExceptionForLastError ();

				// Get actual port number using getsockname()
				var actualAddress = new SockaddrIn ();
				if (Syscall.getsockname (so1, actualAddress) < 0)
					UnixMarshal.ThrowExceptionForLastError ();
				Assert.AreEqual (actualAddress.sa_family, UnixAddressFamily.AF_INET);
				var port = Syscall.ntohs (actualAddress.sin_port);
				Assert.IsTrue (port != 0);


				var remoteAddress = new SockaddrIn {
					sin_family = UnixAddressFamily.AF_INET,
					sin_port = Syscall.htons (port),
					sin_addr = new InAddr (127, 0, 0, 1),
				};

				// Send and receive a few bytes
				long ret;
				var buffer1 = new byte[] { 42, 43, 44 };
				fixed (byte* ptr_buffer1 = buffer1) {
					var iovecs1 = new Iovec[] {
						new Iovec {
							iov_base = (IntPtr) ptr_buffer1,
							iov_len = (ulong) buffer1.Length,
						},
					};
					var msghdr1 = new Msghdr {
						msg_name = remoteAddress,
						msg_iov = iovecs1,
						msg_iovlen = 1,
					};
					ret = Syscall.sendmsg (so2, msghdr1, 0);
					msghdr1.msg_name = remoteAddress.ToSockaddrStorage ();
					if (ret >= 0)
						ret = Syscall.sendmsg (so2, msghdr1, 0);
				}
				if (ret < 0)
					UnixMarshal.ThrowExceptionForLastError ();

				var senderAddress = new SockaddrIn ();
				var senderAddressStorage = new SockaddrStorage ();
				var buffer2 = new byte[1024];
				var buffer3 = new byte[1024];
				fixed (byte* ptr_buffer2 = buffer2, ptr_buffer3 = buffer3) {
					var iovecs2 = new Iovec[] {
						new Iovec {
							iov_base = (IntPtr) ptr_buffer2,
							iov_len = (ulong) buffer2.Length,
						},
					};
					var msghdr2 = new Msghdr {
						msg_name = senderAddress,
						msg_iov = iovecs2,
						msg_iovlen = 1,
					};
					ret = Syscall.recvmsg (so1, msghdr2, 0);
					msghdr2.msg_name = senderAddressStorage;
					iovecs2[0].iov_base = (IntPtr) ptr_buffer3;
					if (ret >= 0)
						ret = Syscall.recvmsg (so1, msghdr2, 0);
				}
				if (ret < 0)
					UnixMarshal.ThrowExceptionForLastError ();
				Assert.AreEqual (senderAddress.sa_family, UnixAddressFamily.AF_INET);
				Assert.AreEqual (senderAddress.sin_addr, new InAddr (127, 0, 0, 1));
				var senderAddress2 = SockaddrIn.FromSockaddrStorage (senderAddressStorage);
				Assert.AreEqual (senderAddress2.sa_family, UnixAddressFamily.AF_INET);
				Assert.AreEqual (senderAddress2.sin_addr, new InAddr (127, 0, 0, 1));

				Assert.AreEqual (buffer1.Length, ret);
				for (int i = 0; i < buffer1.Length; i++)
					Assert.AreEqual (buffer1[i], buffer2[i]);
				for (int i = 0; i < buffer1.Length; i++)
					Assert.AreEqual (buffer1[i], buffer3[i]);
			});
		}
Beispiel #9
0
		public void SendToRecvFrom ()
		{
			WithSockets (UnixAddressFamily.AF_INET, UnixSocketType.SOCK_DGRAM, UnixSocketProtocol.IPPROTO_UDP, (so1, so2) => {
				// Bind UDP socket so1 to 127.0.0.1 with dynamic port
				var address = new SockaddrIn { sin_family = UnixAddressFamily.AF_INET, sin_port = Syscall.htons (0), sin_addr = new InAddr (127, 0, 0, 1) };
				if (Syscall.bind (so1, address) < 0)
					UnixMarshal.ThrowExceptionForLastError ();

				// Get actual port number using getsockname()
				var actualAddress = new SockaddrIn ();
				if (Syscall.getsockname (so1, actualAddress) < 0)
					UnixMarshal.ThrowExceptionForLastError ();
				Assert.AreEqual (actualAddress.sa_family, UnixAddressFamily.AF_INET);
				var port = Syscall.ntohs (actualAddress.sin_port);
				Assert.IsTrue (port != 0);


				var remoteAddress = new SockaddrIn {
					sin_family = UnixAddressFamily.AF_INET,
					sin_port = Syscall.htons (port),
					sin_addr = new InAddr (127, 0, 0, 1),
				};

				// Send and receive a few bytes
				long ret;
				var buffer1 = new byte[] { 42, 43, 44 };
				ret = Syscall.sendto (so2, buffer1, (ulong) buffer1.Length, 0, remoteAddress);
				if (ret < 0)
					UnixMarshal.ThrowExceptionForLastError ();

				var senderAddress = new SockaddrIn ();
				var buffer2 = new byte[1024];
				ret = Syscall.recvfrom (so1, buffer2, (ulong) buffer2.Length, 0, senderAddress);
				if (ret < 0)
					UnixMarshal.ThrowExceptionForLastError ();
				Assert.AreEqual (senderAddress.sa_family, UnixAddressFamily.AF_INET);
				Assert.AreEqual (senderAddress.sin_addr, new InAddr (127, 0, 0, 1));

				Assert.AreEqual (buffer1.Length, ret);
				for (int i = 0; i < buffer1.Length; i++)
					Assert.AreEqual (buffer1[i], buffer2[i]);
			});
		}
Beispiel #10
0
		public void IPv6 ()
		{
			if (!Socket.OSSupportsIPv6)
				Assert.Ignore ("OS does not support IPv6.");

			var address = new SockaddrIn6 {
				sin6_family = UnixAddressFamily.AF_INET6,
				sin6_port = Syscall.htons (0),
				sin6_addr = NativeConvert.ToIn6Addr (IPAddress.IPv6Loopback),
			};
			WithSockets (UnixAddressFamily.AF_INET6, UnixSocketType.SOCK_STREAM, 0, (so1, so2) => {
				if (Syscall.bind (so1, address) < 0)
					UnixMarshal.ThrowExceptionForLastError ();

				var address1Stor = new SockaddrStorage ();
				if (Syscall.getsockname (so1, address1Stor) < 0)
					UnixMarshal.ThrowExceptionForLastError ();
				var address1 = new SockaddrIn6 ();
				address1Stor.CopyTo (address1);

				// Check getsockname(socket, null)
				if (Syscall.getsockname (so1, null) < 0)
					UnixMarshal.ThrowExceptionForLastError ();

				var address2 = new SockaddrIn6 ();
				if (Syscall.getsockname (so1, address2) < 0)
					UnixMarshal.ThrowExceptionForLastError ();

				Assert.AreEqual (address1, address2);
				Assert.IsTrue (Syscall.ntohs (address1.sin6_port) != 0);
				address1.sin6_port = 0;
				Assert.AreEqual (address, address1);

				var address3 = new Sockaddr ();
				if (Syscall.getsockname (so1, address3) < 0)
					UnixMarshal.ThrowExceptionForLastError ();
				Assert.AreEqual (address.sa_family, address3.sa_family);

				// Try to store a sockaddr_in6 into a Sockaddr. Should fail because sockaddr_in6 should be larger than sockaddr_in
				var address4 = new SockaddrIn ();
				if (Syscall.getsockname (so1, address4) == 0)
					Assert.Fail ("getsockname() should have failed");
				Assert.AreEqual (Errno.ENOBUFS, Stdlib.GetLastError ());
			});
		}
Beispiel #11
0
		public void SockaddrInTest ()
		{
			var address1 = new SockaddrIn {
				sin_family = UnixAddressFamily.AF_INET,
				sin_port = Syscall.htons (5678),
				sin_addr = NativeConvert.ToInAddr (IPAddress.Loopback),
			};

			var storage = address1.ToSockaddrStorage ();
			var address2 = SockaddrIn.FromSockaddrStorage (storage);
			Assert.AreEqual (address1, address2);

			var sockaddr = Sockaddr.FromSockaddrStorage (storage);
			Assert.AreEqual (sockaddr.sa_family, address1.sa_family);

			var storage2 = storage.ToSockaddrStorage ();
			Assert.AreEqual (storage, storage2);

			var storage3 = new SockaddrStorage (123);
			storage2.CopyTo (storage3);
			Assert.AreEqual (storage, storage3);

			Assert.AreEqual ("{sin_family=AF_INET, sin_port=htons(5678), sin_addr=127.0.0.1}", address1.ToString ());
		}
		private static extern int FromSockaddrIn (SockaddrIn source, IntPtr destination);
		public static bool TryCopy (SockaddrIn source, IntPtr destination)
		{
			return FromSockaddrIn (source, destination) == 0;
		}
Beispiel #14
0
        [ExpectedException(typeof(ArgumentOutOfRangeException))]           // IPPROTO_UDP not supported
#endif
        public unsafe void SendMsgRecvMsgAddress()
        {
            WithSockets(UnixAddressFamily.AF_INET, UnixSocketType.SOCK_DGRAM, UnixSocketProtocol.IPPROTO_UDP, (so1, so2) => {
                // Bind UDP socket so1 to 127.0.0.1 with dynamic port
                var address = new SockaddrIn {
                    sin_family = UnixAddressFamily.AF_INET,
                    sin_port   = Syscall.htons(0),
                    sin_addr   = new InAddr(127, 0, 0, 1),
                };
                if (Syscall.bind(so1, address) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }

                // Get actual port number using getsockname()
                var actualAddress = new SockaddrIn();
                if (Syscall.getsockname(so1, actualAddress) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }
                Assert.AreEqual(actualAddress.sa_family, UnixAddressFamily.AF_INET);
                var port = Syscall.ntohs(actualAddress.sin_port);
                Assert.IsTrue(port != 0);


                var remoteAddress = new SockaddrIn {
                    sin_family = UnixAddressFamily.AF_INET,
                    sin_port   = Syscall.htons(port),
                    sin_addr   = new InAddr(127, 0, 0, 1),
                };

                // Send and receive a few bytes
                long ret;
                var buffer1             = new byte[] { 42, 43, 44 };
                fixed(byte *ptr_buffer1 = buffer1)
                {
                    var iovecs1 = new Iovec[] {
                        new Iovec {
                            iov_base = (IntPtr)ptr_buffer1,
                            iov_len  = (ulong)buffer1.Length,
                        },
                    };
                    var msghdr1 = new Msghdr {
                        msg_name   = remoteAddress,
                        msg_iov    = iovecs1,
                        msg_iovlen = 1,
                    };
                    ret = Syscall.sendmsg(so2, msghdr1, 0);
                    msghdr1.msg_name = remoteAddress.ToSockaddrStorage();
                    if (ret >= 0)
                    {
                        ret = Syscall.sendmsg(so2, msghdr1, 0);
                    }
                }
                if (ret < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }

                var senderAddress        = new SockaddrIn();
                var senderAddressStorage = new SockaddrStorage();
                var buffer2             = new byte[1024];
                var buffer3             = new byte[1024];
                fixed(byte *ptr_buffer2 = buffer2, ptr_buffer3 = buffer3)
                {
                    var iovecs2 = new Iovec[] {
                        new Iovec {
                            iov_base = (IntPtr)ptr_buffer2,
                            iov_len  = (ulong)buffer2.Length,
                        },
                    };
                    var msghdr2 = new Msghdr {
                        msg_name   = senderAddress,
                        msg_iov    = iovecs2,
                        msg_iovlen = 1,
                    };
                    ret = Syscall.recvmsg(so1, msghdr2, 0);
                    msghdr2.msg_name    = senderAddressStorage;
                    iovecs2[0].iov_base = (IntPtr)ptr_buffer3;
                    if (ret >= 0)
                    {
                        ret = Syscall.recvmsg(so1, msghdr2, 0);
                    }
                }
                if (ret < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }
                Assert.AreEqual(senderAddress.sa_family, UnixAddressFamily.AF_INET);
                Assert.AreEqual(senderAddress.sin_addr, new InAddr(127, 0, 0, 1));
                var senderAddress2 = SockaddrIn.FromSockaddrStorage(senderAddressStorage);
                Assert.AreEqual(senderAddress2.sa_family, UnixAddressFamily.AF_INET);
                Assert.AreEqual(senderAddress2.sin_addr, new InAddr(127, 0, 0, 1));

                Assert.AreEqual(buffer1.Length, ret);
                for (int i = 0; i < buffer1.Length; i++)
                {
                    Assert.AreEqual(buffer1[i], buffer2[i]);
                }
                for (int i = 0; i < buffer1.Length; i++)
                {
                    Assert.AreEqual(buffer1[i], buffer3[i]);
                }
            });
        }
Beispiel #15
0
        /// <summary>
        /// Creates a socket listening to the supplied endpoint
        /// </summary>
        /// <param name="endpoint">The endpoint we listen to.</param>
        /// <param name="backlog">The connection backlog</param>
        /// <param name="autodeletedomainsocket">A flag indicating if the domain socket should be attempted deleted</param>
        public void Bind(EndPoint endpoint, int backlog, bool autodeletedomainsocket)
        {
            try
            {
                Sockaddr servaddr;
                var      filepath = string.Empty;

                if (endpoint is IPEndPoint ipe)
                {
                    // Set up the IP address we are listening on
                    servaddr = new SockaddrIn()
                    {
                        sa_family  = UnixAddressFamily.AF_INET,
                        sin_family = UnixAddressFamily.AF_INET,
                        sin_addr   = new InAddr()
                        {
                            s_addr = BitConverter.ToUInt32(ipe.Address.GetAddressBytes(), 0)
                        },
                        sin_port = Syscall.htons((ushort)ipe.Port)
                    };

                    // Prepare the socket for TCP/IP
                    SetupSocket(UnixAddressFamily.AF_INET);
                }
                else if (endpoint is UnixEndPoint upe)
                {
                    var isHidden = upe.Filename[0] == 0;
                    if (!isHidden)
                    {
                        filepath = upe.Filename;
                    }
                    servaddr = new SockaddrUn(upe.Filename.Substring(isHidden ? 1 : 0), isHidden);
                    // Prepare the socket for Unix Domain Socket
                    SetupSocket(UnixAddressFamily.AF_UNIX);
                }
                else if (endpoint is System.Net.Sockets.UnixDomainSocketEndPoint udse)
                {
                    var name     = udse.ToString();
                    var isHidden = name[0] == 0 || name[0] == '@';
                    if (!isHidden)
                    {
                        filepath = name;
                    }
                    servaddr = new SockaddrUn(name.Substring(isHidden ? 1 : 0), isHidden);
                    // Prepare the socket for Unix Domain Socket
                    SetupSocket(UnixAddressFamily.AF_UNIX);
                }
                else
                {
                    throw new NotSupportedException($"EndPoint not supported: {endpoint.GetType()}");
                }

                // Bind so we are attached
                var ret = Syscall.bind(m_socket, servaddr);
                if (ret < 0)
                {
                    // Save original error code
                    var err = Stdlib.GetLastError();

                    // Handle auto-delete of sockets
                    if (autodeletedomainsocket && err == Errno.EADDRINUSE && TryDeleteDomainSocket(servaddr, filepath))
                    {
                        Syscall.close(m_socket);
                        m_socket = -1;
                        Bind(endpoint, backlog, false);
                        return;
                    }

                    throw new IOException($"Failed to bind to endpoint: {err}");
                }

                ret = Syscall.listen(m_socket, backlog);
                if (ret < 0)
                {
                    throw new IOException($"Failed to set socket to listen: {Stdlib.GetLastError()}");
                }
            }
            catch
            {
                // Avoid leaving the listensocket in an invalid state
                if (m_socket != -1)
                {
                    try { Syscall.close(m_socket); }
                    catch {}

                    m_socket = -1;
                }
                throw;
            }
        }
		private static extern int ToSockaddrIn (IntPtr source, SockaddrIn destination);
		public static bool TryCopy (IntPtr source, SockaddrIn destination)
		{
			return ToSockaddrIn (source, destination) == 0;
		}