Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
MyNetDnsRequest.cpp
00001 // MyNetDnsRequest.cpp 2012/4/19 00002 #include "mbed.h" 00003 #include "MyNetDnsRequest.h" 00004 #include "UDPSocket.h" 00005 #include <string> 00006 #include "dnsname.h" 00007 #include "W5200NetIf.h" 00008 //#define __DEBUG 00009 #include "dbg/dbg.h" 00010 00011 #ifdef __DEBUG 00012 #define DBG2(...) do{ DebugStream::debug("%p %d %s ", this,__LINE__,__PRETTY_FUNCTION__); DebugStream::debug(__VA_ARGS__); } while(0); 00013 #else 00014 #define DBG2(...) while(0); 00015 #endif //__DEBUG 00016 00017 //#define DEBUG 00018 00019 #ifdef DEBUG 00020 #include "Utils.h" 00021 #define PRINT_FUNC() printf("%p %d:%s\n", this,__LINE__,__PRETTY_FUNCTION__) 00022 #else //DEBUG 00023 #define PRINT_FUNC() 00024 #endif //DEBUG 00025 00026 00027 MyNetDnsRequest::MyNetDnsRequest(const char* hostname) : NetDnsRequest(hostname), 00028 m_state(MYNETDNS_START), m_cbFired(false), m_closing(false), m_udp(NULL) { 00029 PRINT_FUNC(); 00030 } 00031 00032 MyNetDnsRequest::MyNetDnsRequest(Host* pHost) : NetDnsRequest(pHost), 00033 m_state(MYNETDNS_START), m_cbFired(false), m_closing(false), m_udp(NULL) { 00034 PRINT_FUNC(); 00035 } 00036 00037 MyNetDnsRequest::~MyNetDnsRequest() { 00038 PRINT_FUNC(); 00039 if (m_udp) { 00040 delete m_udp; 00041 } 00042 } 00043 00044 void MyNetDnsRequest::callback(UDPSocketEvent e) 00045 { 00046 PRINT_FUNC(); 00047 DBG2("m_id[]=%02x:%02x\n", m_id[0], m_id[1]); 00048 uint8_t buf[512]; 00049 Host host; 00050 int len = m_udp->recvfrom((char*)buf, sizeof(buf), &host); 00051 if (memcmp(buf+0, m_id, 2) != 0) { //verify 00052 return; 00053 } 00054 int rcode = response(buf, len); 00055 if (rcode == 0) { 00056 m_state = MYNETDNS_OK; 00057 } else { 00058 m_state = MYNETDNS_NOTFOUND; 00059 } 00060 } 00061 00062 int MyNetDnsRequest::response(uint8_t buf[], int size) { 00063 PRINT_FUNC(); 00064 #ifdef DEBUG 00065 printHex(buf, size); 00066 #endif //DEBUG 00067 int rcode = buf[3] & 0x0f; 00068 if (rcode != 0) { 00069 return rcode; 00070 } 00071 int qdcount = buf[4]<<8|buf[5]; 00072 int ancount = buf[6]<<8|buf[7]; 00073 int pos = 12; 00074 while(qdcount-- > 0) { 00075 dnsname qname(buf); 00076 pos = qname.decode(pos); // qname 00077 pos += 4; // qtype qclass 00078 } 00079 while(ancount-- > 0) { 00080 dnsname name(buf); 00081 pos = name.decode(pos); // name 00082 int type = buf[pos]<<8|buf[pos+1]; 00083 pos += 8; // type class TTL 00084 int rdlength = buf[pos]<<8|buf[pos+1]; pos += 2; 00085 int rdata_pos = pos; 00086 pos += rdlength; 00087 if (type == 1) { // A record 00088 m_ip = IpAddr(buf[rdata_pos],buf[rdata_pos+1],buf[rdata_pos+2],buf[rdata_pos+3]); 00089 } 00090 #ifdef DEBUG 00091 printf("%s", name.str.c_str()); 00092 if (type == 1) { 00093 printf(" A %d.%d.%d.%d\n", 00094 buf[rdata_pos],buf[rdata_pos+1],buf[rdata_pos+2],buf[rdata_pos+3]); 00095 } else if (type == 5) { 00096 dnsname rdname(buf); 00097 rdname.decode(rdata_pos); 00098 printf(" CNAME %s\n", rdname.str.c_str()); 00099 } else { 00100 printf(" TYPE:%d", type); 00101 printfBytes(" RDATA:", &buf[rdata_pos], rdlength); 00102 } 00103 #endif //DEBUG 00104 } 00105 return rcode; 00106 } 00107 00108 int MyNetDnsRequest::query(uint8_t buf[], int size, const char* hostname) { 00109 PRINT_FUNC(); 00110 const uint8_t header[] = { 00111 0x00,0x00,0x01,0x00, // id=0x0000 QR=0 rd=1 opcode=0 rcode=0 00112 0x00,0x01,0x00,0x00, // qdcount=1 ancount=0 00113 0x00,0x00,0x00,0x00};// nscount=0 arcount=0 00114 const uint8_t tail[] = {0x00,0x01,0x00,0x01}; // qtype=A qclass=IN 00115 memcpy(buf, header, sizeof(header)); 00116 int t = clock(); 00117 m_id[0] = t>>8; 00118 m_id[1] = t; 00119 memcpy(buf, m_id, 2); 00120 dnsname qname(buf); 00121 int pos = qname.encode(sizeof(header), (char*)hostname); 00122 memcpy(buf+pos, tail, sizeof(tail)); 00123 pos += sizeof(tail); 00124 return pos; 00125 } 00126 00127 void MyNetDnsRequest::resolve(const char* hostname) { 00128 PRINT_FUNC(); 00129 if (m_udp == NULL) { 00130 m_udp = new UDPSocket; 00131 } 00132 m_udp->setOnEvent(this, &MyNetDnsRequest::callback); 00133 Host local(IpAddr(0,0,0,0), 1024 + rand()&0x7fff); 00134 IpAddr dns(8,8,8,8); 00135 NetIf* pIf = Net::getDefaultIf(); 00136 if (pIf) { 00137 dns = ((W5200NetIf*)pIf)->m_dns; 00138 } 00139 Host server(dns, 53); // DNS 00140 m_udp->bind(local); 00141 uint8_t buf[256]; 00142 int size = query(buf, sizeof(buf), hostname); 00143 #ifdef DEBUG 00144 printf("hostname:[%s]\n", hostname); 00145 printHex(buf, size); 00146 #endif 00147 m_udp->sendto((char*)buf, size, &server); 00148 m_interval.reset(); 00149 m_interval.start(); 00150 } 00151 00152 void MyNetDnsRequest::poll() { 00153 PRINT_FUNC(); 00154 #ifdef DEBUG 00155 printf("%p m_state: %d, m_udp: %p\n", this, m_state, m_udp); 00156 wait_ms(400); 00157 #endif //DEBUG 00158 switch(m_state) { 00159 case MYNETDNS_START: 00160 m_retry = 0; 00161 resolve(m_hostname); 00162 m_state = MYNETDNS_PROCESSING; 00163 break; 00164 case MYNETDNS_PROCESSING: 00165 break; 00166 case MYNETDNS_NOTFOUND: 00167 onReply(NETDNS_FOUND); 00168 break; 00169 case MYNETDNS_ERROR: 00170 onReply(NETDNS_ERROR); 00171 break; 00172 case MYNETDNS_OK: 00173 DBG2("m_retry=%d, m_interval=%d\n", m_retry, m_interval.read_ms()); 00174 onReply(NETDNS_FOUND); 00175 break; 00176 } 00177 if (m_interval.read_ms() > 1000) { 00178 m_interval.stop(); 00179 DBG2("timeout m_retry=%d\n", m_retry); 00180 if (++m_retry > 1) { 00181 m_state = MYNETDNS_ERROR; 00182 } else { 00183 resolve(m_hostname); 00184 m_state = MYNETDNS_PROCESSING; 00185 } 00186 } 00187 if(m_closing && (m_state!=MYNETDNS_PROCESSING)) { 00188 NetDnsRequest::close(); 00189 } 00190 } 00191 00192 void MyNetDnsRequest::close() { 00193 PRINT_FUNC(); 00194 if(m_state != MYNETDNS_PROCESSING) { 00195 NetDnsRequest::close(); 00196 } else { 00197 m_closing = true; 00198 } 00199 }
Generated on Tue Jul 12 2022 19:58:52 by
1.7.2