This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088
Fork of libMiMic by
core/net/mdns/NyLPC_cMDnsServer.c@97:6ca5900a2d68, 2014-10-19 (annotated)
- Committer:
- nyatla
- Date:
- Sun Oct 19 08:44:52 2014 +0000
- Revision:
- 97:6ca5900a2d68
- Parent:
- 96:e6a0db86988e
- Child:
- 98:6284ce9a0476
Bugfix LPC4088 driver; Bugfix mDNS TTL;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
nyatla | 37:fc4b4fd6a649 | 1 | /********************************************************************************* |
nyatla | 37:fc4b4fd6a649 | 2 | * PROJECT: MiMic |
nyatla | 37:fc4b4fd6a649 | 3 | * -------------------------------------------------------------------------------- |
nyatla | 37:fc4b4fd6a649 | 4 | * |
nyatla | 37:fc4b4fd6a649 | 5 | * This file is part of MiMic |
nyatla | 37:fc4b4fd6a649 | 6 | * Copyright (C)2011 Ryo Iizuka |
nyatla | 37:fc4b4fd6a649 | 7 | * |
nyatla | 37:fc4b4fd6a649 | 8 | * MiMic is free software: you can redistribute it and/or modify |
nyatla | 37:fc4b4fd6a649 | 9 | * it under the terms of the GNU Lesser General Public License as published |
nyatla | 37:fc4b4fd6a649 | 10 | * by the Free Software Foundation, either version 3 of the License, or |
nyatla | 37:fc4b4fd6a649 | 11 | * (at your option) any later version. |
nyatla | 37:fc4b4fd6a649 | 12 | * |
nyatla | 37:fc4b4fd6a649 | 13 | * This program is distributed in the hope that it will be useful, |
nyatla | 37:fc4b4fd6a649 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
nyatla | 37:fc4b4fd6a649 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
nyatla | 37:fc4b4fd6a649 | 16 | * GNU General Public License for more details. |
nyatla | 37:fc4b4fd6a649 | 17 | * |
nyatla | 37:fc4b4fd6a649 | 18 | * You should have received a copy of the GNU Lesser General Public License |
nyatla | 37:fc4b4fd6a649 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
nyatla | 37:fc4b4fd6a649 | 20 | * |
nyatla | 37:fc4b4fd6a649 | 21 | * For further information please contact. |
nyatla | 37:fc4b4fd6a649 | 22 | * http://nyatla.jp/ |
nyatla | 37:fc4b4fd6a649 | 23 | * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> |
nyatla | 37:fc4b4fd6a649 | 24 | * |
nyatla | 37:fc4b4fd6a649 | 25 | *********************************************************************************/ |
nyatla | 37:fc4b4fd6a649 | 26 | #include "NyLPC_cMDnsServer.h" |
nyatla | 37:fc4b4fd6a649 | 27 | #include "NyLPC_uipService.h" |
nyatla | 37:fc4b4fd6a649 | 28 | #include "NyLPC_http.h" |
nyatla | 37:fc4b4fd6a649 | 29 | #include "NyLPC_utils.h" |
nyatla | 37:fc4b4fd6a649 | 30 | #include <stdio.h> |
nyatla | 37:fc4b4fd6a649 | 31 | #include <string.h> |
nyatla | 37:fc4b4fd6a649 | 32 | |
nyatla | 37:fc4b4fd6a649 | 33 | |
nyatla | 37:fc4b4fd6a649 | 34 | /** |
nyatla | 37:fc4b4fd6a649 | 35 | * mDNSのポート番号 |
nyatla | 37:fc4b4fd6a649 | 36 | */ |
nyatla | 37:fc4b4fd6a649 | 37 | #define MDNS_MCAST_PORT 5353 |
nyatla | 37:fc4b4fd6a649 | 38 | static const struct NyLPC_TIPv4Addr MDNS_MCAST_IPADDR=NyLPC_TIPv4Addr_pack(224,0,0,251); |
nyatla | 37:fc4b4fd6a649 | 39 | #define TIMEOUT_IN_MS 1000 |
nyatla | 96:e6a0db86988e | 40 | #define NyLPC_TcMDns_TTL (30*60) //30min |
nyatla | 37:fc4b4fd6a649 | 41 | |
nyatla | 37:fc4b4fd6a649 | 42 | |
nyatla | 37:fc4b4fd6a649 | 43 | struct NyLPC_TDnsHeader |
nyatla | 37:fc4b4fd6a649 | 44 | { |
nyatla | 37:fc4b4fd6a649 | 45 | NyLPC_TUInt16 id; |
nyatla | 37:fc4b4fd6a649 | 46 | NyLPC_TUInt16 flag; |
nyatla | 37:fc4b4fd6a649 | 47 | NyLPC_TUInt16 qd; |
nyatla | 37:fc4b4fd6a649 | 48 | NyLPC_TUInt16 an; |
nyatla | 37:fc4b4fd6a649 | 49 | NyLPC_TUInt16 ns; |
nyatla | 37:fc4b4fd6a649 | 50 | NyLPC_TUInt16 ar; |
nyatla | 37:fc4b4fd6a649 | 51 | }PACK_STRUCT_END; |
nyatla | 37:fc4b4fd6a649 | 52 | |
nyatla | 37:fc4b4fd6a649 | 53 | #define NyLPC_TDnsHeader_FLAG_MASK_QR 0x8000 |
nyatla | 37:fc4b4fd6a649 | 54 | #define NyLPC_TDnsHeader_FLAG_MASK_OPCODE 0x7800 |
nyatla | 37:fc4b4fd6a649 | 55 | #define NyLPC_TDnsHeader_FLAG_MASK_AA 0x0400 |
nyatla | 37:fc4b4fd6a649 | 56 | #define NyLPC_TDnsHeader_FLAG_MASK_TC 0x0200 |
nyatla | 37:fc4b4fd6a649 | 57 | #define NyLPC_TDnsHeader_FLAG_MASK_RD 0x0100 |
nyatla | 37:fc4b4fd6a649 | 58 | #define NyLPC_TDnsHeader_FLAG_MASK_RA 0x0080 |
nyatla | 37:fc4b4fd6a649 | 59 | #define NyLPC_TDnsHeader_FLAG_MASK_Z 0x0070 |
nyatla | 37:fc4b4fd6a649 | 60 | #define NyLPC_TDnsHeader_FLAG_MASK_RECODE 0x000F |
nyatla | 37:fc4b4fd6a649 | 61 | |
nyatla | 37:fc4b4fd6a649 | 62 | struct NyLPC_TDnsQuestion |
nyatla | 37:fc4b4fd6a649 | 63 | { |
nyatla | 37:fc4b4fd6a649 | 64 | const char* qname; |
nyatla | 37:fc4b4fd6a649 | 65 | NyLPC_TUInt16 qtype; |
nyatla | 37:fc4b4fd6a649 | 66 | NyLPC_TUInt16 qclass; |
nyatla | 37:fc4b4fd6a649 | 67 | }; |
nyatla | 37:fc4b4fd6a649 | 68 | #define NyLPC_TDnsQuestion_QTYPR_A 1 |
nyatla | 37:fc4b4fd6a649 | 69 | #define NyLPC_TDnsQuestion_QTYPR_NS 2 |
nyatla | 37:fc4b4fd6a649 | 70 | #define NyLPC_TDnsQuestion_QTYPR_CNAME 5 |
nyatla | 37:fc4b4fd6a649 | 71 | #define NyLPC_TDnsQuestion_QTYPR_SOA 6 |
nyatla | 37:fc4b4fd6a649 | 72 | #define NyLPC_TDnsQuestion_QTYPR_PTR 12 |
nyatla | 37:fc4b4fd6a649 | 73 | #define NyLPC_TDnsQuestion_QTYPR_MX 15 |
nyatla | 37:fc4b4fd6a649 | 74 | #define NyLPC_TDnsQuestion_QTYPR_TXT 16 |
nyatla | 37:fc4b4fd6a649 | 75 | #define NyLPC_TDnsQuestion_QTYPR_ANY 255 |
nyatla | 37:fc4b4fd6a649 | 76 | #define NyLPC_TDnsQuestion_QCLASS_IN 1 |
nyatla | 37:fc4b4fd6a649 | 77 | #define NyLPC_TDnsQuestion_QCLASS_CH 3 |
nyatla | 37:fc4b4fd6a649 | 78 | #define NyLPC_TDnsQuestion_QCLASS_HS 4 |
nyatla | 37:fc4b4fd6a649 | 79 | #define NyLPC_TDnsQuestion_QTYPR_SRV 33 |
nyatla | 37:fc4b4fd6a649 | 80 | |
nyatla | 37:fc4b4fd6a649 | 81 | /************************************************** |
nyatla | 37:fc4b4fd6a649 | 82 | * TLabelCache |
nyatla | 37:fc4b4fd6a649 | 83 | **************************************************/ |
nyatla | 37:fc4b4fd6a649 | 84 | |
nyatla | 37:fc4b4fd6a649 | 85 | struct TLabelCache |
nyatla | 37:fc4b4fd6a649 | 86 | { |
nyatla | 37:fc4b4fd6a649 | 87 | NyLPC_TUInt16 idx; |
nyatla | 37:fc4b4fd6a649 | 88 | const char* str; |
nyatla | 37:fc4b4fd6a649 | 89 | }; |
nyatla | 37:fc4b4fd6a649 | 90 | static void TLabelCache_reset(struct TLabelCache* i_struct) |
nyatla | 37:fc4b4fd6a649 | 91 | { |
nyatla | 37:fc4b4fd6a649 | 92 | i_struct->idx=0; |
nyatla | 37:fc4b4fd6a649 | 93 | i_struct->str=NULL; |
nyatla | 37:fc4b4fd6a649 | 94 | } |
nyatla | 37:fc4b4fd6a649 | 95 | static NyLPC_TInt16 TLabelCache_compress(struct TLabelCache* i_struct,NyLPC_TChar* i_src) |
nyatla | 37:fc4b4fd6a649 | 96 | { |
nyatla | 37:fc4b4fd6a649 | 97 | NyLPC_TInt16 s; |
nyatla | 37:fc4b4fd6a649 | 98 | NyLPC_TInt16 k; |
nyatla | 37:fc4b4fd6a649 | 99 | const NyLPC_TChar* q; |
nyatla | 37:fc4b4fd6a649 | 100 | const NyLPC_TChar* d; |
nyatla | 37:fc4b4fd6a649 | 101 | //初めてのインデクスは保存 |
nyatla | 37:fc4b4fd6a649 | 102 | if(i_struct->idx==0){ |
nyatla | 37:fc4b4fd6a649 | 103 | i_struct->idx=12; |
nyatla | 37:fc4b4fd6a649 | 104 | i_struct->str=i_src; |
nyatla | 37:fc4b4fd6a649 | 105 | }else{ |
nyatla | 37:fc4b4fd6a649 | 106 | d=i_struct->str; |
nyatla | 37:fc4b4fd6a649 | 107 | do{ |
nyatla | 37:fc4b4fd6a649 | 108 | q=i_src; |
nyatla | 37:fc4b4fd6a649 | 109 | do{ |
nyatla | 37:fc4b4fd6a649 | 110 | if(strcmp(q,d)==0){ |
nyatla | 37:fc4b4fd6a649 | 111 | //一致,インデクスを計算 |
nyatla | 37:fc4b4fd6a649 | 112 | s=(NyLPC_TInt16)(q-i_src); |
nyatla | 37:fc4b4fd6a649 | 113 | k=(NyLPC_TInt16)(d-i_struct->str); |
nyatla | 37:fc4b4fd6a649 | 114 | //新しい長さを返す |
nyatla | 37:fc4b4fd6a649 | 115 | *((NyLPC_TInt16*)(i_src+s))=NyLPC_HTONS(0xC000|(i_struct->idx+k)); |
nyatla | 37:fc4b4fd6a649 | 116 | return s+2; |
nyatla | 37:fc4b4fd6a649 | 117 | } |
nyatla | 37:fc4b4fd6a649 | 118 | q+=*q+1; |
nyatla | 37:fc4b4fd6a649 | 119 | }while(*q!=0); |
nyatla | 37:fc4b4fd6a649 | 120 | d+=*d+1; |
nyatla | 37:fc4b4fd6a649 | 121 | }while(*d!=0); |
nyatla | 37:fc4b4fd6a649 | 122 | } |
nyatla | 37:fc4b4fd6a649 | 123 | return (NyLPC_TInt16)(strlen(i_src)+1); |
nyatla | 37:fc4b4fd6a649 | 124 | } |
nyatla | 37:fc4b4fd6a649 | 125 | |
nyatla | 37:fc4b4fd6a649 | 126 | |
nyatla | 37:fc4b4fd6a649 | 127 | |
nyatla | 37:fc4b4fd6a649 | 128 | |
nyatla | 37:fc4b4fd6a649 | 129 | |
nyatla | 37:fc4b4fd6a649 | 130 | /** |
nyatla | 37:fc4b4fd6a649 | 131 | * 受領可能なQuestionか確認する |
nyatla | 37:fc4b4fd6a649 | 132 | * @return |
nyatla | 37:fc4b4fd6a649 | 133 | * 受領可能なQuestionの数 |
nyatla | 37:fc4b4fd6a649 | 134 | * |
nyatla | 37:fc4b4fd6a649 | 135 | */ |
nyatla | 37:fc4b4fd6a649 | 136 | static NyLPC_TUInt16 getNumberOfQuestion(const void* i_packet,NyLPC_TUInt16 i_len) |
nyatla | 37:fc4b4fd6a649 | 137 | { |
nyatla | 37:fc4b4fd6a649 | 138 | struct NyLPC_TDnsHeader* ptr=(struct NyLPC_TDnsHeader*)i_packet; |
nyatla | 37:fc4b4fd6a649 | 139 | NyLPC_TUInt16 t; |
nyatla | 37:fc4b4fd6a649 | 140 | if(i_len<12){ |
nyatla | 37:fc4b4fd6a649 | 141 | return NyLPC_TBool_FALSE; |
nyatla | 37:fc4b4fd6a649 | 142 | } |
nyatla | 37:fc4b4fd6a649 | 143 | //questrionの確認 |
nyatla | 37:fc4b4fd6a649 | 144 | //QR==0 && op==0 && tc=0 |
nyatla | 37:fc4b4fd6a649 | 145 | t=NyLPC_ntohs(ptr->flag); |
nyatla | 37:fc4b4fd6a649 | 146 | if( ((t & NyLPC_TDnsHeader_FLAG_MASK_QR)!=0) && |
nyatla | 37:fc4b4fd6a649 | 147 | ((t & NyLPC_TDnsHeader_FLAG_MASK_OPCODE)!=0) && |
nyatla | 37:fc4b4fd6a649 | 148 | ((t & NyLPC_TDnsHeader_FLAG_MASK_TC)!=0)) |
nyatla | 37:fc4b4fd6a649 | 149 | { |
nyatla | 37:fc4b4fd6a649 | 150 | //this is response |
nyatla | 37:fc4b4fd6a649 | 151 | return 0; |
nyatla | 37:fc4b4fd6a649 | 152 | } |
nyatla | 37:fc4b4fd6a649 | 153 | return NyLPC_ntohs(ptr->qd); |
nyatla | 37:fc4b4fd6a649 | 154 | } |
nyatla | 37:fc4b4fd6a649 | 155 | |
nyatla | 37:fc4b4fd6a649 | 156 | static NyLPC_TInt16 NyLPC_TDnsQuestion_parse(const void* i_qpacket,NyLPC_TUInt16 i_len,struct NyLPC_TDnsQuestion* o_val) |
nyatla | 37:fc4b4fd6a649 | 157 | { |
nyatla | 37:fc4b4fd6a649 | 158 | NyLPC_TUInt16 l; |
nyatla | 37:fc4b4fd6a649 | 159 | NyLPC_TUInt16 i; |
nyatla | 37:fc4b4fd6a649 | 160 | const char* p=(const char*)i_qpacket; |
nyatla | 37:fc4b4fd6a649 | 161 | //QNameのパース'0終端' |
nyatla | 38:b0604fee76b0 | 162 | l=i_len-4-1;//スキャン長はパケットサイズ-5まで |
nyatla | 37:fc4b4fd6a649 | 163 | for(i=0;i<l;i++){ |
nyatla | 37:fc4b4fd6a649 | 164 | if(*(p+i)==0){ |
nyatla | 37:fc4b4fd6a649 | 165 | l=i+1;//NULL終端を加味した文字列長 |
nyatla | 37:fc4b4fd6a649 | 166 | o_val->qname=p; |
nyatla | 37:fc4b4fd6a649 | 167 | p+=l; |
nyatla | 37:fc4b4fd6a649 | 168 | o_val->qtype=NyLPC_ntohs(*(NyLPC_TUInt16*)p); |
nyatla | 37:fc4b4fd6a649 | 169 | o_val->qclass=NyLPC_ntohs(*(NyLPC_TUInt16*)(p+sizeof(NyLPC_TUInt16))); |
nyatla | 37:fc4b4fd6a649 | 170 | //OK |
nyatla | 37:fc4b4fd6a649 | 171 | return l+4; |
nyatla | 37:fc4b4fd6a649 | 172 | } |
nyatla | 37:fc4b4fd6a649 | 173 | } |
nyatla | 37:fc4b4fd6a649 | 174 | return 0; |
nyatla | 37:fc4b4fd6a649 | 175 | } |
nyatla | 37:fc4b4fd6a649 | 176 | |
nyatla | 37:fc4b4fd6a649 | 177 | /** |
nyatla | 37:fc4b4fd6a649 | 178 | * .区切りラベル文字列とDNSラベル文字列を比較する。 |
nyatla | 37:fc4b4fd6a649 | 179 | * @param record |
nyatla | 37:fc4b4fd6a649 | 180 | * .区切りのドメイン名 |
nyatla | 37:fc4b4fd6a649 | 181 | * @param question |
nyatla | 37:fc4b4fd6a649 | 182 | * QuestionName文字列 |
nyatla | 37:fc4b4fd6a649 | 183 | */ |
nyatla | 37:fc4b4fd6a649 | 184 | inline static NyLPC_TBool isEqualName(const char* record,const char* question) |
nyatla | 37:fc4b4fd6a649 | 185 | { |
nyatla | 37:fc4b4fd6a649 | 186 | char s; |
nyatla | 37:fc4b4fd6a649 | 187 | const char* q=question; |
nyatla | 37:fc4b4fd6a649 | 188 | const char* m=record; |
nyatla | 37:fc4b4fd6a649 | 189 | for(;;){ |
nyatla | 37:fc4b4fd6a649 | 190 | if(*m=='\0'){ |
nyatla | 37:fc4b4fd6a649 | 191 | //questionは最後のフラグメントが残るはず |
nyatla | 37:fc4b4fd6a649 | 192 | return memcmp(q,"\5local\0",7)==0; |
nyatla | 37:fc4b4fd6a649 | 193 | } |
nyatla | 37:fc4b4fd6a649 | 194 | s=*q; |
nyatla | 37:fc4b4fd6a649 | 195 | switch(*q) |
nyatla | 37:fc4b4fd6a649 | 196 | { |
nyatla | 37:fc4b4fd6a649 | 197 | case 0x00: |
nyatla | 37:fc4b4fd6a649 | 198 | return NyLPC_TBool_FALSE; |
nyatla | 37:fc4b4fd6a649 | 199 | case 0xc0: |
nyatla | 37:fc4b4fd6a649 | 200 | return NyLPC_TBool_FALSE;//offset |
nyatla | 37:fc4b4fd6a649 | 201 | default: |
nyatla | 37:fc4b4fd6a649 | 202 | q++; |
nyatla | 37:fc4b4fd6a649 | 203 | if(strncmp(m,q,s)!=0){ |
nyatla | 37:fc4b4fd6a649 | 204 | return NyLPC_TBool_FALSE; |
nyatla | 37:fc4b4fd6a649 | 205 | } |
nyatla | 37:fc4b4fd6a649 | 206 | m+=s; |
nyatla | 37:fc4b4fd6a649 | 207 | q+=s; |
nyatla | 37:fc4b4fd6a649 | 208 | } |
nyatla | 37:fc4b4fd6a649 | 209 | m++; |
nyatla | 37:fc4b4fd6a649 | 210 | } |
nyatla | 37:fc4b4fd6a649 | 211 | } |
nyatla | 37:fc4b4fd6a649 | 212 | /** |
nyatla | 37:fc4b4fd6a649 | 213 | * DNSレコードのPRTフィールドとDNSラベル文字列を比較する。 |
nyatla | 37:fc4b4fd6a649 | 214 | */ |
nyatla | 37:fc4b4fd6a649 | 215 | static NyLPC_TInt16 NyLPC_TDnsRecord_getMatchPtrIdx(const struct NyLPC_TDnsRecord* i_struct,const NyLPC_TChar* question) |
nyatla | 37:fc4b4fd6a649 | 216 | { |
nyatla | 37:fc4b4fd6a649 | 217 | NyLPC_TInt16 i; |
nyatla | 37:fc4b4fd6a649 | 218 | for(i=0;i<i_struct->num_of_srv;i++){ |
nyatla | 37:fc4b4fd6a649 | 219 | if(isEqualName(i_struct->srv[i].protocol,question)){ |
nyatla | 37:fc4b4fd6a649 | 220 | return i; |
nyatla | 37:fc4b4fd6a649 | 221 | } |
nyatla | 37:fc4b4fd6a649 | 222 | } |
nyatla | 37:fc4b4fd6a649 | 223 | return -1; |
nyatla | 37:fc4b4fd6a649 | 224 | } |
nyatla | 37:fc4b4fd6a649 | 225 | static NyLPC_TInt16 NyLPC_TDnsRecord_getMatchSrvIdx(const struct NyLPC_TDnsRecord* i_struct,const NyLPC_TChar* question) |
nyatla | 37:fc4b4fd6a649 | 226 | { |
nyatla | 37:fc4b4fd6a649 | 227 | NyLPC_TInt16 i; |
nyatla | 37:fc4b4fd6a649 | 228 | NyLPC_TInt16 l=(NyLPC_TInt16)strlen(i_struct->name); |
nyatla | 37:fc4b4fd6a649 | 229 | //Aレコードをチェック |
nyatla | 37:fc4b4fd6a649 | 230 | if(l!=question[0] || memcmp(question+1,i_struct->name,l)!=0){ |
nyatla | 37:fc4b4fd6a649 | 231 | return -1; |
nyatla | 37:fc4b4fd6a649 | 232 | } |
nyatla | 37:fc4b4fd6a649 | 233 | for(i=0;i<i_struct->num_of_srv;i++){ |
nyatla | 37:fc4b4fd6a649 | 234 | if(isEqualName(i_struct->srv[i].protocol,question+l+1)){ |
nyatla | 37:fc4b4fd6a649 | 235 | return i; |
nyatla | 37:fc4b4fd6a649 | 236 | } |
nyatla | 37:fc4b4fd6a649 | 237 | } |
nyatla | 37:fc4b4fd6a649 | 238 | return -1; |
nyatla | 37:fc4b4fd6a649 | 239 | } |
nyatla | 37:fc4b4fd6a649 | 240 | /** |
nyatla | 37:fc4b4fd6a649 | 241 | * _services._dns-sd._udp.localであるか確認する。 |
nyatla | 37:fc4b4fd6a649 | 242 | */ |
nyatla | 37:fc4b4fd6a649 | 243 | static NyLPC_TBool NyLPC_TDnsRecord_isServicesDnsSd(const NyLPC_TChar* question) |
nyatla | 37:fc4b4fd6a649 | 244 | { |
nyatla | 37:fc4b4fd6a649 | 245 | return memcmp(question,"\x09_services\x07_dns-sd\x04_udp\5local\x00",30)==0; |
nyatla | 37:fc4b4fd6a649 | 246 | } |
nyatla | 37:fc4b4fd6a649 | 247 | |
nyatla | 37:fc4b4fd6a649 | 248 | |
nyatla | 37:fc4b4fd6a649 | 249 | /** |
nyatla | 37:fc4b4fd6a649 | 250 | * '.'区切り文字列をDNS形式の[n]text[n]text\0へ変換する。 |
nyatla | 37:fc4b4fd6a649 | 251 | * @return |
nyatla | 37:fc4b4fd6a649 | 252 | * 変換後のデータブロックの長さin byte |
nyatla | 37:fc4b4fd6a649 | 253 | * 終端の\0の長さを含みます。 |
nyatla | 37:fc4b4fd6a649 | 254 | */ |
nyatla | 37:fc4b4fd6a649 | 255 | static NyLPC_TInt16 str2label(NyLPC_TChar* buf,const NyLPC_TChar* name) |
nyatla | 37:fc4b4fd6a649 | 256 | { |
nyatla | 37:fc4b4fd6a649 | 257 | //proto文字列の変換 |
nyatla | 37:fc4b4fd6a649 | 258 | NyLPC_TChar* lp; |
nyatla | 37:fc4b4fd6a649 | 259 | const NyLPC_TChar* n=name; |
nyatla | 37:fc4b4fd6a649 | 260 | NyLPC_TChar* b=buf; |
nyatla | 37:fc4b4fd6a649 | 261 | while(*n!='\0'){ |
nyatla | 37:fc4b4fd6a649 | 262 | lp=b; |
nyatla | 37:fc4b4fd6a649 | 263 | b++; |
nyatla | 37:fc4b4fd6a649 | 264 | for(;strchr(".\0",*n)==NULL;){ |
nyatla | 37:fc4b4fd6a649 | 265 | *b=*n; |
nyatla | 37:fc4b4fd6a649 | 266 | b++; |
nyatla | 37:fc4b4fd6a649 | 267 | n++; |
nyatla | 37:fc4b4fd6a649 | 268 | } |
nyatla | 37:fc4b4fd6a649 | 269 | *lp=(char)(b-lp-1); |
nyatla | 37:fc4b4fd6a649 | 270 | if(*n!='\0'){ |
nyatla | 37:fc4b4fd6a649 | 271 | n++; |
nyatla | 37:fc4b4fd6a649 | 272 | } |
nyatla | 37:fc4b4fd6a649 | 273 | } |
nyatla | 37:fc4b4fd6a649 | 274 | *b='\0'; |
nyatla | 37:fc4b4fd6a649 | 275 | b++; |
nyatla | 37:fc4b4fd6a649 | 276 | return b-buf; |
nyatla | 37:fc4b4fd6a649 | 277 | } |
nyatla | 37:fc4b4fd6a649 | 278 | |
nyatla | 37:fc4b4fd6a649 | 279 | /** |
nyatla | 37:fc4b4fd6a649 | 280 | * ResourceHeaderのライタ |
nyatla | 37:fc4b4fd6a649 | 281 | */ |
nyatla | 37:fc4b4fd6a649 | 282 | static NyLPC_TInt16 writeResourceHeader(char* buf,NyLPC_TInt16 len,const char* i_name,NyLPC_TUInt16 i_type,NyLPC_TUInt16 i_class) |
nyatla | 37:fc4b4fd6a649 | 283 | { |
nyatla | 37:fc4b4fd6a649 | 284 | NyLPC_TInt16 s; |
nyatla | 37:fc4b4fd6a649 | 285 | NyLPC_TInt16 l=1+(NyLPC_TInt16)strlen(i_name)+1+5+1; |
nyatla | 37:fc4b4fd6a649 | 286 | if(len<l+4+4){ |
nyatla | 37:fc4b4fd6a649 | 287 | return 0; |
nyatla | 37:fc4b4fd6a649 | 288 | } |
nyatla | 37:fc4b4fd6a649 | 289 | s=str2label(buf,i_name); |
nyatla | 37:fc4b4fd6a649 | 290 | str2label(buf+s-1,"local"); |
nyatla | 37:fc4b4fd6a649 | 291 | (*(NyLPC_TUInt16*)(buf+l))=NyLPC_HTONS(i_type); |
nyatla | 37:fc4b4fd6a649 | 292 | (*(NyLPC_TUInt16*)(buf+l+2))=NyLPC_HTONS(i_class); |
nyatla | 37:fc4b4fd6a649 | 293 | (*(NyLPC_TUInt32*)(buf+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL); |
nyatla | 37:fc4b4fd6a649 | 294 | return l+2+2+4; |
nyatla | 37:fc4b4fd6a649 | 295 | } |
nyatla | 37:fc4b4fd6a649 | 296 | |
nyatla | 37:fc4b4fd6a649 | 297 | inline static NyLPC_TInt16 writeSrvResourceHeader(char* buf,NyLPC_TInt16 len,const struct NyLPC_TDnsRecord* i_recode,int i_sid,NyLPC_TUInt16 i_type,NyLPC_TUInt16 i_class,struct TLabelCache* i_ca) |
nyatla | 37:fc4b4fd6a649 | 298 | { |
nyatla | 37:fc4b4fd6a649 | 299 | NyLPC_TInt16 l=(NyLPC_TInt16)(1+strlen(i_recode->name)+1+strlen(i_recode->srv[i_sid].protocol)+1+5+1); |
nyatla | 37:fc4b4fd6a649 | 300 | if(len<l+2+2+4){ |
nyatla | 37:fc4b4fd6a649 | 301 | return 0; |
nyatla | 37:fc4b4fd6a649 | 302 | } |
nyatla | 37:fc4b4fd6a649 | 303 | l=str2label(buf,i_recode->name)-1; |
nyatla | 37:fc4b4fd6a649 | 304 | l+=str2label(buf+l,i_recode->srv[i_sid].protocol)-1; |
nyatla | 37:fc4b4fd6a649 | 305 | l+=str2label(buf+l,"local"); |
nyatla | 37:fc4b4fd6a649 | 306 | l=TLabelCache_compress(i_ca,buf);//圧縮 |
nyatla | 37:fc4b4fd6a649 | 307 | (*(NyLPC_TUInt16*)(buf+l))=NyLPC_HTONS(i_type); |
nyatla | 37:fc4b4fd6a649 | 308 | (*(NyLPC_TUInt16*)(buf+l+2))=NyLPC_HTONS(i_class); |
nyatla | 37:fc4b4fd6a649 | 309 | (*(NyLPC_TUInt32*)(buf+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL); |
nyatla | 37:fc4b4fd6a649 | 310 | return l+2+2+4; |
nyatla | 37:fc4b4fd6a649 | 311 | } |
nyatla | 37:fc4b4fd6a649 | 312 | |
nyatla | 37:fc4b4fd6a649 | 313 | inline static NyLPC_TUInt16 setResponseHeader(char* obuf,const struct NyLPC_TDnsHeader* i_in_dns_header,NyLPC_TUInt16 i_an_count,NyLPC_TUInt16 i_ns_count,NyLPC_TUInt16 i_ar_count) |
nyatla | 37:fc4b4fd6a649 | 314 | { |
nyatla | 37:fc4b4fd6a649 | 315 | struct NyLPC_TDnsHeader* p=(struct NyLPC_TDnsHeader*)obuf; |
nyatla | 37:fc4b4fd6a649 | 316 | if(i_in_dns_header!=NULL){ |
nyatla | 37:fc4b4fd6a649 | 317 | memcpy(p,i_in_dns_header,sizeof(struct NyLPC_TDnsHeader)); |
nyatla | 37:fc4b4fd6a649 | 318 | p->flag=p->flag | NyLPC_HTONS(NyLPC_TDnsHeader_FLAG_MASK_QR|NyLPC_TDnsHeader_FLAG_MASK_AA); |
nyatla | 37:fc4b4fd6a649 | 319 | p->flag=p->flag & NyLPC_HTONS(~(NyLPC_TDnsHeader_FLAG_MASK_RECODE|NyLPC_TDnsHeader_FLAG_MASK_TC|NyLPC_TDnsHeader_FLAG_MASK_RA)); |
nyatla | 37:fc4b4fd6a649 | 320 | }else{ |
nyatla | 37:fc4b4fd6a649 | 321 | p->flag=0; |
nyatla | 37:fc4b4fd6a649 | 322 | p->id=0; |
nyatla | 37:fc4b4fd6a649 | 323 | } |
nyatla | 37:fc4b4fd6a649 | 324 | p->qd=0; |
nyatla | 37:fc4b4fd6a649 | 325 | p->an=NyLPC_HTONS(i_an_count); |
nyatla | 37:fc4b4fd6a649 | 326 | p->ns=NyLPC_HTONS(i_ns_count); |
nyatla | 37:fc4b4fd6a649 | 327 | p->ar=NyLPC_HTONS(i_ar_count); |
nyatla | 37:fc4b4fd6a649 | 328 | return sizeof(struct NyLPC_TDnsHeader); |
nyatla | 37:fc4b4fd6a649 | 329 | } |
nyatla | 37:fc4b4fd6a649 | 330 | inline static NyLPC_TInt16 writeARecord(char* obuf,NyLPC_TInt16 obuflen,const NyLPC_TChar* a_rec,const struct NyLPC_TIPv4Addr* ip) |
nyatla | 37:fc4b4fd6a649 | 331 | { |
nyatla | 37:fc4b4fd6a649 | 332 | NyLPC_TInt16 ret; |
nyatla | 37:fc4b4fd6a649 | 333 | //AnswerはAレコードのみ |
nyatla | 37:fc4b4fd6a649 | 334 | //A record header |
nyatla | 37:fc4b4fd6a649 | 335 | ret=writeResourceHeader(obuf,obuflen,a_rec,NyLPC_TDnsQuestion_QTYPR_A,NyLPC_TDnsQuestion_QCLASS_IN); |
nyatla | 37:fc4b4fd6a649 | 336 | if(ret==0 || obuflen-ret<8){ |
nyatla | 37:fc4b4fd6a649 | 337 | return 0; |
nyatla | 37:fc4b4fd6a649 | 338 | } |
nyatla | 37:fc4b4fd6a649 | 339 | //Aレコードを書く |
nyatla | 37:fc4b4fd6a649 | 340 | //IPADDR |
nyatla | 37:fc4b4fd6a649 | 341 | (*(NyLPC_TUInt16*)(obuf+ret))=NyLPC_HTONS(4); |
nyatla | 37:fc4b4fd6a649 | 342 | (*(NyLPC_TUInt32*)(obuf+ret+2))=ip->v; |
nyatla | 37:fc4b4fd6a649 | 343 | return ret+8; |
nyatla | 37:fc4b4fd6a649 | 344 | } |
nyatla | 37:fc4b4fd6a649 | 345 | static NyLPC_TInt16 writeSdPtrRecord(const char* i_qname,const struct NyLPC_TMDnsServiceRecord* i_srvlec,char* obuf,NyLPC_TInt16 obuflen) |
nyatla | 37:fc4b4fd6a649 | 346 | { |
nyatla | 37:fc4b4fd6a649 | 347 | NyLPC_TInt16 l,s; |
nyatla | 37:fc4b4fd6a649 | 348 | //Header |
nyatla | 37:fc4b4fd6a649 | 349 | s=(NyLPC_TInt16)strlen(i_qname)+1; |
nyatla | 37:fc4b4fd6a649 | 350 | //Headerの長さチェック |
nyatla | 37:fc4b4fd6a649 | 351 | if(obuflen<s+2+2+4){ |
nyatla | 37:fc4b4fd6a649 | 352 | return 0; |
nyatla | 37:fc4b4fd6a649 | 353 | } |
nyatla | 37:fc4b4fd6a649 | 354 | //Header書込み |
nyatla | 37:fc4b4fd6a649 | 355 | memcpy(obuf,i_qname,s); |
nyatla | 37:fc4b4fd6a649 | 356 | (*(NyLPC_TUInt16*)(obuf+s))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_PTR); |
nyatla | 37:fc4b4fd6a649 | 357 | (*(NyLPC_TUInt16*)(obuf+s+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN); |
nyatla | 37:fc4b4fd6a649 | 358 | (*(NyLPC_TUInt32*)(obuf+s+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL); |
nyatla | 37:fc4b4fd6a649 | 359 | l=s+2+2+4; |
nyatla | 37:fc4b4fd6a649 | 360 | |
nyatla | 37:fc4b4fd6a649 | 361 | //Resourceの書込み |
nyatla | 37:fc4b4fd6a649 | 362 | s=(NyLPC_TInt16)(1+strlen(i_srvlec->protocol)+1+5+1);//逆引き文字列の長さ(デリミタ×3+1) |
nyatla | 37:fc4b4fd6a649 | 363 | if(obuflen<s+l+2){ |
nyatla | 37:fc4b4fd6a649 | 364 | return 0; |
nyatla | 37:fc4b4fd6a649 | 365 | } |
nyatla | 37:fc4b4fd6a649 | 366 | (*(NyLPC_TUInt16*)(obuf+l))=NyLPC_ntohs(s); |
nyatla | 37:fc4b4fd6a649 | 367 | l+=2; |
nyatla | 37:fc4b4fd6a649 | 368 | l+=str2label(obuf+l,i_srvlec->protocol)-1; |
nyatla | 37:fc4b4fd6a649 | 369 | l+=str2label(obuf+l,"local"); |
nyatla | 37:fc4b4fd6a649 | 370 | return l; |
nyatla | 37:fc4b4fd6a649 | 371 | } |
nyatla | 37:fc4b4fd6a649 | 372 | static NyLPC_TInt16 writePtrRecord(const struct NyLPC_TDnsRecord* i_recode,NyLPC_TInt16 i_sid,char* obuf,NyLPC_TInt16 obuflen,struct TLabelCache* i_ca) |
nyatla | 37:fc4b4fd6a649 | 373 | { |
nyatla | 37:fc4b4fd6a649 | 374 | NyLPC_TInt16 l,s; |
nyatla | 37:fc4b4fd6a649 | 375 | NyLPC_TUInt16* rlen; |
nyatla | 37:fc4b4fd6a649 | 376 | //Header:開始文字数(1)+プレフィクス(n)+終端(1)+local(5)+1 |
nyatla | 37:fc4b4fd6a649 | 377 | s=(NyLPC_TInt16)(1+strlen(i_recode->srv[i_sid].protocol)+1+5+1); |
nyatla | 37:fc4b4fd6a649 | 378 | //Headerの長さチェック |
nyatla | 37:fc4b4fd6a649 | 379 | if(obuflen<s+2+2+4){ |
nyatla | 37:fc4b4fd6a649 | 380 | return 0; |
nyatla | 37:fc4b4fd6a649 | 381 | } |
nyatla | 37:fc4b4fd6a649 | 382 | //Header書込み |
nyatla | 37:fc4b4fd6a649 | 383 | s=str2label(obuf,i_recode->srv[i_sid].protocol)-1; |
nyatla | 37:fc4b4fd6a649 | 384 | s+=str2label(obuf+s,"local"); |
nyatla | 37:fc4b4fd6a649 | 385 | s=TLabelCache_compress(i_ca,obuf); |
nyatla | 37:fc4b4fd6a649 | 386 | (*(NyLPC_TUInt16*)(obuf+s))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_PTR); |
nyatla | 37:fc4b4fd6a649 | 387 | (*(NyLPC_TUInt16*)(obuf+s+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN); |
nyatla | 97:6ca5900a2d68 | 388 | (*(NyLPC_TUInt32*)(obuf+s+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL); |
nyatla | 37:fc4b4fd6a649 | 389 | l=s+2+2+4; |
nyatla | 37:fc4b4fd6a649 | 390 | |
nyatla | 37:fc4b4fd6a649 | 391 | //Resourceの書込み |
nyatla | 37:fc4b4fd6a649 | 392 | s=1+strlen(i_recode->name)+1+strlen(i_recode->srv[i_sid].protocol)+1+5+1;//逆引き文字列の長さ(デリミタ×3+1) |
nyatla | 37:fc4b4fd6a649 | 393 | if(obuflen<s+l+2){ |
nyatla | 37:fc4b4fd6a649 | 394 | return 0; |
nyatla | 37:fc4b4fd6a649 | 395 | } |
nyatla | 37:fc4b4fd6a649 | 396 | rlen=(NyLPC_TUInt16*)(obuf+l); |
nyatla | 37:fc4b4fd6a649 | 397 | l+=2; |
nyatla | 37:fc4b4fd6a649 | 398 | s=str2label(obuf+l,i_recode->name)-1; |
nyatla | 37:fc4b4fd6a649 | 399 | s+=str2label(obuf+l+s,i_recode->srv[i_sid].protocol)-1; |
nyatla | 37:fc4b4fd6a649 | 400 | s+=str2label(obuf+l+s,"local"); |
nyatla | 37:fc4b4fd6a649 | 401 | s=TLabelCache_compress(i_ca,obuf+l);//圧縮 |
nyatla | 37:fc4b4fd6a649 | 402 | (*rlen)=NyLPC_ntohs(s); |
nyatla | 37:fc4b4fd6a649 | 403 | return l+s; |
nyatla | 37:fc4b4fd6a649 | 404 | } |
nyatla | 37:fc4b4fd6a649 | 405 | |
nyatla | 37:fc4b4fd6a649 | 406 | |
nyatla | 37:fc4b4fd6a649 | 407 | static NyLPC_TInt16 writeSRVRecord(NyLPC_TcMDnsServer_t* i_inst,NyLPC_TInt16 i_sid,char* obuf,NyLPC_TInt16 obuflen,struct TLabelCache* i_ca) |
nyatla | 37:fc4b4fd6a649 | 408 | { |
nyatla | 37:fc4b4fd6a649 | 409 | NyLPC_TInt16 l,s; |
nyatla | 37:fc4b4fd6a649 | 410 | NyLPC_TUInt16* rlen; |
nyatla | 37:fc4b4fd6a649 | 411 | |
nyatla | 37:fc4b4fd6a649 | 412 | //SRV Record |
nyatla | 37:fc4b4fd6a649 | 413 | s=writeSrvResourceHeader(obuf,obuflen,i_inst->_ref_record,i_sid,NyLPC_TDnsQuestion_QTYPR_SRV,NyLPC_TDnsQuestion_QCLASS_IN,i_ca); |
nyatla | 37:fc4b4fd6a649 | 414 | if(s==0){ |
nyatla | 37:fc4b4fd6a649 | 415 | return 0; |
nyatla | 37:fc4b4fd6a649 | 416 | } |
nyatla | 37:fc4b4fd6a649 | 417 | |
nyatla | 37:fc4b4fd6a649 | 418 | l=1+strlen(i_inst->_ref_record->a)+1+5+1;//逆引き文字列の長さ(デリミタ×3+1) |
nyatla | 37:fc4b4fd6a649 | 419 | if(obuflen-s-l<8){ |
nyatla | 37:fc4b4fd6a649 | 420 | return 0; |
nyatla | 37:fc4b4fd6a649 | 421 | } |
nyatla | 37:fc4b4fd6a649 | 422 | //IPADDR |
nyatla | 37:fc4b4fd6a649 | 423 | rlen=(NyLPC_TUInt16*)(obuf+s); |
nyatla | 37:fc4b4fd6a649 | 424 | (*(NyLPC_TUInt16*)(obuf+s+2))=NyLPC_HTONS(0);//Priority |
nyatla | 37:fc4b4fd6a649 | 425 | (*(NyLPC_TUInt16*)(obuf+s+4))=NyLPC_HTONS(0);//Weight |
nyatla | 37:fc4b4fd6a649 | 426 | (*(NyLPC_TUInt16*)(obuf+s+6))=NyLPC_HTONS(i_inst->_ref_record->srv[i_sid].port);//PORT |
nyatla | 37:fc4b4fd6a649 | 427 | l=4*2+s; |
nyatla | 37:fc4b4fd6a649 | 428 | s=str2label(obuf+l,i_inst->_ref_record->a)-1; |
nyatla | 37:fc4b4fd6a649 | 429 | s+=str2label(obuf+l+s,"local"); |
nyatla | 37:fc4b4fd6a649 | 430 | s=TLabelCache_compress(i_ca,obuf+l);//圧縮 |
nyatla | 37:fc4b4fd6a649 | 431 | (*rlen)=NyLPC_HTONS(2+2+2+s); |
nyatla | 37:fc4b4fd6a649 | 432 | return l+s; |
nyatla | 37:fc4b4fd6a649 | 433 | } |
nyatla | 37:fc4b4fd6a649 | 434 | static NyLPC_TInt16 writeTXTRecord(NyLPC_TcMDnsServer_t* i_inst,NyLPC_TInt16 i_sid,char* obuf,NyLPC_TInt16 obuflen,struct TLabelCache* i_ca) |
nyatla | 37:fc4b4fd6a649 | 435 | { |
nyatla | 37:fc4b4fd6a649 | 436 | NyLPC_TInt16 ret; |
nyatla | 37:fc4b4fd6a649 | 437 | NyLPC_TInt16 l; |
nyatla | 37:fc4b4fd6a649 | 438 | //Answer |
nyatla | 37:fc4b4fd6a649 | 439 | ret=writeSrvResourceHeader(obuf,obuflen,i_inst->_ref_record,i_sid,NyLPC_TDnsQuestion_QTYPR_TXT,NyLPC_TDnsQuestion_QCLASS_IN,i_ca); |
nyatla | 37:fc4b4fd6a649 | 440 | if(ret==0){ |
nyatla | 37:fc4b4fd6a649 | 441 | return 0; |
nyatla | 37:fc4b4fd6a649 | 442 | } |
nyatla | 37:fc4b4fd6a649 | 443 | //name.proto.localを返す。 |
nyatla | 37:fc4b4fd6a649 | 444 | if(obuflen-ret<2){ |
nyatla | 37:fc4b4fd6a649 | 445 | return 0; |
nyatla | 37:fc4b4fd6a649 | 446 | } |
nyatla | 37:fc4b4fd6a649 | 447 | (*(NyLPC_TUInt16*)(obuf+ret))=NyLPC_ntohs(0); |
nyatla | 37:fc4b4fd6a649 | 448 | //proto.name.local. |
nyatla | 37:fc4b4fd6a649 | 449 | l=ret+2; |
nyatla | 37:fc4b4fd6a649 | 450 | return l; |
nyatla | 37:fc4b4fd6a649 | 451 | } |
nyatla | 37:fc4b4fd6a649 | 452 | |
nyatla | 37:fc4b4fd6a649 | 453 | |
nyatla | 37:fc4b4fd6a649 | 454 | |
nyatla | 37:fc4b4fd6a649 | 455 | |
nyatla | 37:fc4b4fd6a649 | 456 | |
nyatla | 37:fc4b4fd6a649 | 457 | |
nyatla | 37:fc4b4fd6a649 | 458 | static void sendAnnounse(NyLPC_TcMDnsServer_t* i_inst) |
nyatla | 37:fc4b4fd6a649 | 459 | { |
nyatla | 37:fc4b4fd6a649 | 460 | char* obuf; |
nyatla | 37:fc4b4fd6a649 | 461 | NyLPC_TUInt16 obuflen; |
nyatla | 37:fc4b4fd6a649 | 462 | NyLPC_TUInt16 l,s; |
nyatla | 37:fc4b4fd6a649 | 463 | int i2; |
nyatla | 37:fc4b4fd6a649 | 464 | struct TLabelCache cache; |
nyatla | 37:fc4b4fd6a649 | 465 | for(i2=0;i2<i_inst->_ref_record->num_of_srv;i2++){ |
nyatla | 37:fc4b4fd6a649 | 466 | TLabelCache_reset(&cache); |
nyatla | 37:fc4b4fd6a649 | 467 | //Bufferの取得 |
nyatla | 37:fc4b4fd6a649 | 468 | obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,TIMEOUT_IN_MS); |
nyatla | 37:fc4b4fd6a649 | 469 | if(obuf==NULL){ |
nyatla | 37:fc4b4fd6a649 | 470 | return; |
nyatla | 37:fc4b4fd6a649 | 471 | } |
nyatla | 37:fc4b4fd6a649 | 472 | l=setResponseHeader(obuf,NULL,1,0,3); |
nyatla | 37:fc4b4fd6a649 | 473 | s=writePtrRecord(i_inst->_ref_record,i2,obuf+l,obuflen-l,&cache); |
nyatla | 37:fc4b4fd6a649 | 474 | if(s<=0){ |
nyatla | 37:fc4b4fd6a649 | 475 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 37:fc4b4fd6a649 | 476 | } |
nyatla | 37:fc4b4fd6a649 | 477 | l+=s; |
nyatla | 37:fc4b4fd6a649 | 478 | s=writeSRVRecord(i_inst,i2,obuf+l,obuflen-l,&cache); |
nyatla | 37:fc4b4fd6a649 | 479 | if(s<=0){ |
nyatla | 37:fc4b4fd6a649 | 480 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 37:fc4b4fd6a649 | 481 | } |
nyatla | 37:fc4b4fd6a649 | 482 | l+=s; |
nyatla | 37:fc4b4fd6a649 | 483 | s=writeTXTRecord(i_inst,i2,obuf+l,obuflen-l,&cache); |
nyatla | 37:fc4b4fd6a649 | 484 | if(s<=0){ |
nyatla | 37:fc4b4fd6a649 | 485 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 37:fc4b4fd6a649 | 486 | } |
nyatla | 37:fc4b4fd6a649 | 487 | l+=s; |
nyatla | 37:fc4b4fd6a649 | 488 | //Aレコード |
nyatla | 37:fc4b4fd6a649 | 489 | s=writeARecord(obuf+l,obuflen-l,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr)); |
nyatla | 37:fc4b4fd6a649 | 490 | if(s<=0){ |
nyatla | 37:fc4b4fd6a649 | 491 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 37:fc4b4fd6a649 | 492 | } |
nyatla | 37:fc4b4fd6a649 | 493 | l+=s; |
nyatla | 37:fc4b4fd6a649 | 494 | if(!NyLPC_cUdpSocket_psend(&(i_inst->_super),&MDNS_MCAST_IPADDR,MDNS_MCAST_PORT,obuf,l)){ |
nyatla | 37:fc4b4fd6a649 | 495 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 37:fc4b4fd6a649 | 496 | } |
nyatla | 37:fc4b4fd6a649 | 497 | } |
nyatla | 37:fc4b4fd6a649 | 498 | return; |
nyatla | 37:fc4b4fd6a649 | 499 | ERROR: |
nyatla | 37:fc4b4fd6a649 | 500 | NyLPC_cUdpSocket_releaseSendBuf(&(i_inst->_super),obuf); |
nyatla | 37:fc4b4fd6a649 | 501 | return; |
nyatla | 37:fc4b4fd6a649 | 502 | } |
nyatla | 37:fc4b4fd6a649 | 503 | |
nyatla | 37:fc4b4fd6a649 | 504 | |
nyatla | 37:fc4b4fd6a649 | 505 | static void sendReply2(NyLPC_TcMDnsServer_t* i_inst,const struct NyLPC_TDnsHeader* i_dns_header,const struct NyLPC_TDnsQuestion* q) |
nyatla | 37:fc4b4fd6a649 | 506 | { |
nyatla | 37:fc4b4fd6a649 | 507 | NyLPC_TInt16 ptr_recode; |
nyatla | 37:fc4b4fd6a649 | 508 | NyLPC_TInt16 i2; |
nyatla | 37:fc4b4fd6a649 | 509 | char* obuf; |
nyatla | 37:fc4b4fd6a649 | 510 | NyLPC_TUInt16 obuflen; |
nyatla | 37:fc4b4fd6a649 | 511 | NyLPC_TUInt16 l,s; |
nyatla | 37:fc4b4fd6a649 | 512 | struct TLabelCache cache; |
nyatla | 37:fc4b4fd6a649 | 513 | TLabelCache_reset(&cache); |
nyatla | 37:fc4b4fd6a649 | 514 | //パケットヘッダの生成 |
nyatla | 37:fc4b4fd6a649 | 515 | switch(q->qtype){ |
nyatla | 37:fc4b4fd6a649 | 516 | case NyLPC_TDnsQuestion_QTYPR_SRV: |
nyatla | 37:fc4b4fd6a649 | 517 | //SRV,A record |
nyatla | 37:fc4b4fd6a649 | 518 | ptr_recode=NyLPC_TDnsRecord_getMatchSrvIdx(i_inst->_ref_record,q->qname); |
nyatla | 37:fc4b4fd6a649 | 519 | if(ptr_recode<0){ |
nyatla | 37:fc4b4fd6a649 | 520 | goto DROP; |
nyatla | 37:fc4b4fd6a649 | 521 | } |
nyatla | 37:fc4b4fd6a649 | 522 | //Bufferの取得 |
nyatla | 37:fc4b4fd6a649 | 523 | obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0); |
nyatla | 37:fc4b4fd6a649 | 524 | if(obuf==NULL){ |
nyatla | 37:fc4b4fd6a649 | 525 | goto DROP; |
nyatla | 37:fc4b4fd6a649 | 526 | } |
nyatla | 37:fc4b4fd6a649 | 527 | l=setResponseHeader(obuf,i_dns_header,1,0,2); |
nyatla | 37:fc4b4fd6a649 | 528 | s=writeSRVRecord(i_inst,ptr_recode,obuf+l,obuflen-l,&cache); |
nyatla | 37:fc4b4fd6a649 | 529 | if(s<=0){ |
nyatla | 37:fc4b4fd6a649 | 530 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 37:fc4b4fd6a649 | 531 | } |
nyatla | 37:fc4b4fd6a649 | 532 | l+=s; |
nyatla | 37:fc4b4fd6a649 | 533 | s=writeTXTRecord(i_inst,ptr_recode,obuf+l,obuflen-l,&cache); |
nyatla | 37:fc4b4fd6a649 | 534 | if(s<=0){ |
nyatla | 37:fc4b4fd6a649 | 535 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 37:fc4b4fd6a649 | 536 | } |
nyatla | 37:fc4b4fd6a649 | 537 | l+=s; |
nyatla | 37:fc4b4fd6a649 | 538 | //Aレコード |
nyatla | 37:fc4b4fd6a649 | 539 | s=writeARecord(obuf+l,obuflen-l,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr)); |
nyatla | 37:fc4b4fd6a649 | 540 | if(s<=0){ |
nyatla | 37:fc4b4fd6a649 | 541 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 37:fc4b4fd6a649 | 542 | } |
nyatla | 37:fc4b4fd6a649 | 543 | l+=s; |
nyatla | 37:fc4b4fd6a649 | 544 | break; |
nyatla | 37:fc4b4fd6a649 | 545 | case NyLPC_TDnsQuestion_QTYPR_A: |
nyatla | 37:fc4b4fd6a649 | 546 | //自分宛?(name.local) |
nyatla | 37:fc4b4fd6a649 | 547 | if(!isEqualName(i_inst->_ref_record->a,q->qname)){ |
nyatla | 37:fc4b4fd6a649 | 548 | goto DROP; |
nyatla | 37:fc4b4fd6a649 | 549 | } |
nyatla | 37:fc4b4fd6a649 | 550 | //Bufferの取得 |
nyatla | 37:fc4b4fd6a649 | 551 | obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0); |
nyatla | 37:fc4b4fd6a649 | 552 | if(obuf==NULL){ |
nyatla | 37:fc4b4fd6a649 | 553 | goto DROP; |
nyatla | 37:fc4b4fd6a649 | 554 | } |
nyatla | 37:fc4b4fd6a649 | 555 | //Headerのコピー |
nyatla | 37:fc4b4fd6a649 | 556 | l=setResponseHeader(obuf,i_dns_header,1,0,0); |
nyatla | 37:fc4b4fd6a649 | 557 | //Aレコードのみ |
nyatla | 37:fc4b4fd6a649 | 558 | s=writeARecord(obuf+l,obuflen-l,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr)); |
nyatla | 37:fc4b4fd6a649 | 559 | if(s<=0){ |
nyatla | 37:fc4b4fd6a649 | 560 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 37:fc4b4fd6a649 | 561 | } |
nyatla | 37:fc4b4fd6a649 | 562 | l+=s; |
nyatla | 37:fc4b4fd6a649 | 563 | break; |
nyatla | 37:fc4b4fd6a649 | 564 | case NyLPC_TDnsQuestion_QTYPR_PTR: |
nyatla | 37:fc4b4fd6a649 | 565 | if(NyLPC_TDnsRecord_isServicesDnsSd(q->qname)){ |
nyatla | 37:fc4b4fd6a649 | 566 | //Bufferの取得 |
nyatla | 37:fc4b4fd6a649 | 567 | obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0); |
nyatla | 37:fc4b4fd6a649 | 568 | if(obuf==NULL){ |
nyatla | 37:fc4b4fd6a649 | 569 | goto DROP; |
nyatla | 37:fc4b4fd6a649 | 570 | } |
nyatla | 37:fc4b4fd6a649 | 571 | l=setResponseHeader(obuf,i_dns_header,i_inst->_ref_record->num_of_srv,0,0); |
nyatla | 37:fc4b4fd6a649 | 572 | for(i2=0;i2<i_inst->_ref_record->num_of_srv;i2++){ |
nyatla | 37:fc4b4fd6a649 | 573 | s=writeSdPtrRecord(q->qname,&(i_inst->_ref_record->srv[i2]),obuf+l,obuflen-l); |
nyatla | 37:fc4b4fd6a649 | 574 | if(s<=0){ |
nyatla | 37:fc4b4fd6a649 | 575 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 37:fc4b4fd6a649 | 576 | } |
nyatla | 37:fc4b4fd6a649 | 577 | l+=s; |
nyatla | 37:fc4b4fd6a649 | 578 | } |
nyatla | 37:fc4b4fd6a649 | 579 | }else{ |
nyatla | 37:fc4b4fd6a649 | 580 | //自分宛?(proto.local) |
nyatla | 37:fc4b4fd6a649 | 581 | ptr_recode=NyLPC_TDnsRecord_getMatchPtrIdx(i_inst->_ref_record,q->qname); |
nyatla | 37:fc4b4fd6a649 | 582 | if(ptr_recode<0){ |
nyatla | 37:fc4b4fd6a649 | 583 | goto DROP; |
nyatla | 37:fc4b4fd6a649 | 584 | } |
nyatla | 37:fc4b4fd6a649 | 585 | //Bufferの取得 |
nyatla | 37:fc4b4fd6a649 | 586 | obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0); |
nyatla | 37:fc4b4fd6a649 | 587 | if(obuf==NULL){ |
nyatla | 37:fc4b4fd6a649 | 588 | goto DROP; |
nyatla | 37:fc4b4fd6a649 | 589 | } |
nyatla | 37:fc4b4fd6a649 | 590 | l=setResponseHeader(obuf,i_dns_header,1,0,3); |
nyatla | 37:fc4b4fd6a649 | 591 | s=writePtrRecord(i_inst->_ref_record,ptr_recode,obuf+l,obuflen-l,&cache); |
nyatla | 37:fc4b4fd6a649 | 592 | if(s<=0){ |
nyatla | 37:fc4b4fd6a649 | 593 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 37:fc4b4fd6a649 | 594 | } |
nyatla | 37:fc4b4fd6a649 | 595 | l+=s; |
nyatla | 37:fc4b4fd6a649 | 596 | s=writeSRVRecord(i_inst,ptr_recode,obuf+l,obuflen-l,&cache); |
nyatla | 37:fc4b4fd6a649 | 597 | if(s<=0){ |
nyatla | 37:fc4b4fd6a649 | 598 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 37:fc4b4fd6a649 | 599 | } |
nyatla | 37:fc4b4fd6a649 | 600 | l+=s; |
nyatla | 37:fc4b4fd6a649 | 601 | s=writeTXTRecord(i_inst,ptr_recode,obuf+l,obuflen-l,&cache); |
nyatla | 37:fc4b4fd6a649 | 602 | if(s<=0){ |
nyatla | 37:fc4b4fd6a649 | 603 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 37:fc4b4fd6a649 | 604 | } |
nyatla | 37:fc4b4fd6a649 | 605 | l+=s; |
nyatla | 37:fc4b4fd6a649 | 606 | //Aレコード |
nyatla | 37:fc4b4fd6a649 | 607 | s=writeARecord(obuf+l,obuflen-l,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr)); |
nyatla | 37:fc4b4fd6a649 | 608 | if(s<=0){ |
nyatla | 37:fc4b4fd6a649 | 609 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 37:fc4b4fd6a649 | 610 | } |
nyatla | 37:fc4b4fd6a649 | 611 | l+=s; |
nyatla | 37:fc4b4fd6a649 | 612 | } |
nyatla | 37:fc4b4fd6a649 | 613 | break; |
nyatla | 37:fc4b4fd6a649 | 614 | case NyLPC_TDnsQuestion_QTYPR_TXT: |
nyatla | 37:fc4b4fd6a649 | 615 | //自分宛?(proto.local) |
nyatla | 37:fc4b4fd6a649 | 616 | ptr_recode=NyLPC_TDnsRecord_getMatchSrvIdx(i_inst->_ref_record,q->qname); |
nyatla | 37:fc4b4fd6a649 | 617 | if(ptr_recode<0){ |
nyatla | 37:fc4b4fd6a649 | 618 | goto DROP; |
nyatla | 37:fc4b4fd6a649 | 619 | } |
nyatla | 37:fc4b4fd6a649 | 620 | //Bufferの取得 |
nyatla | 37:fc4b4fd6a649 | 621 | obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0); |
nyatla | 37:fc4b4fd6a649 | 622 | l=setResponseHeader(obuf,i_dns_header,1,0,1); |
nyatla | 37:fc4b4fd6a649 | 623 | s=writeTXTRecord(i_inst,ptr_recode,obuf+l,obuflen-l,&cache); |
nyatla | 37:fc4b4fd6a649 | 624 | if(s<=0){ |
nyatla | 37:fc4b4fd6a649 | 625 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 37:fc4b4fd6a649 | 626 | } |
nyatla | 37:fc4b4fd6a649 | 627 | l+=s; |
nyatla | 37:fc4b4fd6a649 | 628 | s=writeARecord(obuf+l,obuflen-l,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr)); |
nyatla | 37:fc4b4fd6a649 | 629 | if(s<=0){ |
nyatla | 37:fc4b4fd6a649 | 630 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 37:fc4b4fd6a649 | 631 | } |
nyatla | 37:fc4b4fd6a649 | 632 | l+=s; |
nyatla | 37:fc4b4fd6a649 | 633 | break; |
nyatla | 37:fc4b4fd6a649 | 634 | default: |
nyatla | 37:fc4b4fd6a649 | 635 | goto DROP; |
nyatla | 37:fc4b4fd6a649 | 636 | } |
nyatla | 37:fc4b4fd6a649 | 637 | if(!NyLPC_cUdpSocket_psend(&(i_inst->_super),&MDNS_MCAST_IPADDR,MDNS_MCAST_PORT,obuf,l)){ |
nyatla | 37:fc4b4fd6a649 | 638 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 37:fc4b4fd6a649 | 639 | } |
nyatla | 37:fc4b4fd6a649 | 640 | return; |
nyatla | 37:fc4b4fd6a649 | 641 | ERROR: |
nyatla | 37:fc4b4fd6a649 | 642 | NyLPC_cUdpSocket_releaseSendBuf(&(i_inst->_super),obuf); |
nyatla | 37:fc4b4fd6a649 | 643 | DROP: |
nyatla | 37:fc4b4fd6a649 | 644 | return; |
nyatla | 37:fc4b4fd6a649 | 645 | } |
nyatla | 37:fc4b4fd6a649 | 646 | #define CTRL_FLAG_INIT 0x00 |
nyatla | 37:fc4b4fd6a649 | 647 | #define CTRL_FLAG_STARTED 0x80 |
nyatla | 37:fc4b4fd6a649 | 648 | #define CTRL_FLAG_STOP_REQUESTED 0x40 |
nyatla | 37:fc4b4fd6a649 | 649 | #define CTRL_FLAG_PROCESS_PACKET 0x20 //パケット処理中の間1 |
nyatla | 37:fc4b4fd6a649 | 650 | |
nyatla | 37:fc4b4fd6a649 | 651 | static NyLPC_TBool onPacket(NyLPC_TcUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info) |
nyatla | 37:fc4b4fd6a649 | 652 | { |
nyatla | 37:fc4b4fd6a649 | 653 | NyLPC_TUInt16 in_len=i_info->size; |
nyatla | 37:fc4b4fd6a649 | 654 | NyLPC_TUInt16 num_of_query; |
nyatla | 37:fc4b4fd6a649 | 655 | const char* qptr; |
nyatla | 37:fc4b4fd6a649 | 656 | struct NyLPC_TDnsQuestion q; |
nyatla | 37:fc4b4fd6a649 | 657 | NyLPC_TUInt16 s; |
nyatla | 37:fc4b4fd6a649 | 658 | NyLPC_TInt16 i; |
nyatla | 37:fc4b4fd6a649 | 659 | |
nyatla | 37:fc4b4fd6a649 | 660 | if(i_info->peer_port!=MDNS_MCAST_PORT || !NyLPC_TIPv4Addr_isEqual(&MDNS_MCAST_IPADDR,&i_info->ip)){ |
nyatla | 37:fc4b4fd6a649 | 661 | return NyLPC_TBool_FALSE; |
nyatla | 37:fc4b4fd6a649 | 662 | } |
nyatla | 37:fc4b4fd6a649 | 663 | |
nyatla | 37:fc4b4fd6a649 | 664 | num_of_query=getNumberOfQuestion(i_buf,in_len); |
nyatla | 37:fc4b4fd6a649 | 665 | if(num_of_query==0){ |
nyatla | 37:fc4b4fd6a649 | 666 | goto DROP; |
nyatla | 37:fc4b4fd6a649 | 667 | } |
nyatla | 37:fc4b4fd6a649 | 668 | qptr=(const char*)i_buf+sizeof(struct NyLPC_TDnsHeader); |
nyatla | 37:fc4b4fd6a649 | 669 | in_len-=sizeof(struct NyLPC_TDnsHeader); |
nyatla | 37:fc4b4fd6a649 | 670 | for(i=0;i<num_of_query;i++){ |
nyatla | 37:fc4b4fd6a649 | 671 | //Queryのパース |
nyatla | 37:fc4b4fd6a649 | 672 | s=NyLPC_TDnsQuestion_parse(qptr,in_len,&q); |
nyatla | 37:fc4b4fd6a649 | 673 | if(s==0){ |
nyatla | 37:fc4b4fd6a649 | 674 | goto DROP; |
nyatla | 37:fc4b4fd6a649 | 675 | } |
nyatla | 37:fc4b4fd6a649 | 676 | qptr+=s; |
nyatla | 37:fc4b4fd6a649 | 677 | in_len-=s; |
nyatla | 37:fc4b4fd6a649 | 678 | sendReply2((NyLPC_TcMDnsServer_t*)i_inst,(const struct NyLPC_TDnsHeader*)i_buf,&q); |
nyatla | 37:fc4b4fd6a649 | 679 | } |
nyatla | 37:fc4b4fd6a649 | 680 | //パケット処理終了 |
nyatla | 37:fc4b4fd6a649 | 681 | return NyLPC_TBool_FALSE; |
nyatla | 37:fc4b4fd6a649 | 682 | DROP: |
nyatla | 37:fc4b4fd6a649 | 683 | return NyLPC_TBool_FALSE; |
nyatla | 37:fc4b4fd6a649 | 684 | } |
nyatla | 37:fc4b4fd6a649 | 685 | |
nyatla | 37:fc4b4fd6a649 | 686 | static void onPeriodic(NyLPC_TcUdpSocket_t* i_inst) |
nyatla | 37:fc4b4fd6a649 | 687 | { |
nyatla | 37:fc4b4fd6a649 | 688 | |
nyatla | 37:fc4b4fd6a649 | 689 | if(NyLPC_cStopwatch_isExpired(&((NyLPC_TcMDnsServer_t*)i_inst)->_periodic_sw)){ |
nyatla | 37:fc4b4fd6a649 | 690 | //アナウンス |
nyatla | 37:fc4b4fd6a649 | 691 | sendAnnounse(((NyLPC_TcMDnsServer_t*)i_inst)); |
nyatla | 37:fc4b4fd6a649 | 692 | //TTL(msec)*1000*80% |
nyatla | 96:e6a0db86988e | 693 | NyLPC_cStopwatch_startExpire((&((NyLPC_TcMDnsServer_t*)i_inst)->_periodic_sw),NyLPC_TcMDns_TTL*1000/2); |
nyatla | 37:fc4b4fd6a649 | 694 | } |
nyatla | 37:fc4b4fd6a649 | 695 | } |
nyatla | 37:fc4b4fd6a649 | 696 | |
nyatla | 37:fc4b4fd6a649 | 697 | NyLPC_TBool NyLPC_cMDnsServer_initialize( |
nyatla | 48:00d211aac2ec | 698 | NyLPC_TcMDnsServer_t* i_inst,const struct NyLPC_TDnsRecord* i_ref_record) |
nyatla | 37:fc4b4fd6a649 | 699 | { |
nyatla | 37:fc4b4fd6a649 | 700 | NyLPC_cStopwatch_initialize(&(i_inst->_periodic_sw)); |
nyatla | 37:fc4b4fd6a649 | 701 | NyLPC_cStopwatch_startExpire(&(i_inst->_periodic_sw),1000); |
nyatla | 37:fc4b4fd6a649 | 702 | NyLPC_cUdpSocket_initialize(&(i_inst->_super),MDNS_MCAST_PORT,NULL,0); |
nyatla | 37:fc4b4fd6a649 | 703 | NyLPC_cUdpSocket_setOnRxHandler(&(i_inst->_super),onPacket); |
nyatla | 48:00d211aac2ec | 704 | NyLPC_cUdpSocket_setOnPeriodicHandler(&(i_inst->_super),onPeriodic); |
nyatla | 37:fc4b4fd6a649 | 705 | NyLPC_cUdpSocket_joinMulticast(&(i_inst->_super),&MDNS_MCAST_IPADDR); |
nyatla | 37:fc4b4fd6a649 | 706 | i_inst->_ref_record=i_ref_record; |
nyatla | 37:fc4b4fd6a649 | 707 | return NyLPC_TBool_TRUE; |
nyatla | 37:fc4b4fd6a649 | 708 | } |
nyatla | 37:fc4b4fd6a649 | 709 | void NyLPC_cMDnsServer_finalize( |
nyatla | 37:fc4b4fd6a649 | 710 | NyLPC_TcMDnsServer_t* i_inst) |
nyatla | 37:fc4b4fd6a649 | 711 | { |
nyatla | 37:fc4b4fd6a649 | 712 | NyLPC_cUdpSocket_finalize(&(i_inst->_super)); |
nyatla | 37:fc4b4fd6a649 | 713 | NyLPC_cStopwatch_finalize(&(i_inst->_periodic_sw)); |
nyatla | 37:fc4b4fd6a649 | 714 | } |
nyatla | 37:fc4b4fd6a649 | 715 | |
nyatla | 37:fc4b4fd6a649 | 716 | |
nyatla | 37:fc4b4fd6a649 | 717 |