Write the MX record acquisition component

Source: Internet
Author: User
Tags 0xc0 domain name server mail exchange mx record to domain

I. Application of MX record
Email is the most successful application on the Internet so far. Imagine if a web contact does not have its own email address, it will not be called "Internet users ". The number of email-related applications on the Internet has also increased. When writing a network application, we often need to embed the email application into our own application. This type of application uses third-party email-related components to complete email writing, sending, receiving, and decoding. In the process of sending an email, the NT platform generally uses the CDO component provided by the NT System. Such components are often implemented by services on the local machine or a specific SMTP server, it is not possible to ensure whether a letter arrives or not, and the possibility of losing the letter is also caused by the delay of relay. Therefore, many experts use Direct Email Delivery to the target email server to send emails. The key to achieving this function is three points:
1. Mime encoding of the email
2. SMTP session control
3. Obtain the MX record.
I understand that there are many articles on the Internet on the first and second points, and there are many reference codes, however, it is seldom discussed in detail how to locate the target email receiving server-obtain the MX record of the mailbox domain name. Search for related components to obtain the server component of an ASP environment (charged ), no detailed source code is available for reference. Based on this, I learned the Java language to write a similar component to help you understand the details.

Ii. DNS record classification and principles
We know that the Domain Name System is the cornerstone of the Internet. It is the credit of the domain name system to access the websites we are interested in through friendly names like Yahoo.com. When you click www.yahoo.com in the browser, your browser will ask the DNS server if you do not know where to retrieve the webpage directed to by this domain name ), the domain name resolution server looks for its own record library to check whether the requested domain name record exists. If yes, it will return directly. If no record exists, it will send a request to the higher-level domain name resolution server (forwarding the request ), until the resolution record of this domain name is finally found and returned to your browser, telling your browser which IP address to obtain the relevant content. This process of converting an Internet domain name to a corresponding IP address is called resolution.
Domain name records include a variety of common A (Address) records, alias (cname) records, and MX (mail exchange) records. A record is a record of a domain name corresponding to an IP address. The IP address corresponding to www.yahoo.com just mentioned is the Query Process of a record. The alias record is mainly used to replace the domain name to be resolved with an existing a record. For example, the alias value of www.yahoo.akadns.net will be obtained when www.yahoo.com is queried, And the IP address 64.58.76.177 will be obtained after www.yaho. Mail exchange records are used for mail delivery. For example, if you need to send an email to the abc@yahoo.com, then generally your ISP's SMTP server (technically become a mail proxy, that is, instead of the user's direct delivery of mail) the SMTP server queries the MX record of Yahoo.com to see which server the mail should be sent to. If the MX record of Yahoo.com is found, then, your ISP's SMTP server will establish a TCP connection to the server specified by the MX record, and send your email to the target server to complete the email delivery process.
If you can obtain the MX record of a domain name, that is, you can directly deliver it to the target mailbox. To obtain this MX record, you must be able to correctly send your request to the DNS of the Domain Name Server, at the same time, you must be able to understand the information returned by DNS and read the content you need. The details here are relatively complex. Here is a brief introduction:
The UDP packet sent by the customer to port 53 of the DNS, and then the server queries (which may be forwarded or called recursive query in the middle) and sends back the record required by the client, which is also the UDP packet. The general format of such packets is:
| 2-byte mark | 2-byte mark | 2-byte number of problems | 2-byte number of resource records | 2-byte number of authorized resource records | 2-byte number of additional resource records | domain name to be queried (unfixed length) | response resource record for the request (the length is not fixed) | authorization Resource Record (the length is not fixed) | additional record information (the length is not fixed)
Id fieldIt is used to indicate the number of the message, which is generally specified by the customer. This identifier is carried when the DNS server returns the information to tell the client which request to answer.
The 16-bit flag field is divided into eight sub-fields, from left to right (high to low:
Qr 1 bit: 0 query packet 1 response packet
Opcode 4 bit: usually 0, indicating standard query, 1 reverse query, 2 server status query
Aa 1 bit: Used for the server to return a message, indicating whether it is an authorized answer
TC 1 bit: due to the length limit of UDP, the content after 512 bytes is often truncated. This bit indicates whether the content can be truncated.
RD 1 bit: this parameter is used to set in the query message and is returned by the server response message. This bit indicates that the server must process this query. If this bit is 0 and the number of authorized answers returned by the server is 0, the server must return a list of other servers that can answer this query.
RA 1 bit: if the server supports recursion, the server sets this bit in the Response Message.
The subsequent 3bit must be 0
RCODE 4 bit: the final return code, 0 error-free, 3 name error, that is, there is no record of the domain name to be queried on the server, which is generally used to return from the final authorization name server.
Query ProblemsThe query class consists of the Query Class of the query name query type. The query name consists of a sequence of multiple identifiers. the first byte of each identifier indicates the length of the identifier, and the end byte 0 indicates the end of the name. For example, cn.yahoo.com is composed of 2 C n 5 y a h o 3 c o m 0. If this domain name is still used later, it is generally followed by the compression format, then the first byte is not the length, but a byte with the highest bit of 1, usually 0xc0, because there will be no identifiers with a length greater than 64 (due to Domain Name Regulations ). After the mark byte in the compressed format, it is the offset value of the original identifier of the domain name. The query type is 2 bytes. 1 indicates a record query 5 indicates cname record query 15 indicates MX record query. Indicates whether it is Internet data.
Response MessageThe response record in consists of the domain name (unfixed length) type (2 bytes) Class (2 bytes) survival time (4 bytes, seconds) Resource Data Length (2 bytes) resource data (not fixed ). The domain name format is the same as the query domain name format. The Interpretation of types and classes is the same as that of query problems. Resource data varies depending on the record type.
If we send a UDP greeting to the server with the domain name resolution function according to the above format, we can receive the response sent back by the DNS server, so that we can get the desired record. Therefore, the main difficulty lies in the Construction of packets and the analysis of response packets.

Iii. Write the MX record component
Start VJ. You must create a DLL project and modify the name of the main class as needed. If everything is correct, you will get a DLL with the domain name MX record query function. For specific code, see the source code analysis. The key is to construct the query message and the Response Message After explanation based on your query questions. The network connection mode of the same server is UDP.
For convenience of debugging, I added a main function entry, so that we can call jvew in the DOS window to view the results of the domain name MX record, and also facilitate debugging.

Iv. application example and Expansion
With such a query component, you can directly obtain the MX record of the domain name, which can help us get the mail delivery method. At the same time, we also know the location of the email receiving server for this domain name. By testing different user names, we can also obtain the mailbox usernames that exist in the post office of this domain name. You may wonder how your mailbox is obtained by others. Some email Searchers may query MX records to get the address of the email server, and then use a special user name generation algorithm to get different user names, one by one test to get the mailbox. By adding this function to your application, you can directly send emails to the target server without relying on the components on the server. You can even write an email forwarding server to serve your users (generally, the sending server is not open to the outside world ).

V. source code and Analysis
Import java.net .*;
Import java. Io .*;
Import java. util. stringtokenizer;
// Import java. util .*;

/**
* This class is designed to be packaged with a com DLL output format.
* The class has no standard entry points, other than the constructor.
* Public methods will be exposed as methods on the default COM interface.
* @ Com. Register (CLSID = 20ae856f-e2f8-488e-b41e-753e6bebd375, typelib = 10911559-afab-479e-8572-9a0b1f06ccda)
*/
Public class mxdns
{
Private string thednsserver; // the address of the current DNS Server
Private datagrampacket outpk; // send data packets
Private datagrampacket inpk; // receives data packets
Private datagramsocket udpsocket; // UDP taozi
Private inetaddress dnsserverip; // ip address of the domain name resolution Server
Private int position, ID, length; // variable required for analyzing DNS records
Private string dmname; // The queried domain name.
Private mxrec mxrecs; // DNS response record
Private Static int dns_port = 53; // The DNS Service port
Private byte [] pkdata = new byte [512]; // get a 512-byte Packet

Public mxdns () // Constructor
{
Id = (New java. util. Date (). getseconds () * 60 * (New java. util. Random (). nextint ();
// Obtain the unique ID
}
// The following are the exposed attributes and methods.

Public void setdnsserver (string dnsserver)
{
Thednsserver = dnsserver; // set the name or IP address of the current DNS server.
}

Public String getmxrecords (string DM) // obtain an array of all dnsmx records
{
Return (getmxrecords (DM, thednsserver ));
}

Public String getmxrecords (string DM, string dnsserver)
{
Try
{
Dnsserverip = inetaddress. getbyname (dnsserver );
// Obtain the inetaddress of the DNS server
Outpk = new datagrampacket (pkdata, pkdata. length, dnsserverip, dns_port );
// Outbound Datagram
Udpsocket = new datagramsocket (dns_port); // data packet Port
Makednsquery (ID, DM); // generates Query Packets
Udpsocket. Send (outpk); // send data packets
Inpk = new datagrampacket (pkdata, pkdata. Length );
Udpsocket. Receive (inpk); // receives the returned Response Message
Pkdata = inpk. getdata (); // obtain the link
Length = pkdata. length;
}
Catch (unknownhostexception UE)
{
}
Catch (socketexception SE)
{
}
Catch (ioexception IOE)
{
}
Return (getresponse (); // analyze the returned data packets and obtain the record results.
}

Public void makednsquery (int id, string DM)
{// Generate query data in the pkdate byte array
For (INT I = 0; I <512; I ++)
{
Pkdata [I] = 0;
}

Pkdata [0] = (byte) (ID> 8 );
Pkdata [1] = (byte) (ID & 0xff); // the query identifier is 2 bytes.
Pkdata [2] = (byte) 1; // qrbit bit is 1, indicating the query Packet
Pkdata [3] = (byte) 0;
Pkdata [4] = (byte) 0;
Pkdata [5] = (byte) 1; // 1 problem
Pkdata [6] = (byte) 0; // The number of resource records, authorized resource records, and additional resource records are all 0, because they are Query Packets
Pkdata [7] = (byte) 0;
Pkdata [8] = (byte) 0;
Pkdata [9] = (byte) 0;
Pkdata [10] = (byte) 0;
Pkdata [11] = (byte) 0;
Stringtokenizer ST = new stringtokenizer (DM, "."); // separate domain names
String label;
Position = 12; // query generated starting from 12th bytes
While (St. hasmoretokens ())
{
Label = ST. nexttoken ();
Pkdata [position ++] = (byte) (Label. Length () & 0xff); // convert to byte
Byte [] B = label. getbytes ();
For (Int J = 0; j {
Pkdata [position ++] = B [J];
}
}
Pkdata [position ++] = (byte) 0; // end the domain name with 0
Pkdata [position ++] = (byte) 0;
Pkdata [position ++] = (byte) 15; // query type 15 indicates MX record Query
Pkdata [position ++] = (byte) 0;
Pkdata [position ++] = (byte) 1; // query Internet data records
} // Query constructed

Private string getresponse () // get feedback
{
String temp = "";
Int qcount = (pkdata [4] & 0xff) <8) | (pkdata [5] & 0xff); // obtain the number of problems
If (qcount <0)
{Return ("") ;}// the number of problems is less than 0, and an empty string is returned.
Int acount = (pkdata [6] & 0xff) <8) | (pkdata [7] & 0xff); // obtain the number of response questions
If (acount <0)
{Return ("") ;}// the number of problems is less than 0, and an empty string is returned.
Position = 12; // start position of the query question Section
For (INT I = 0; I {
Dmname = "";
Position = proc (position );
Position + = 4; // adds the query type and Query Class of the byte length.
}
For (INT I = 0; I{
Dmname = "";
Position = proc (position );
Position + = 10; // type 2 bytes, Class 2 bytes, survival time 4 bytes, resource length 2 bytes, total 10 bytes
Int Pref = (pkdata [position ++] <8) | (pkdata [position ++] & 0xff); // obtain the switch base of the MX record
Dmname = "";
Position = proc (position); // obtain the switch value, which is generally a standard domain name.
If (temp. Revoke signorecase (""))
{Temp = "" + Pref + "" + dmname;} // return data
Else
{Temp = temp + "," + Pref + "" + dmname ;}
}
Return (temp );
}
Private int proc (INT position)
{// This process searches for domain names from the pkdata byte array
Int Len = (pkdata [position ++] & 0xff); // gets the length of the identifier to be processed
If (LEN = 0) // if no other identifier exists, end and return
{Return position ;}
Int offset; // offset
Do {
If (LEN & 0xc0) = 0xc0) // compression format?
{
If (position> = length) // exceeds the package size, the offset is obviously incorrect.
{Return (-1 );}
Offset = (LEN & 0x3f) <8) | (pkdata [position ++] & 0xff); // get the offset of the compressed source identifier
Proc (offset); // recursive call to obtain the name before compression
Return (position );
}
Else // non-compressed format
{
If (Position + Len)> length) // exceeds the length
{Return (-1 );}
Dmname + = new string (pkdata, position, Len); // obtain each part of the domain name identifier
Position + = Len;
}
If (position> length)
{Return (-1 );}
Len = pkdata [position ++] & 0xff; // is it the end of 0?
If (Len! = 0)
{
Dmname + = "."; // Add. to form a complete Domain Name
}
} While (Len! = 0 );
Return (position );
}
Public static void main (string ARGs []) throws exception
{
Mxdns MX = new mxdns ();
String S = mx. getmxrecords ("Sina.com", "202.96.128.68 ");
System. Out. println (s );
Int K = system. In. Read ();
}
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.