public Socket Accept() { if (_isClosed) { throw new ObjectDisposedException("Socket has been closed"); } if (_fd < 0) { // Invalid file descriptor throw new ZeroTier.Sockets.SocketException((int)Constants.ERR_SOCKET); } if (_isListening == false) { throw new InvalidOperationException("Socket is not in a listening state. Call Listen() first"); } // TODO: Rewrite -- Check for memory leaks // Inform zts_accept of the size of the available address buffer int addrlen = Marshal.SizeOf(typeof(zts_sockaddr_in)); IntPtr addrlenPtr = GCHandle.Alloc(addrlen, GCHandleType.Pinned).AddrOfPinnedObject(); // Allocate space for address buffer and provide pointer to zts_accept zts_sockaddr_in in4 = new zts_sockaddr_in(); IntPtr remoteAddrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(zts_sockaddr_in))); Marshal.StructureToPtr(in4, remoteAddrPtr, false); int err = zts_accept(_fd, remoteAddrPtr, addrlenPtr); if (err < 0) { throw new ZeroTier.Sockets.SocketException(err, ZeroTier.Core.Node.ErrNo); } in4 = (zts_sockaddr_in)Marshal.PtrToStructure(remoteAddrPtr, typeof(zts_sockaddr_in)); // Convert sockaddr contents to IPEndPoint IPAddress ipAddress = new IPAddress(in4.sin_addr); IPEndPoint clientEndPoint = new IPEndPoint(ipAddress, IPAddress.NetworkToHostOrder(((ushort)in4.sin_port)); // Create new socket by providing file descriptor returned from zts_accept call. Socket clientSocket = new Socket( err, _socketFamily, _socketType, _socketProtocol, _localEndPoint, clientEndPoint); Marshal.FreeHGlobal(remoteAddrPtr); return clientSocket; }
public void Connect(IPEndPoint remoteEndPoint) { if (_isClosed) { throw new ObjectDisposedException("Socket has been closed"); } if (_fd < 0) { // Invalid file descriptor throw new ZeroTier.Sockets.SocketException((int)Constants.ERR_SOCKET); } if (remoteEndPoint == null) { throw new ArgumentNullException("remoteEndPoint"); } int err = Constants.ERR_OK; int addrlen = 0; IntPtr remoteAddrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(zts_sockaddr))); if (remoteEndPoint.AddressFamily == AddressFamily.InterNetwork) { zts_sockaddr_in sa = new zts_sockaddr_in(); addrlen = Marshal.SizeOf(typeof(zts_sockaddr_in)); switch (remoteEndPoint.AddressFamily) { case AddressFamily.InterNetwork: sa.sin_family = (byte)Constants.AF_INET; break; case AddressFamily.InterNetworkV6: sa.sin_family = (byte)Constants.AF_INET6; break; case AddressFamily.Unknown: sa.sin_family = (byte)Constants.AF_UNSPEC; break; } sa.sin_port = (short)IPAddress.HostToNetworkOrder((ushort)remoteEndPoint.Port); sa.sin_addr = remoteEndPoint.Address.GetAddressBytes(); sa.sin_len = (byte)addrlen; // lwIP-specific Marshal.StructureToPtr(sa, remoteAddrPtr, false); //zts_sockaddr sAddr = (zts_sockaddr)Marshal.PtrToStructure(remoteAddrPtr, typeof(zts_sockaddr)); err = zts_connect(_fd, remoteAddrPtr, (byte)addrlen); } if (remoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6) { /* socketAddress.iSockaddrLength = Marshal.SizeOf(typeof(sockaddr_in6)); socketAddress.lpSockAddr = CriticalAllocHandle.FromSize(socketAddress.iSockaddrLength); sockaddr_in6 sa = new sockaddr_in6(); sa.sin6_family = (short)AddressFamily.InterNetworkV6; sa.sin6_port = (ushort)endpoint.Port; sa.sin6_addr = endpoint.Address.GetAddressBytes(); sa.sin6_scope_id = (uint)endpoint.Address.ScopeId; Marshal.StructureToPtr(sa, (IntPtr)socketAddress.lpSockAddr, false); */ } if (err < 0) { throw new ZeroTier.Sockets.SocketException(err, ZeroTier.Core.Node.ErrNo); } Marshal.FreeHGlobal(remoteAddrPtr); _remoteEndPoint = remoteEndPoint; _isConnected = true; }
public void Bind(IPEndPoint localEndPoint) { if (_isClosed) { throw new ObjectDisposedException("Socket has been closed"); } if (_fd < 0) { // Invalid file descriptor throw new ZeroTier.SocketException((int)Constants.ERR_SOCKET); } if (localEndPoint == null) { throw new ArgumentNullException("localEndPoint"); } int err = Constants.ERR_OK; int addrlen = 0; if (localEndPoint.AddressFamily == AddressFamily.InterNetwork) { zts_sockaddr_in sa = new zts_sockaddr_in(); addrlen = Marshal.SizeOf(typeof(zts_sockaddr_in)); switch (localEndPoint.AddressFamily) { case AddressFamily.InterNetwork: sa.sin_family = (byte)Constants.AF_INET; break; case AddressFamily.InterNetworkV6: sa.sin_family = (byte)Constants.AF_INET6; break; case AddressFamily.Unknown: sa.sin_family = (byte)Constants.AF_UNSPEC; break; } sa.sin_port = (short)zts_htons((ushort)localEndPoint.Port); sa.sin_addr = localEndPoint.Address.GetAddressBytes(); sa.sin_len = (byte)addrlen; // lwIP-specific IntPtr ptr1 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(zts_sockaddr))); Marshal.StructureToPtr(sa, ptr1, false); err = zts_bind(_fd, ptr1, (byte)addrlen); } if (localEndPoint.AddressFamily == AddressFamily.InterNetworkV6) { /* * socketAddress.iSockaddrLength = Marshal.SizeOf(typeof(sockaddr_in6)); * socketAddress.lpSockAddr = CriticalAllocHandle.FromSize(socketAddress.iSockaddrLength); * sockaddr_in6 sa = new sockaddr_in6(); * sa.sin6_family = (short)AddressFamily.InterNetworkV6; * sa.sin6_port = (ushort)endpoint.Port; * sa.sin6_addr = endpoint.Address.GetAddressBytes(); * sa.sin6_scope_id = (uint)endpoint.Address.ScopeId; * Marshal.StructureToPtr(sa, (IntPtr)socketAddress.lpSockAddr, false); */ } if (err < 0) { throw new ZeroTier.SocketException((int)err); } _localEndPoint = localEndPoint; }