Ryo Iizuka / libMiMic

Dependents:   MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more

Files at this revision

API Documentation at this revision

Comitter:
nyatla
Date:
Tue Oct 28 12:38:10 2014 +0000
Parent:
101:5022828ace54
Child:
103:853ddf4a1b81
Commit message:
bugfix; AAAA/NSEC???????

Changed in this revision

core/net/mdns/NyLPC_cMDnsServer.c Show annotated file Show diff for this revision Revisions of this file
--- a/core/net/mdns/NyLPC_cMDnsServer.c	Mon Oct 27 11:21:29 2014 +0000
+++ b/core/net/mdns/NyLPC_cMDnsServer.c	Tue Oct 28 12:38:10 2014 +0000
@@ -76,6 +76,8 @@
 #define NyLPC_TDnsQuestion_QTYPR_MX     15
 #define NyLPC_TDnsQuestion_QTYPR_TXT    16
 #define NyLPC_TDnsQuestion_QTYPR_ANY    255
+#define NyLPC_TDnsQuestion_QTYPR_AAAA   28
+#define NyLPC_TDnsQuestion_QTYPR_NSEC   47
 #define NyLPC_TDnsQuestion_QCLASS_IN    1
 #define NyLPC_TDnsQuestion_QCLASS_CH    3
 #define NyLPC_TDnsQuestion_QCLASS_HS    4
@@ -425,26 +427,31 @@
     b++;
     return b-buf;
 }
-
 /**
- * ResourceHeaderのライタ
- *//*
-static NyLPC_TInt16 writeResourceHeader(char* i_packet,NyLPC_TInt16 i_spos,NyLPC_TInt16 buflen,const char* i_name,NyLPC_TUInt16 i_type,NyLPC_TUInt16 i_class)
+ * query文字列をパケットに追記します。
+ * @return 出力したバイト数
+ */
+static NyLPC_TInt16 query2label(char* i_packet,NyLPC_TInt16 i_spos,NyLPC_TInt16 obuflen,const NyLPC_TChar* i_query)
 {
-    NyLPC_TInt16 s;
-    NyLPC_TInt16 l=1+(NyLPC_TInt16)strlen(i_name)+1+5+1;
-    if(buflen<i_spos+l+4+4){
-        return 0;
+    const char* n;
+    NyLPC_TInt16 s=0;
+    for(;;){
+        n=getExtractNamePos(i_query,i_query+s);
+        if(n==NULL){
+            *(i_packet+i_spos+s)=0;
+            s++;
+            break;
+        }else{
+            memcpy(i_packet+i_spos+s,i_query+s,((NyLPC_TUInt8)*n)+1);
+            s+=((NyLPC_TUInt8)*n)+1;
+            if(obuflen<i_spos+s+1+4+4){
+                return 0;
+            }
+        }
     }
-    s=str2label(i_packet+i_spos,i_name)-1;
-    s+=str2label(i_packet+i_spos+s,"local");
-    //レコード圧縮
-    l=compressName(i_packet,i_spos,s);
-    (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(i_type);
-    (*(NyLPC_TUInt16*)(i_packet+l+2))=NyLPC_HTONS(i_class);
-    (*(NyLPC_TUInt32*)(i_packet+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
-    return l+2+2+4;
-}*/
+    return s;
+}
+
 
 inline static NyLPC_TInt16 writeSrvResourceHeader(char* i_packet,NyLPC_TInt16 i_spos,NyLPC_TInt16 buflen,const struct NyLPC_TDnsRecord* i_recode,int i_sid,NyLPC_TUInt16 i_type,NyLPC_TUInt16 i_class)
 {
@@ -513,30 +520,20 @@
     (*(NyLPC_TUInt32*)(i_packet+l+2))=ip->v;
     return l+6;
 }
+
 /**
  * AレコードクエリからAレコードレスポンスを書きだす。
  */
-inline static NyLPC_TInt16 writeARecordByQuery(char* i_packet,NyLPC_TInt16 i_spos,NyLPC_TInt16 obuflen,const NyLPC_TChar* i_query,const struct NyLPC_TIPv4Addr* ip)
+static NyLPC_TInt16 writeARecordByQuery(char* i_packet,NyLPC_TInt16 i_spos,NyLPC_TInt16 obuflen,const NyLPC_TChar* i_query,const struct NyLPC_TIPv4Addr* ip)
 {
-    const char* n;
     NyLPC_TInt16 s;
     //AnswerはAレコードのみ
     NyLPC_TInt16 l;
-    s=0;
-    for(;;){
-        n=getExtractNamePos(i_query,i_query+s);
-        if(n==NULL){
-            *(i_packet+i_spos+s)=0;
-            s++;
-            break;
-        }else{
-            memcpy(i_packet+i_spos+s,i_query+s,((NyLPC_TUInt8)*n)+1);
-            s+=((NyLPC_TUInt8)*n)+1;
-            if(obuflen<i_spos+s+1+4+4){
-                return 0;
-            }
-        }
+    s=query2label(i_packet,i_spos,obuflen,i_query);
+    if(s==0){
+        return 0;
     }
+
     //レコード圧縮
     l=compressName(i_packet,i_spos,s);
     (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_A);
@@ -554,6 +551,105 @@
     return l+6;
 }
 
+/**
+ * AレコードクエリからAレコードレスポンスを書きだす。
+ */
+static NyLPC_TInt16 writeAAAARecordByQuery(char* i_packet,NyLPC_TInt16 i_spos,NyLPC_TInt16 obuflen,const NyLPC_TChar* i_query,const struct NyLPC_TIPv4Addr* ip)
+{
+    NyLPC_TInt16 s;
+    //AnswerはAレコードのみ
+    NyLPC_TInt16 l;
+    s=query2label(i_packet,i_spos,obuflen,i_query);
+    if(s==0){
+        return 0;
+    }
+
+    //レコード圧縮
+    l=compressName(i_packet,i_spos,s);
+    (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_AAAA);
+    (*(NyLPC_TUInt16*)(i_packet+l+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN|NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH);
+    (*(NyLPC_TUInt32*)(i_packet+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
+    l+=2+2+4;
+    //A record header
+    if(obuflen<l+2+16){
+        return 0;
+    }
+    //AAAAレコードを書く
+    //IPADDR
+    (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(16);
+    memset(i_packet+l+2,0,10);
+    (*(NyLPC_TUInt16*)(i_packet+l+2+10))=0xffff;
+    (*(NyLPC_TUInt32*)(i_packet+l+2+12))=ip->v;
+    return l+2+16;
+}
+/**
+ * NSECレコードレスポンスを書きだす。
+ * IPv6わからんし。
+ */
+static NyLPC_TInt16 writeNSECRecord(char* i_packet,NyLPC_TInt16 i_spos,NyLPC_TInt16 obuflen,const NyLPC_TChar* i_name)
+{
+    NyLPC_TInt16 s;
+    //AnswerはAレコードのみ
+    NyLPC_TInt16 l=1+(NyLPC_TInt16)strlen(i_name)+1+5+1;
+    if(obuflen<i_spos+l+4+4){
+        return 0;
+    }    
+    s=str2label(i_packet+i_spos,i_name)-1;
+    s+=str2label(i_packet+i_spos+s,"local");
+
+    //レコード圧縮
+    l=i_spos+s;//compressName(i_packet,i_spos,s);
+    (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_NSEC);
+    (*(NyLPC_TUInt16*)(i_packet+l+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN|NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH);
+    (*(NyLPC_TUInt32*)(i_packet+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
+    l+=2+2+4;
+    //A record header
+    if(obuflen<l+2+2+6){
+        return 0;
+    }
+    //NSECレコードを書く
+    *((NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(2+6);
+    l+=2;
+    *(i_packet+l)=0xc0;
+    *(i_packet+l+1)=(NyLPC_TUInt8)i_spos;
+    l+=2;
+    memcpy(i_packet+l,"\x00\x04\x00\x00\x00\x08",6);
+    return l+6;
+}
+/**
+ * NSECレコードレスポンスを書きだす。
+ * IPv6わからんし。
+ */
+static NyLPC_TInt16 writeNSECRecordByQuery(char* i_packet,NyLPC_TInt16 i_spos,NyLPC_TInt16 obuflen,const NyLPC_TChar* i_query)
+{
+    NyLPC_TInt16 s;
+    //AnswerはAレコードのみ
+    NyLPC_TInt16 l;
+    s=query2label(i_packet,i_spos,obuflen,i_query);
+    if(s==0){
+        return 0;
+    }
+
+    //レコード圧縮
+    l=i_spos+s;
+//    l=compressName(i_packet,i_spos,s);
+    (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_NSEC);
+    (*(NyLPC_TUInt16*)(i_packet+l+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN|NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH);
+    (*(NyLPC_TUInt32*)(i_packet+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
+    l+=2+2+4;
+    //A record header
+    if(obuflen<l+2+2+6){
+        return 0;
+    }
+    //NSECレコードを書く
+    *((NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(2+6);
+    l+=2;
+    *(i_packet+l)=0xc0;
+    *(i_packet+l+1)=(NyLPC_TUInt8)i_spos;
+    l+=2;
+    memcpy(i_packet+l,"\x00\x04\x00\x00\x00\x08",6);
+    return l+6;
+}
 static NyLPC_TInt16 writeSdPtrRecord(const struct NyLPC_TDnsQuestion* i_question,const struct NyLPC_TMDnsServiceRecord* i_srvlec,char* i_packet,NyLPC_TInt16 i_spos,NyLPC_TInt16 obuflen)
 {
     NyLPC_TInt16 l,s;
@@ -680,15 +776,17 @@
         if(obuf==NULL){
             return;
         }
-        l=setResponseHeader(obuf,NULL,1,0,3);
+        l=setResponseHeader(obuf,NULL,1,0,4);
         l=writePtrRecord(i_inst->_ref_record,i2,obuf,l,obuflen);
         if(l<=0){
             NyLPC_OnErrorGoto(ERROR);
         }
+        //SRV
         l=writeSRVRecord(i_inst,i2,obuf,l,obuflen);
         if(l<=0){
             NyLPC_OnErrorGoto(ERROR);
         }
+        //TXT
         l=writeTXTRecord(i_inst,i2,obuf,l,obuflen);
         if(l<=0){
             NyLPC_OnErrorGoto(ERROR);
@@ -698,6 +796,11 @@
         if(l<=0){
             NyLPC_OnErrorGoto(ERROR);
         }
+        //NSEC
+        l=writeNSECRecord(obuf,l,obuflen,i_inst->_ref_record->a);
+        if(l<=0){
+            NyLPC_OnErrorGoto(ERROR);
+        }          
         if(!NyLPC_cUdpSocket_psend(&(i_inst->_super),&MDNS_MCAST_IPADDR,MDNS_MCAST_PORT,obuf,l)){
             NyLPC_OnErrorGoto(ERROR);
         }
@@ -744,6 +847,34 @@
         if(l<=0){
             NyLPC_OnErrorGoto(ERROR);
         }
+        //NSEC
+        l=writeNSECRecord(obuf,l,obuflen,i_inst->_ref_record->a);
+        if(l<=0){
+            NyLPC_OnErrorGoto(ERROR);
+        }      
+        break;
+    case NyLPC_TDnsQuestion_QTYPR_AAAA:
+        //自分宛?(name.local)
+        if(!NyLPC_TDnsQuestion_isEqualName(q,i_inst->_ref_record->a,"")){
+            goto DROP;
+        }
+        //Bufferの取得
+        obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
+        if(obuf==NULL){
+            goto DROP;
+        }
+        //Headerのコピー
+        l=setResponseHeader(obuf,i_dns_header,1,0,1);        
+        //AAAAレコード
+        l=writeAAAARecordByQuery(obuf,l,obuflen,q->buf+q->qname_pos,&(i_inst->_super.uip_udp_conn.lipaddr));
+        if(l<=0){
+            NyLPC_OnErrorGoto(ERROR);
+        }
+        //NSEC
+        l=writeNSECRecordByQuery(obuf,l,obuflen,q->buf+q->qname_pos);
+        if(l<=0){
+            NyLPC_OnErrorGoto(ERROR);
+        }
         break;
     case NyLPC_TDnsQuestion_QTYPR_A:
         //自分宛?(name.local)
@@ -756,12 +887,16 @@
             goto DROP;
         }
         //Headerのコピー
-        l=setResponseHeader(obuf,i_dns_header,1,0,0);
+        l=setResponseHeader(obuf,i_dns_header,1,0,1);
         //Aレコードのみ
         l=writeARecordByQuery(obuf,l,obuflen,q->buf+q->qname_pos,&(i_inst->_super.uip_udp_conn.lipaddr));
         if(l<=0){
             NyLPC_OnErrorGoto(ERROR);
         }
+        l=writeNSECRecordByQuery(obuf,l,obuflen,q->buf+q->qname_pos);
+        if(l<=0){
+            NyLPC_OnErrorGoto(ERROR);
+        }        
         break;
     case NyLPC_TDnsQuestion_QTYPR_PTR:
         //_service._dns-sd._udpかどうか
@@ -789,7 +924,7 @@
             if(obuf==NULL){
                 goto DROP;
             }
-            l=setResponseHeader(obuf,i_dns_header,1,0,3);
+            l=setResponseHeader(obuf,i_dns_header,1,0,4);
             l=writePtrRecord(i_inst->_ref_record,ptr_recode,obuf,l,obuflen);
             if(l<=0){
                 NyLPC_OnErrorGoto(ERROR);
@@ -807,6 +942,10 @@
             if(l<=0){
                 NyLPC_OnErrorGoto(ERROR);
             }
+            l=writeNSECRecord(obuf,l,obuflen,i_inst->_ref_record->a);
+            if(l<=0){
+                NyLPC_OnErrorGoto(ERROR);
+            }
         }
         break;
     case NyLPC_TDnsQuestion_QTYPR_TXT:
@@ -817,7 +956,7 @@
         }
         //Bufferの取得
         obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
-        l=setResponseHeader(obuf,i_dns_header,1,0,1);
+        l=setResponseHeader(obuf,i_dns_header,1,0,2);
         l=writeTXTRecord(i_inst,ptr_recode,obuf,l,obuflen);
         if(l<=0){
             NyLPC_OnErrorGoto(ERROR);
@@ -826,6 +965,10 @@
         if(l<=0){
             NyLPC_OnErrorGoto(ERROR);
         }
+        l=writeNSECRecord(obuf,l,obuflen,i_inst->_ref_record->a);
+        if(l<=0){
+            NyLPC_OnErrorGoto(ERROR);
+        }
         break;
     default:
         goto DROP;