This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088

Fork of libMiMic by Ryo Iizuka

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?

UserRevisionLine numberNew 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