Example #1
0
        public override void Bind(UInt32 ipAddress, UInt16 ipPort)
        {
            if (_sourceIpAddressAndPortAssigned)
            {
                throw Utility.NewSocketException(SocketError.IsConnected); /* is this correct; should we throw an exception if we already have an IP address/port assigned? */
            }
            _sourceIpAddressAndPortAssigned = true;

            // if ipAddress is IP_ADDRESS_ANY, then change it to to our actual ipAddress.
            if (ipAddress == IP_ADDRESS_ANY)
            {
                ipAddress = _ipv4Layer.IPAddress;
            }

            if (ipPort == IP_PORT_ANY)
            {
                ipPort = _ipv4Layer.GetNextEphemeralPortNumber(IPv4Layer.ProtocolType.Udp) /* next available ephemeral port # */;
            }

            // verify that this source IP address is correct
            if (ipAddress != _ipv4Layer.IPAddress)
            {
                throw Utility.NewSocketException(SocketError.AddressNotAvailable);
            }

            /* ensure that no other UdpSockets are bound to this address/port */
            for (int iSocketHandle = 0; iSocketHandle < IPv4Layer.MAX_SIMULTANEOUS_SOCKETS; iSocketHandle++)
            {
                Socket socket = _ipv4Layer.GetSocket(iSocketHandle);
                if (socket != null &&
                    socket.ProtocolType == IPv4Layer.ProtocolType.Udp &&
                    socket.SourceIPAddress == ipAddress &&
                    socket.SourceIPPort == ipPort)
                {
                    throw Utility.NewSocketException(SocketError.AddressAlreadyInUse);
                }
            }

            _srcIPAddress = ipAddress;
            _srcIPPort    = ipPort;
        }
        bool SendDnsQueryAndWaitForResponse(UInt32 dnsServerIPAddress, DnsRecordType recordType, string name, out DnsResponse dnsResponse, Int64 timeoutInMachineTicks)
        {
            // obtain an exclusive handle to the reserved socket
            int socketHandle = _ipv4Layer.CreateSocket(IPv4Layer.ProtocolType.Udp, timeoutInMachineTicks, true);
            // instantiate the reserved socket
            UdpSocket socket = (UdpSocket)_ipv4Layer.GetSocket(socketHandle);

            try
            {
                // create DNS request header
                byte[] dnsRequestBuffer = new byte[DNS_FRAME_BUFFER_LENGTH];
                int    bufferIndex      = 0;
                /* Transaction ID */
                UInt16 transactionID = _nextTransactionID++;
                dnsRequestBuffer[bufferIndex++] = (byte)((transactionID >> 8) & 0xFF);
                dnsRequestBuffer[bufferIndex++] = (byte)(transactionID & 0xFF);
                /* Flags (including OpCode and RCODE) */
                DnsMessageFlagsFlags flags = 0;

                /* QR = 0 (query)
                 * OpCode = 0 (standard query/response)
                 * RD = 1 (recursion desired) */
                flags |= DnsMessageFlagsFlags.RecursionDesired;
                dnsRequestBuffer[bufferIndex++] |= (byte)(((UInt16)flags >> 8) & 0xFF);
                dnsRequestBuffer[bufferIndex++] |= (byte)((UInt16)flags & 0xFF);
                /* Query Count */
                UInt16 queryCount = 1;
                dnsRequestBuffer[bufferIndex++] = (byte)((queryCount >> 8) & 0xFF);
                dnsRequestBuffer[bufferIndex++] = (byte)(queryCount & 0xFF);
                /* Answer Count */
                // skip bytes 6-7
                bufferIndex += 2;
                /* Authority Record Count */
                // skip bytes 8-9
                bufferIndex += 2;
                /* Additional Information Count */
                // skip bytes 10-11
                bufferIndex += 2;

                // create dns question (query)
                // Query Name
                Int32 namePosition = 0;
                while (true)
                {
                    Int32 labelLength = name.IndexOf('.', namePosition) - namePosition;
                    if (labelLength < 0)
                    {
                        bufferIndex++;
                        break;
                    }

                    dnsRequestBuffer[bufferIndex++] = (byte)labelLength;
                    Int32 labelLengthVerify = System.Text.Encoding.UTF8.GetBytes(name, namePosition, labelLength, dnsRequestBuffer, bufferIndex);
                    // if the label was not decoded as 8-bit characters, throw an exception; international punycode-encoded domains are not supported.
                    if (labelLengthVerify != labelLength)
                    {
                        throw new ArgumentException();
                    }

                    namePosition += labelLength + 1;
                    bufferIndex  += labelLength;
                }
                // Query Type
                dnsRequestBuffer[bufferIndex++] = (byte)((((UInt16)recordType) >> 8) & 0xFF);
                dnsRequestBuffer[bufferIndex++] = (byte)(((UInt16)recordType) & 0xFF);
                // Query Class
                UInt16 queryClass = DNS_RECORD_CLASS_INTERNET;
                dnsRequestBuffer[bufferIndex++] = (byte)((queryClass >> 8) & 0xFF);
                dnsRequestBuffer[bufferIndex++] = (byte)(queryClass & 0xFF);

                /* NOTE: this implementation queries the primary DNS address */
                // send DNS request
                socket.SendTo(dnsRequestBuffer, 0, bufferIndex, 0, timeoutInMachineTicks, dnsServerIPAddress, DNS_SERVER_PORT);

                // wait for DNS response
                bool success = RetrieveDnsResponse(socket, transactionID, out dnsResponse, timeoutInMachineTicks);

                if (success)
                {
                    return(true);
                }
            }
            finally
            {
                // close the reserved socket
                _ipv4Layer.CloseSocket(socketHandle);
            }

            return(false);  /* could not retrieve DNS response */
        }
Example #3
0
        public static int accept(int handle)
        {
            if (!_isInitialized)
            {
                Initialize();
            }

            Socket socket = _ipv4Layer.GetSocket(handle).Accept();

            if (socket != null)
            {
                return(socket.Handle);
            }
            else
            {
                return(-1);
            }
        }