From bbb8742283f7011919798fa9eb58aa69d3807f43 Mon Sep 17 00:00:00 2001 From: Nick Peng Date: Thu, 10 May 2018 00:26:32 +0800 Subject: [PATCH] update code --- dns.c | 234 ++++++++++++++++++++++++++++++++++++++------------- dns.h | 153 +++++++++++++++------------------ dns_server.c | 4 +- smartdns | Bin 0 -> 73100 bytes test-dns.c | 2 +- 5 files changed, 248 insertions(+), 145 deletions(-) create mode 100644 smartdns diff --git a/dns.c b/dns.c index e1e6d6d..af1dcaf 100644 --- a/dns.c +++ b/dns.c @@ -1,102 +1,222 @@ #include "dns.h" +#include +#include #define DNS_MAX_CNAME_LEN 128 -int dns_decode_head(struct dns_head *head, struct idns_head *ihead) +short dns_read_short(unsigned char **buffer) { - head->id = ntohs(ihead->id); - head->opcode = (ihead->opcode >> 3) & 0x0F; - head->query = (ihead->opcode & 0x80) != 0x80; - head->aa = (ihead->opcode & 0x04) == 0x04; - head->tc = (ihead->opcode & 0x02) == 0x02; - head->rd = (ihead->opcode & 0x01) == 0x01; - head->ra = (ihead->rcode & 0x80) == 0x80; - head->z = (ihead->rcode & 0x40) == 0x40; - head->ad = (ihead->rcode & 0x20) == 0x20; - head->cd = (ihead->rcode & 0x10) == 0x10; - head->rcode = (ihead->rcode & 0x0F); - head->qdcount = ntohs(ihead->qdcount); - head->ancount = ntohs(ihead->ancount); - head->nscount = ntohs(ihead->nscount); - head->nrcount = ntohs(ihead->arcount); + unsigned short value; + value = *((unsigned short *)(*buffer)); + *buffer += 2; + + return ntohs(value); +} + +void dns_write_char(unsigned char **buffer, unsigned char value) +{ + **buffer = value; + *buffer += 1; +} + +unsigned char dns_read_char(unsigned char **buffer) +{ + unsigned char value = **buffer; + *buffer += 1; + return value; +} + +void dns_write_short(unsigned char **buffer, unsigned short value) +{ + value = htons(value); + *((unsigned short *)(*buffer)) = value; + *buffer += 2; +} + +void dns_write_int(unsigned char **buffer, unsigned int value) +{ + value = htons(value); + *((unsigned int *)(*buffer)) = value; + *buffer += 4; +} + +unsigned int dns_read_int(unsigned char **buffer) +{ + unsigned int value; + + value = *((unsigned int *)(*buffer)); + *buffer += 4; + + return ntohs(value); +} + +int dns_decode_head(struct dns_head *head, unsigned char **data) +{ + unsigned int fields; + unsigned char *start = *data; + unsigned char *end = start; + + head->id = dns_read_short(data); + fields = dns_read_short(data); + head->qr = (fields & QR_MASK) >> 15; + head->opcode = (fields & OPCODE_MASK) >> 11; + head->aa = (fields & AA_MASK) >> 10; + head->tc = (fields & TC_MASK) >> 9; + head->rd = (fields & RD_MASK) >> 8; + head->ra = (fields & RA_MASK) >> 7; + head->rcode = (fields & RCODE_MASK) >> 0; + head->qdcount = dns_read_short(data); + head->ancount = dns_read_short(data); + head->nscount = dns_read_short(data); + head->nrcount = dns_read_short(data); + + end = *data; + return start - end; +} + +int dns_encode_head(unsigned char **data, struct dns_head *head) +{ + dns_write_short(data, head->id); + + int fields = 0; + fields |= (head->qr << 15) & QR_MASK; + fields |= (head->rcode << 0) & RCODE_MASK; + dns_write_short(data, fields); + + dns_write_short(data, head->qdcount); + dns_write_short(data, head->ancount); + dns_write_short(data, head->nscount); + dns_write_short(data, head->nrcount); return 0; } -int dns_decode_rr(char *data, int size) +int dns_get_domain(char *output, int size, unsigned char *data) { - int ret; - int len = 0; + int i = 0; + int output_len = 0; + int copy_len = 0; + int total_len = 0; - return len; -} + while (data[i]) { + int len = data[i]; -int dns_get_domain(char *data, int size, char *output) -{ - int i = 0; + if (i != 0) { + *output = '.'; + output++; + } - while (data[i]) { - int len = data[i]; - *output = '.'; - output++; i++; - memcpy(output, data + i, len); + total_len++; + if (output_len < size - 1) { + copy_len = (len < size - output_len) ? len : size - 1 - output_len; + memcpy(output, data + i, copy_len); + } i += len; output += len; + output_len += len; + total_len += len; } - int qtype = (unsigned short) data[i+1]; - int qclass = (unsigned short) data[i+3]; - - return 0; + *output = 0; + total_len++; + return total_len; } -int dns_decode_qd(char *data, int size) +int dns_encode_domain(unsigned char *output, int size, char *domain) +{ + int i = 0; + int num = 0; + int total_len = 0; + unsigned char *ptr_num = output++; + total_len++; + while (i < size && *domain != 0) { + if (*domain == '.') { + *ptr_num = num; + num = 0; + ptr_num = output; + domain++; + output++; + total_len++; + continue; + } + *output = *domain; + num++; + output++; + domain++; + total_len++; + } + *ptr_num = num; + *output = 0; + total_len++; + return total_len; +} + +int dns_decode_qd(unsigned char *data, int size, char *domain, int domain_size, int *qtype, int *qclass) { - int ret; int len = 0; - char name[DNS_MAX_CNAME_LEN]; - len = dns_get_domain(data, size, name); - printf("%s\n", name); + len = dns_get_domain(domain, domain_size, data); + data += len; + *qtype = dns_read_short(&data); + *qclass = dns_read_short(&data); return len; } -int dns_decode_body(struct dns_packet *packet, char *data, int size) +int dns_decode_body(struct dns_packet *packet, unsigned char *data, int size) { struct dns_head *head = &packet->head; int i = 0; int len = 0; int decode_len = 0; + int qtype = 0; + int qclass = 0; + char name[DNS_MAX_CNAME_LEN]; + + if (head->nrcount || head->nscount || head->ancount) { + return -1; + } for (i = 0; i < head->qdcount; i++) { - len = dns_decode_qd(data, size - decode_len); - + len = dns_decode_qd(data, size - decode_len, name, DNS_MAX_CNAME_LEN, &qtype, &qclass); + printf("QR: %d, domain: %s, qtype = %d, qclass = %d\n", head->qr, name, qtype, qclass); decode_len += len; data += len; } - for (i = 0; i < head->qdcount; i++) { - } - - for (i = 0; i < head->qdcount; i++) { - } - - for (i = 0; i < head->qdcount; i++) { - } - return 0; } -int dns_decode(struct dns_packet *packet, char *data, int size) +int dns_decode(struct dns_packet *packet, unsigned char *data, int size) { - struct idns_head *ihead = (struct idns_head *)data; struct dns_head *head = &packet->head; int decode_len = 0; + int ret = 0; - dns_decode_head(head, ihead); - decode_len += sizeof(struct idns_head); - data += sizeof(struct idns_head); - dns_decode_body(packet, data, size - decode_len); - return -1; + decode_len = dns_decode_head(head, &data); + ret = dns_decode_body(packet, data, size - decode_len); + return ret; +} + + +int dns_encode(unsigned char *data, int size, struct dns_packet *packet) +{ + int rc; + int len = 0; + + len = dns_encode_head(&data, &packet->head); + + while (1) { + len = dns_encode_domain(data, size, "www.baidu.com"); + data += len; + dns_write_short(&data, /*qType*/12); + dns_write_short(&data, /*qClass*/ 1); + } + + /* + rc |= dns_encode_resource_records(packet->answers, data); + rc |= dns_encode_resource_records(packet->nameservers, data); + rc |= dns_encode_resource_records(packet->additional, data); + */ + return rc; } \ No newline at end of file diff --git a/dns.h b/dns.h index c1ddc6c..24625e5 100644 --- a/dns.h +++ b/dns.h @@ -1,23 +1,22 @@ #ifndef _DNS_HEAD_H #define _DNS_HEAD_H -#include #include #include #include +#include -typedef enum dns_section { - DNS_S_QD = 0x01, - DNS_S_AN = 0x02, - DNS_S_NS = 0x04, - DNS_S_AR = 0x08, - DNS_S_ALL = 0x0f -} dns_section_t; +#define QR_MASK 0x8000 +#define OPCODE_MASK 0x7800 +#define AA_MASK 0x0400 +#define TC_MASK 0x0200 +#define RD_MASK 0x0100 +#define RA_MASK 0x8000 +#define RCODE_MASK 0x000F -typedef enum dns_class { - DNS_C_IN = 1, - DNS_C_ANY = 255 -} dns_class_t; +typedef enum dns_section { DNS_S_QD = 0x01, DNS_S_AN = 0x02, DNS_S_NS = 0x04, DNS_S_AR = 0x08, DNS_S_ALL = 0x0f } dns_section_t; + +typedef enum dns_class { DNS_C_IN = 1, DNS_C_ANY = 255 } dns_class_t; typedef enum dns_type { DNS_T_A = 1, @@ -58,36 +57,22 @@ typedef enum dns_rtcode { DNS_RC_NOTZONE = 10, /* EDNS(0) extended RCODEs */ DNS_RC_BADVERS = 16, -} dns_rtcode_t ; /* dns_rcode */ - -struct idns_head -{ - unsigned short id; - unsigned char opcode; - unsigned char rcode; - unsigned short qdcount; - unsigned short ancount; - unsigned short nscount; - unsigned short arcount; -} __attribute__ ((packed)); +} dns_rtcode_t; /* dns_rcode */ struct dns_head { - unsigned short id; // identification number - unsigned char rd : 1; // recursion desired - unsigned char tc : 1; // truncated message - unsigned char aa : 1; // authoritive answer - unsigned char opcode : 4; // purpose of message - unsigned char query : 1; // query/response flag - unsigned char rcode : 4; // response code - unsigned char cd : 1; // checking disabled - unsigned char ad : 1; // authenticated data - unsigned char z : 1; // its z! reserved - unsigned char ra : 1; // recursion available - unsigned short qdcount; // number of question entries - unsigned short ancount; // number of answer entries - unsigned short nscount; // number of authority entries - unsigned short nrcount; // number of resource entries -} __attribute__ ((packed)); + unsigned short id; // identification number + unsigned short qr; /* Query/Response Flag */ + unsigned short opcode; /* Operation Code */ + unsigned short aa; /* Authoritative Answer Flag */ + unsigned short tc; /* Truncation Flag */ + unsigned short rd; /* Recursion Desired */ + unsigned short ra; /* Recursion Available */ + unsigned short rcode; /* Response Code */ + unsigned short qdcount; // number of question entries + unsigned short ancount; // number of answer entries + unsigned short nscount; // number of authority entries + unsigned short nrcount; // number of addititional resource entries +} __attribute__((packed)); struct dns_qds { unsigned short type; @@ -104,75 +89,73 @@ struct dns_rrs { typedef uint32_t TTL; -typedef struct dns_question_t /* RFC-1035 */ +typedef struct dns_question_t /* RFC-1035 */ { - const char *name; - dns_type_t type; - dns_class_t class; + const char *name; + dns_type_t type; + dns_class_t class; } dns_question_t; -typedef struct dns_generic_t /* RFC-1035 */ +typedef struct dns_generic_t /* RFC-1035 */ { - const char *name; - dns_type_t type; - dns_class_t class; - TTL ttl; + const char *name; + dns_type_t type; + dns_class_t class; + TTL ttl; } dns_generic_t; -typedef struct dns_a_t /* RFC-1035 */ +typedef struct dns_a_t /* RFC-1035 */ { - const char *name; - dns_type_t type; - dns_class_t class; - TTL ttl; - in_addr_t address; + const char *name; + dns_type_t type; + dns_class_t class; + TTL ttl; + in_addr_t address; } dns_a_t; -typedef struct dns_aaaa_t /* RFC-1886 */ +typedef struct dns_aaaa_t /* RFC-1886 */ { - const char *name; - dns_type_t type; - dns_class_t class; - TTL ttl; - struct in6_addr address; + const char *name; + dns_type_t type; + dns_class_t class; + TTL ttl; + struct in6_addr address; } dns_aaaa_t; -typedef struct dns_cname_t /* RFC-1035 */ +typedef struct dns_cname_t /* RFC-1035 */ { - const char *name; - dns_type_t type; - dns_class_t class; - TTL ttl; - const char *cname; + const char *name; + dns_type_t type; + dns_class_t class; + TTL ttl; + const char *cname; } dns_cname_t; -typedef struct dns_ptr_t /* RFC-1035 */ +typedef struct dns_ptr_t /* RFC-1035 */ { - const char *name; - dns_type_t type; - dns_class_t class; - TTL ttl; - const char *ptr; + const char *name; + dns_type_t type; + dns_class_t class; + TTL ttl; + const char *ptr; } dns_ptr_t; - -typedef union dns_answer_t -{ - dns_generic_t generic; - dns_a_t a; - dns_cname_t cname; - dns_ptr_t ptr; - dns_aaaa_t aaaa; +typedef union dns_answer_t { + dns_generic_t generic; + dns_a_t a; + dns_cname_t cname; + dns_ptr_t ptr; + dns_aaaa_t aaaa; } dns_answer_t; struct dns_packet { struct dns_head head; dns_question_t *questions; - dns_answer_t *answers; - dns_answer_t *nameservers; - dns_answer_t *additional; + dns_answer_t *answers; + dns_answer_t *nameservers; + dns_answer_t *additional; }; -int dns_decode(struct dns_packet *packet, char *data, int size); +int dns_decode(struct dns_packet *packet, unsigned char *data, int size); #endif \ No newline at end of file diff --git a/dns_server.c b/dns_server.c index 93c3177..e248c29 100644 --- a/dns_server.c +++ b/dns_server.c @@ -51,8 +51,8 @@ void _dns_server_period_run() static int _dns_server_process(struct timeval *now) { int len; - char inpacket[DNS_INPACKET_SIZE]; - char rsppacket[DNS_INPACKET_SIZE]; + unsigned char inpacket[DNS_INPACKET_SIZE]; + unsigned char rsppacket[DNS_INPACKET_SIZE]; struct dns_packet *packet = (struct dns_packet *)rsppacket; struct sockaddr_storage from; socklen_t from_len = sizeof(from); diff --git a/smartdns b/smartdns new file mode 100644 index 0000000000000000000000000000000000000000..afbfbebdc80e94ad5e1bacee7a3d43035e5778b3 GIT binary patch literal 73100 zcmdqK34D~***ARdd+u2?lgwl$Fj+_@5FmjN28j|vkg$U+Mnt8G0+L|RKvD>cN)=fY z6_tn!ZKI?vRS{e2!&7NpO4a(^%u30}~$*L9g%gRQVx#*cu}RrY2(MiyfT#XT0}#R|f=?zsQGBxS>4#5$eE1hv z57|Zo04MD9AUuok8EU7C?Pm#|!)%z3;rNu==@EFA;nV*87k@eap|PPe*8L#k>RDUg zG6sEi&(2Gurym%8N!B&TZ`;tEdF;MJ-@j$U4!<}2`;ukzM$R4o_pW1GVig}=pLgq^ zpZ{#aXI+nd@2`=J^L{WcEKOOwXTh30)`1gB<4$M0J@*`*8I1BPT zxaZaHMJ{jMQ2*ihu6{??el_0vvNoZug|e4UBmm^=1_aDB_0)d}026frPp0p5q-pnC zjh+mq<0mV+LMC+=alk~Q_^KA=~ko{EJ6PS zuLwM-I;H&Cl=L|%>GM+biKNK$ZVLYSDd~q&>ZhfYKarB=c%c7ipW2l4=9Ki^De2Qv z(ywV^c#__Rl=72P(nC_xFQlaNQ_{alp}!<0otc8aA*Fm?O8M%P@;xc#Eh*&!V_Z{n z{i?bpwH(`$V$sa`a~9Rst*X0d`ReAnRrBXeZfIOtH-E{64RvDCX=@kFvkN9SELpv} zZneVi6MJbxi;T*uty|r^s`1ipdMZ~+ z1O1m$^HaoXu&-+t_05ed8|3$DvASv1@|DfY1ZuBbx}r%mfpOz1QPUOX)y+#*H7{DR1a^i3^{XW|jJtIG60}y`dT6(3(M2m7 zSK641#Pr!SCrw^-QrXyUh~Yu^pNZLy|4jT-(23u=L_al#PFvmenWH|81TekJIXek% z*~^z>s0a$W9+eokpI# zfe`obiQwjbKJ$dw%jXaw_VI~;V?Un=CJyk4;KNrv;+^jc@vd*<<43Ia5uH~1?#}e~ zo7#QHpXi)%7Fz0=n+|3DZu_Abe|xM`!_^MB!T~28aIphUIN-Pg4m)6<0~QYW(~o=j z9(TY;9B{h>e$4^D;DDcXzy}@h0SCO#0pIU{+Z^yN2fV`pZ*#yK9q@Vw+~k1k9q?iY zyubn1IN%u$xY_|%IN+oME_T2P2OM|6VF&DUz`_B4`jNx_g!#9x?XYNXJ8XsTcr%n} z>#!2=8!@6Yd~kQCb#O#yQ0(puCUl4 z=i7+%59fD{H16)|I{GFi%*Q}J4>)pE3w}g==6l_GhMs}Qo@nJqb{3{CY z?kpmHcw+m+NL$B`3a)DZb$DL~>893W9bGRB-;Y<5&&!f_c;n;ozd&9i3H_2!cOrdc zA@GZ(EIT9)*yS98tZ`eOFS@z{q%#^ag{vPw@+Xu9u^!@|wQoeH*muLB;0tpO`9xZ$ zFPYovOXPNn#O7|;0*v0s+37+%2E&j~llO&>nnS{Bz@(*uC5%`O_f{AoN(APj`qz%ecH)@{V;^*e?5Om<_x9xn-pjdU z_g_7i41JIJmd-!#zrkzV$ut<)^&ox;*W#ZzN`Q98Wyo5vQHQxt$g8-wTWHtIw(Bhb?iR>{>Hg@cp%d{-Q}9cHzaIFI z@F?36QsdbU9ediF@kAUtgu{j?#dC&3pXzk+F6v4DpucN9s{-QP7V!TFGD~|n%Gh?~ zMPErIXB{FhlRjtXVQN1b6m5r>(5|2z1|EH${nUs4Ksb?@b;t}WzWq^G`c@LYW&4pI zcKvHt*Xs%3(znt;ll~L~%yx|98JA_~zo5f$Dh__cVLPx6W#gFR67xFVhd(;oxR&-n zoBA*&T>Fo+16SUHx5BVWvIa&&RM%en0H)UX7zS(8AOF5udyqa=R z-kqIZn@*OpOULyiVW&~hH@T^u@><~WHt0#8hu&JRF!VkQy)|!yZPITQFIPMJ3HyMi z{|{Rx(hkC=q@Oq`3f-wcY@z%;K)48bMKVwMifk9qmt!krrd+kK<1_#0dY5^$V=?L! zJLnKDMP6wt9UJFe*tsvAo`+8K58Bp;u{8{Ts&}+OOCN3UA>?2k+6LjAY=h@iUWab~ zAZ>?sSQx>)3fiBeT(<+unD?Y@BW<&NcDk=N+0;jy&=)Z`O8F_v$&h6y{Dpkq3@g5G zfG_jN@5eU%)VAU{#QyNFwiQBe*;Z1oL|aEJoZDHC_Bt25|JC+7+DCg)-)H)0uV%E@ zddJuic8uY(AxBe0yt^MdI>$yVCj#a6nAOi7g4-xv0c9|PGMZ2?ay(CFy|;emO0}d9UpL<(s4_wta=RAu?pvO#9eZ1GdMU@`ZCdM==gbZc=kiA8n&$ru}F~>L?N~ zbsAxOVwhtRS9O?#;|g{m260sZPHsMdrnVvHsyNyw53(f?XK;L$;|b*Cn8>*1<#NX4 zo7%hQDe$Halwl2gGY0#=!f_mZPTD=Wxt(Pk=PY}S!T8o4b3q=&N~+vvm;c5tr*14K zFWQP}S8|f1XJO6=gV+7Ncny+ej2|hJmQ&89c3txFpf3I7`@Q5CB<1MgvnhqvBqayx z22uCAUNR1nWj%Zt|D7mv*p~V7e?jJ`Epx-aATw=6na}?gGIPERCMO@#F{Yd|po`4M zSa)?-*L50peX#rXhtTFt0}PSK!?=Ubkz7MOhtEEIZoy|gJ`3@w#-|7$A3n!&xW3En zOhbD!Hl|;)&2)RQETGFOPAv25vhowl=tGhw{Lkq>r0LaV;K#NiKka)ST?T%sWo}&t zeyL^jY0Zy5=k#ZnE(1UM75VAD06bL>{8GydT?T%sWtx|>Z)tz$8iRc$-EQv=&J*2s znB1!$5tp*0**^IP8&}btEX%Y%6PI?%wtetFZCs`AWLcIf1AU!7cko-tp!@Q_e+wC? z8~g5_Zy`h6mSJ}vGH@P|;|ZR6K6w9$hyJYR1n1oM|F?Ce)=|$PT&FX3q(2}Ak!uIW zUAj-ghq~uc`liH#KeJD9z3^dISLN5u%g(q*^Wc;IB-cKmu^Dlm=Cv>RlANFBd;#BO z{0IMa`Z|4%GU$GLH_GK$4>=G|Uq{?Q=u@i`U2hRyo$Pvx{Z2jGJLD5>e*ANrzN7uM zU3A-X|A{n2a?=TWFZIi?b78M@lbAP)F>e-O4V8ecy5M(=fkM!MHZqe>$+)}-YmNkT z7s(rthja1aXz-fS|01nDnNb#>gItR2_PW~-6J-r6vT7M7o;16tD-A5Xr_jA}2wy;jV zCndgREc;D5Jd&crO?~LFFVdq!rbCCQtwZcyN1|G@taC*h~1cDw5J?(K@t;bN3kp?$eltj3e;$Ruz}(ayxJfK2x}WWx4) zU@`12s&{sNPv>(j3Hx4Tr|Iw2VeF40Zzc2aOwtG86K>Qu&>l=uuep z>3mzaq@AX23vAuSFb}$w+q$KpK8{Wg|@6oC#btR;zO6&6PCO-i=-(Yn^q! z>|PVtbPjx}cxqox#cP7k|LHTeb|8<(h>w0s+jDKku|UVL?I>efubbaMnr%Z{aeU-H z^Dk^#tj~Q;`shLArS_?sTHKAX_g9M0P6_xRTU>=_IceUTwdtZe< zbIj3CzRCXDHcq?eIqcp7UesB(g~QgVcK;ai?;H4%v}a#7pXt!!>uf$7INIie{)x@M z$=2NWT@G5`WbYZay=!c_w7n}Gau(b6p2)m!u=irvTiaasKOG~mjo5dTzwhkcf2LpE zhP4al7w%2#@__1BIV>-;%jJBHeDp=xUm4F3-#|O8^lHc)mlwO``l!_)H9ZIqtChBGB%a z-gbDb)R}80d;bn)7ozO*2`V<|SEgbJ+WmCe3H3QgY=plg!)hL%t@FW;K13Y$8TuCC za=`ll7vWisG}jhpqU}eRdw$09y*Azf!7~8R2=A0~hB^Kx+B)9=@xm(#4wT*~D(d_M5xUEjsPkC1}?vMV;^3b&RUbhqw>GdOK3;y^4D4!TWydggTkD z9iBf^V?D7(oi^i}Q49GkSyCV-!fdb%y)3jxyVqCP!%0n+^e^5|c*jgF@nmpJ>Z z9uG-(E_4Xm_PG&tX%DXVD{bA{p^vi3&2Kw>2EG{}Z~8ywvar{r=VgxlxC$fJpW1iW z7UcJ5DW8hP7;CCnY$sxbo;ZQD87JtogjCvkZg@+cZ}slu=tDW&YoBe~fqf{B^bDlg z_g8Zd9({`T(c_!8PwKi+?(I@H_#wv>#8kMz_HpbLJI5jVdTAK(eu8neI+N1v!nR=FvIBG8m$J80VdRoa+#Wd1kVQTh1hLtK+l_M)(|<3fiW*-o@0pW2S9 z?RIv`^=Z!@#6Pv8bIxW=L;vPI6Y5WYjiGHg4`JSv=b3UZ5Hhjf$USGQ2dE?NN(8v) zqw8=EV~jyNIqU3z9%xfp2W^nU_Qg|;bM_de`=D;))VWr-FLhSq|5I|T=l&A;a;%`t zTzAUx6LibLgY|T~TH(!yDv(a1EltsO_>sSNy*tdt(QVEBWc~&>>oLtxAhokj|l;`YnbyEe4Jy>WvIh;CqJ$^$&33BZpb6^9kMcB z+)f^x7eL!NrgwGWj-F=6a>v*xmX5-_+d0*ye|FPXO~pA@;qx=hmCw?rtBu-Psnp zPf8uYi+198kOw%7@`^&NFJT9cVQ`Qf<}ps#Thv=7j!&;b2DT^Lj&l=ngB-6wPu(F< z{zjN>#_=qbFYB;A&dw3$Dqo)uU%4N&b(!i5?VK~DjPz@+X`Jn}A2Rc-opX9v^`l#RT$fyWAHtR&4-w;@4XC0+%pAyJ|Ee3nDiS2F8FI1F^<1+IBz6Io{*WK#s8emH8Y$ z`PAblVa`KSQsyDZDCZ%T>oy_0_iOl~9j{~ioQhb9@mdl#PqMCUFT&-><5-kxFUbRV z==a@zMqgHA$eD*9Ou3_=@ewD=adragwsdvD{KD}k;?l>sX2aUyXyFKyCngU{PJ`GFG3ID{VocxTq@nxETOW75dmOgyz!TTZRX+uPtp9WR!haojxQ>0aud> z?T42@pB)%GXtymGU!H`n73lAz`)`0vZ``x*#`5Qnon-G)9m}z z@CVK(cOs8_D@CYd*nU|NW(?VOm~%t|e7^@A=bXhD{x%!qA9#=Sc90@BPTam{# z3-x#n?S2Mv0KWiuF5qgw&jK#QoJIH`;C#Sb@6rB6i0Qv;)8(G)dgSjr=}9?n^DZ6t zXmlKbaUU^a+hNA9JloNIjr*a*;TWp>$wtuBz6zVmHQsH=s{sEzJb4!~NAhj&H9xQ& zeHdIgPn2Sw*l~&>Y5~u%=M3(1)YsxuhY`g-|Kiwie;;zvZ+AH4++ySS9CDrw85)pZ zZ2JfL$?H7BVw%3N9ObhmjrPOE@V#ol+qq6xed_h3ohI%Dz)je=+p+eKL&uJf*uJ|v z|AHsSI_j`m}lkQYoM@92gRdr>cz@tl$Vt?=IOg~vFp8;|!C zY&@`Qpw4LP}IA@_|i-?9%MjE7@ct9WnM~Y&l4G2WtID2|=TICknNGkaC&(^DC1oA@zgbq=nznfZ z_xiccS;1H<(bhq^s4M3l$|2hcI&&VPZOvrcC|9zrkiJNt)&8j4CXT-3Tw~D}8DrDO zcprmf3;A7duaTTIbS#$#8r*{_K+2<^uw?*MYX>F&cUOSz{c@r!MI z_*q|fLeIkAX#8d1@9X4k`Wkr`rpU|r;hW^;9MMbOqJJiv5Ti#6k%8aQ^(h8s!`ZPOu;HI0vv#ImhNC=F*`3o12e~SsgDIVx3YAoEqF)1wZ0% zV_PFn^*6MqZhQ1emIq(J`TW=X4oA;v?3=P3A)}HXVDnV{T^)>eOKoH zls!)^7spqpef9WqAMVcYGI38OQ|))$a#C972KYy*v9q%fasR!zm(D$o62#hiZ-aM- zJ3i)@M_SbF2b(hXdU3W$P$+|0Iue+S}^}1`az3$R9bUe8UzBUDW3*GB)z~6S= z#e24zZeKjP?($*XH3{~2uDhz?m%mA|JJ(%K8k`Sh-vA!hU7PVtU3c|`zX5oRBl;>^ zgEHM;xbB){+y0-eyPUN2x@$3XPwiK7E_1BAbbPPZU0laer#+BEuekI%<1c6 z?KFMe7g1}XYUB+9pW_^t(T4O@z3w`Kv776p0^p>syPgI`LJMIQIT zs7EX4eRN!{uWkYS1lGFE;6pq6cy|wWvIpv;i(N0iUuGxQhAqUF$Qp8p+pKs67o>;Elt#A)`vcpJuDW1QOeX5VKl zyAi&$3wz{mz~&sYwie7fl!@_{`*i$p?$BvDE+fr0<{VOkws879=a5}&JNW#i(vN!P zkfnB-{c3$!`TWIpThiZn{=3!wT@}X~?k5hkg!EH+hZcEL(Ej@|KF9H~@SZ8{pT_IBFNw8=QOP-TGS2KK_uBu{`N^-z zuSm(Kow#mV4c&BIV;E>-kC3=YJoO&2&M!uu#wCuPuNGn4?a7aJ&s#dLJQ?k5!+6!# z{;_l45cACsRyk;O^G%Uw0merQ{$S*&IV@rC9r8Cww5@YIOtef_tfv+7bj?26*urcOF3mgnz4qK18pepgH1x2))RRF;wxS%9?-U& z4;!*Q7vR~1&o+E$U+u#@yOv|Rw5QrLujP0GJ5XlwV>!=6XWFsb6pRypgUmX1dkZjQ zw;agioMX6Wo(Ec-W7>g(_Uc}z{LW6()?bFz9P{7Ee}7wp);{27CZ;C(deGVNb3jd3Qzcc{3*CUIb%9o*_*IFDX|_`{*`q0R-1GwaA+fLqjdKG!}`SbClEjhmEcuo8IF0{*je$Y10 z;qx+JJ=byHS@SCgtmA6f<#oniYTRt=cwF)(F8T>{<2hS3d4eC`89-j7uj#T+>HR+G zOZ*Kd?u59or-D7-?%%6iE9F*eO8VidF!yHJmp66@{5E1B_B2-E9yi;8zy0K$W70E0 z>u#*|xd)@~uJHGzX5zo)U6%EUCl7B%IeF0!%*3y|>#a`y6u+I}Z)Vu&7F@~P`` z-+3eJBEPS?7Rsgl@ta_@tt+*zg}U5l?5i&JYQC|qNxtyozUu1zaEz6TFYKiDkzedI z!Uo3Brw+T4_-$WF=I zt)sJU_@C4blkeBml|EqG#Fc!pGXplsux;Y9ZDPR(-F^7rk-w^bN%;z z{*|`>^4Qn==D*VRN4|mHw{3g9{_S&(jrO3Q^tJ9!J)fgbG3Mfa72C1r-0dZdVLkDY z8!-saoXQfMSD%vSPu$OCe9L;>d%F%A^7qVG7xIqnZs^RhlJkb%yC$s9i!>c4e~$5g zL_DwQJIlCUX1)tDIP>*+MqmA82j;^ai1}^_tJsoyZ{xiHj5)W2b31oH&i!0#07vG- zhBr}e@&T-4F5T}^ZOOZGluO%`Pc4s*XUUWA524=57L(+C?mX~*8N3-^(Qa~o9Q*mK zM_8Y8^1hk22Wc@r>9b!!Cnfj14!pZ;r_Ia>$DFXpFZLp(bU#4V=?Y= z*X-`}EWWATU4zf!Y3;^F%&j|cU;o{%cc(4c*Kz!s$9}A~grk`zte&H23 z%i+7$#MvF6z|Vnqq|IfBUHI@FY+Sd-6MQGeP34S&8r zk?&6AdoTx&I%RcbVs+hj#}BSe@I|2G2bYar7C14#aZNMU9e9T*UhsB^9%Ldm5#M&hdYw9W!1jXQ5A(kh`BazVA ztI3n^RZXm30mh`$%~qT*OW(s4wwxrND)a|BCE?;b`Nl?yjVQbq7PatLcDT|jc zt#c54^P#RQvAR0p?_dah3m^XRyZZwGYgy5X9TdFpO}ufQdRIN)JCF6Je77|(&iatX z9bTFK+gDwU`wc^2UKAA`L%wsq82y$yO~fFZh9~xP1nzIiKkUf}v6yeZ#RL4X$12~& z&Udd@`3(t|;)ydMSr7LngsBI!)J&tJX!ZRo|hs0Kl{h`3+o%_v z8oQiy_-E6}&~$vr<8S<@Po7+vD4w@ub<>5*m#j>jQZ~9QIbu}B@KsIAM-8v7yKwB9 zQ6(xjaZ+;BnB>W$P7xE?ahB9Axp28KiU7J#5gw1v@EZX$(~24~Bg^RTiW}KRj+ti+ zH0W+haSDq69s%xKL;m)kDt`gLK2+s1`WYfQSeN28rT|TG3r;On`TB8&ctPudGF5)( z2wgs75?-ZqLiwW=y1ZeAAvS`W{!{haVM#^**crIe=O}-!TQbYo4@H72QS%a*)v1VS z_-;i1Fir25d|2N5fP}|gd>Eb`vdq01)m@ew@7orp&wUs)OrQ4-pjd-YVvRYQ;K#tV zHeV*|yD=dOYX$_fw$#cT?@$&$&9Cc;WBr`q4Fuhm$D&_AmfMl(CG7izU+(-vc=!{@ zbtiTL6#fzrb{F0W&=S7W;Z{D+7%%etbCKm4d%8s8m#31jB|H{s1c;MnVbm1f@NmGv z2k>PCgCLDlv**b-$``tOtOLZs^+9a1TzLx^_^CpS#Z9zq!G2mLD z`zK;RGV*T(DE#B_rC>{VYb7y$`!)mLG729e{yxCQz*mVce0Q?c82lm&B%vX)z+Xv1 zL;eS{L5S5nmilIKh^G1oK>Bt71tOyr;spkpT@vp>a}|hM;c>1lkq+;3s(abD>P|LuL#ACXfq$LK>ETEr=nV!2nYSYA^f@I zWg4*n4Q2jM*bQ09L{I1w>OQy5GXMGmsSkcr~RwM>{YQ5vaZ z!ZPq4I+2VFAT5t^42kl{+br=Jl(r&L#FC&)R7EN%O1jaAlIln)OEQg8B&I}8C)21g z5s7J$G<*kR#)rV39vO&^6O0=suxCW7NTATT3J5ikQr0Ok9zbG2WHb}QWMW~Yl8NCm zu{gp>C|D{JwUHT2lo``upZdsLT4|(|ts%0I;*2tUcr=Mj&Q`(Oe4L4Bx4-LARx(?fv!5X5 zeQbV_Z0)>^XaV1=X&Ec^) z-sIds#THTERt$k#kY%)f3|y)IlHU4X*h~MV4*hF;>0hVye--or_2}8yqvrt>^yq2h&mZtYU-;CsU>>w`O?eJ)&3pk#qxCY(5V_x{^`_D3VAR}q zXyWM{rr`%{xEV^+ru)+7D4g!l0s6luQ;JmWpysteoG6PH z_dlQP{T$cK7BQd#G;09IS2d#p1WDLzX~LJ!Vjx^JpS7Oj%ydhJAvWM?w0<8*gV;&U z=WOorwZi-_BGJrCh537x-y{ZK071_J%dBGY!A{&XvyY7)c#%oqJ9Q$*uG%D=6LL9_Cp(XA@1K9E0alK%mWuM+bu3Y#o=b&#CPO{nnD3&%WT@xc zd@FG*8S0q~^?X~dlsPigGa2gnt|yMkP|tS*L67CNo+FY9^?ZcQThNHU$7cfc%c#$v z&qY>%QJ+8Y6J(13qdtG(F92G?FQdM|m=Q!`)E5{_Y31?{FK!`>P{|^VG~xs;l1>Ys z0XQV1zEBXPu^wd9mlox0YW^n%-?XfY0D7$z_)g!BuMGLcdKsjeaXX=>0RibHeEV4L zwGIOeTSofBNCkd@Rj83c#{<<*V0t5b2l7ouk-^s}iAzP1W+A$FD9M)c{hk?+naD=0 z%xYdseY4n1z*Eu-2NS0pa;6U)LvSk^BYl@-{d0oPQb2QA5a4eo5&S6xO8=ci__ZJQ z7+izg$ZQZR$|(L72xsEG=^|s81Z#ktF`O+gqHOEmqdayWfI-4!m5ee*to{e!$yUbb zj{pZIK!J>t2~ytI@ic!;f~OG7vNEO(g6f%a(h{c%JmoKHYzula(J!B@!dau8>|`5GG0S@HkA$!H2)xrpFvIz z!}Q2l2{KHNOs7ma4AUdCCCFhgQbW*x6{NAO@dc1QcfGL2ABFco8OD)$zl8y$zbE32 zNQVv~ZG>`RA~RHsdalr7+B&oV`R>r!fIXp`(MW*-Tk#DlBL4tH$J0C$l```tA>sc5 zU^u#GHz)@7LXYTP5*LBrAwT*MvrW~$KLsdF5Q0~N;Kt}9?X2_>SVw=MDy>IbM1RR_ zGw>e7h(1aW+Moy=*90y_DH<@APwo8ABio7<#6Tu+Gn_S6NJP}7QxzdsG97C7^;pS& zAuIGMh>Or-P%%O!fX&cWRJB6);@cD23Ie{+bZ8I^od!EZLQeqh7rGDP4G5hFBNT?d z3tdY>GvR(^q0<1546OjQlS21~@k@e`7fcq0o`jkggysOgFq96Qi$aaaX$Vz<+Lq9z zz~2^n5%9I4w*hzM|0li$!X4R4v067+hhAk~XfbFE53K{|(oh$8R)%889~Y{@cU5RK zzONDHjbI&H_ZJu?D;#^J616jL0B-D634Wip`6JcI^bzs(a{-Dd#}{TwD`ki%tFuI= zy&_5*U#!zE;SYjLIQG(JWCiXZoj1Y&VJ{-(yaFv_oh;13{<(;~MbMvv+;HsuKLHN> zn%N(y=AKCG52>aZc#ioWeSvQ)Fbr0T{hjDO5lwC`6ol(KSW z0`$KEcD{c7ccNC{a%A_5PXQ=$FK)(v@4jt|8*kh%Dn{tLlfs9Ohtzvo3CH~ z0i<#p>Q>^vU?OP|_&bRtn9Zr^Ts#vN^iA|1W0pgMf^3M(Ys@QU?mjnUnLX4f}cak{^QLjFldAe9tGq6r%Gb6f<2@*!F&e9;ss4iRGXDxlLy|H zp_bQr0uuO-L#RZ&@H;389EV572N8sO(16PU+Sbpq;=^|$nR!2vMo91}@Qat-&D>wY z(D9M~#;UR=Gi6Pr=~yh0X+t^QQ#uXD`T(#mK19Hm1H0hp@nX8B2&{o<@e;yD;Kz_P zK8%#iz>DOSq->TbT;3#N*_Yggx&yC)m9kf|?JO%#4DY+mBa}I{+o3-(shG@ zMKFef!@|E8qWE$)KMHz*w*lvDy&4rnpaN}|b2VZ3$qE!$IXAZx=?Z9*bIautDM|QN z!lv-QLp5`L;0A7BJz6oRRUv%_gXG*{BgH`0%4s`=Nbf-IoVzG18kDT>RyvzhoK)taU)j zHJK7TPP&=5!mc?_uz@r0CaGUZVGJT1WHk|`eo;WSzxj8dMqbXf3y~Fgi1J^rtnmop z?aCTc3Ev>C5$GV_AJceN;34Rr^J~h80f>F4K@-Li#6j3RH^(61?4dAoZmz-3nmvd4 zc?Ku_>?a8qDx4DHlqejI4Y|W4j$dx6<$W*;o)qAgTHc2wBLdt~%lm{}tpK;w@;)W( z3vf#x8pa?LC%e#~6S^+Ks^6sKJd>Ae(kmt4b zLj@UNP;A@dycV0X=*N&C`(@S{XIzhr><>JTLqe#MyQ*%P@DAnTO$72`2yZbLNmk$vk}e?}4BQC@-eFWM7T{iq zx0LF}1Ke)$jv$%5T`vR*7 zmlNI}2t!=&$qb|q6yFAGc~9YtUttulL&JH;P;2b9O1~Tc($X)l6hl7(37^|r$xV~o zRclrX?>N$f)$qTZdaGKbN`ug%-tk}=U z*rX@D#x}gpY%a&1rPOLx6cicsQ8tQ=bE`>_ z%$CJ)hmTKI?$Eo&?BPB%%84~*fClvBUP*ElI+?dlN?m^vmSj@b^JAF)q^@;RS69n( zYe&ges57|%gjQKw%2?lfk=D1Yp59e&vZ|})<#lD}xshIOvJ)e{wrnGZA8Rgu)5=>6M52-GfNS?{QKV7O=4x7XLaPP60Qp@F_H(f3_%$C{Z za=@A{mm+4%jB+_;gJ{8GR{9wQKg+xmMum4F$7``6 zycTo37MGb`i%ZtzE_Ug1sp77rAsCPtt@}YxwST$YV9n*SealT2p_7f0t*`1qr}8^E zY?VvrKvz>LPBx1mEEv(Q$tsGJE*aH~M1x9OUfNGHO1Bx!E^nh1(rrdF%Kt$>QuSa< z#VFloR9%YokT-0S45TQN(?i6(QYLH5${^pT+~SECeC z_2@d%avvG&R&bp%DaPLdDL?BWu0mg6)$npdPPdHs}vq8b?YD3j{l0m zU0)m|sR8j-Th-=L9{YJ;lY0(ulF^T$?iBER6C71P{F9*u%ZA}cP}b9P|757atR6kL z6q5GzTwSAf_!Q)ySYt8hSDZ~9H%ob+#Xk89aumaV_+@w0&9=O=%Vor&5ZO^>9J5)5 z)a6qKPTk2l+uWN19=d1DTIy+fY z%E0J)8+W1V9=|cBzyxYyc*rhVAd=IeqIaQ8zgcXEH)WGe%!Vr8?J41eO_CSb^_t5T zu*DV`M1K!o2)&bO1rFn+Xm6^1yRbx#CU4nYuS9mex9y%+C5OKwB!ON!UIt75SO{^&sV~tLUu**5 z?Xu~f=_dT5BHS!a9mTQc`5C||mN-Ydah}&Wl^zZ+50k_Efrj{4;!VeOz;SZwd02J8 zDJ4TWPVML376y}&4Gb9mT{-NG66vr%S3))@A)ome#6)EYg={6>`a(mzA&LK6H}O`R z_&6Ezw<-eF2~p|TM0K4y*F@k((U5^Z6l)GP|N{>4BotALZR#c z`wH+oZrPw$cC%Te*vv2C=AU;-wd~Fd6w_sjDgWyq#q=W9bG!Ke04b(TimBDj^d`;J zBdSj&({ne1X;RscOl2dS%Ra@3eBu!5GM9UK&*kH0g~W3W0N!r8;aq~~&Xc4^&EFm#4e0@IyEQj_!1zdQr$L9td+oC-3Na96`KkPr#3z6^<(C?vh* z!c(MR4Eq*WAyejqjQhD7ARHT@Pq42i6`o+bpHn{2P_-0xJ20d@w6)>(s!w57E|6N0OYGKt9VV$8Zcwsl(1TA!a zL)9h1nn$v*5$y6h*iHEriA-R{B5-D`WwhQ-&P~Wxd>g8`-nS+)o6>qM9z;zUje*eh zG;6-mUxlnj>q|fx_Zi$o70@C#!3|wcYm1Dz3Hattvk6riB(o?Exks&Jo;_ENs%JvA zYkiqK_SB1lW-;{!*v8yqmZN@^tUt!Czs0WKEXG_IG5TumuVhl6N$1x zS1GFmn)yAG2d9`%#FR(a017AEgZ+E+96^-FbdZraE0_GL`_q+cEATjx{! zUUxU`+nR1`B8ogbeRK^pcK~)0~`^Gr=wQj%!!Gev2>O;`ATLw%+*`Q@qV$0kPWt=%-HD;f)xG!hMA zaBz9;dSTAAX{1+xc?}3;yhmDdRCayF9~~)(>;Ho33YJ!b(_?rVtzF%mDtd8}Xx*GD zHKz@zNC!}yPVL3XPLWeS?J|<3Uyj#ynG6FeyNv8*7m3zwm!!=J`;w#)WO8v8d;?8n zw7yCjvdw~uMy+bIkV-8M{fa7v6pe+U#caWJm0A$`m}PcK1i7zahE-W}`T>Yp-mO=O z%5G8?v{M+kBBhYYkOH$KA3+7&AmqrWGU<8T^f5-sp#>f;vN7#j;$=*O_DJvyNXXkf zlhifv4nL$)w{cv&)Z@w@1G1Lt>Xy36W2un>kGo`jr|ns7>#H5b~lnVHa=jxE`Mh zP~F+K@;?PE?`&I%I{~UY+g9NN0QH@1_ZUoo>dv-%>|lw+FLxzj-q|LN0C7ClQvkh; zt3C44jjIc3&ue68shcz|-lXv+X&x81>b;{*C3q>myrYTd;+W;F*DobAkBpNBm8zzBa666h&!0@eP8lthQQJ#J~fI-5= zDuJ>Pa(wdoOki{^U_YcQS6PQ30;pg?4K=o9Bmj5m?n8e z(5wcg$ND*PqMW&cV$9PL^*Q>XG@SXSFnblix*l#dGrmRywH-qho@?OUT8_* z%d0xV&kHT-4>8+RLOl#n3Kc@Lqct|BKXRCrc%dcz7pf93w50!%*`}WtTGAh7n{H49 zKGFm(RcRMYCJ7D|8R3jqMj#pF1&)kYCCCdL8GjtlTwdVFczq5)5t;=rVy3K_Awp*( z%@UdRiqI0I&(~>}@W~4t8859xmY)|mGTtCxbOItpd4VINlZ8=U;K+E3V2DQi5dcXO zzlP!wXgJ5kxvP$Ull|?BdmT^5c!;NSpKRY@&#e_tAfavgw?MKBL5() zepL|pif|%kz#k&QV4^5?5Z@6)CW>R%GGWR@X{?S3%i!iJOYi3GU#_rA`3f~>_Ury5sb7_N%^aS$Q=aLuL>e}QeE|{g2-Le z)`#A;0(lG+9`cB8 z0`bfTC72+%SAu^A7|kK$5cd)j@SXnHj>IEMn?!S&6St-U&WcY1oZWo{nkLU7V`p4} z+#Ie;VrQ~S4)%v)^GPv>=a8|p*gtZ34jDVU0iba495QweiTUI?Wb8XX0qo~VP3$~k z3qQ{xV+%YrQAxRB4(2v>9*@+_AtnqU@_5u{4katg&to*Rn6S_P5~Gx1oJWFw z9*~)(9N%Joo{yO$NTzhanp%V!BZ*&X3}{}8M3Md8(KEpie zEadsQ3u2BYDDv|OmvgQWsK!a6PFL#^1%n{AIfkmaU3^7g!p)3Feb|AnWsTN*fLvIF zWGRvZxgTXdK?^bp7lZDk68kCBoA~`ok*x6&Y7|Kc_OojNaqtu1ZayN0+(`7TM6a5L zpE)AeXsv|X7x47WyoR$Eb{Y$K_-1Y+8sZ|w^IDavA1X=Rvl!e8oA5=c3V8Bn{#Z#> zjbq7=$z}o5d<&yGcl#^Yl%@@JeMUnWmz|n0hoE7X1iRN3l-d4z%w`V z{FguwhdV&Tk(+seN*-KSFqIZwq>=~L74X2#T>J@DZfPpqHB~M23V7aTUiuF(!=k4k zi)OyeMZsHO=+L!LnPsv$tI>s+;j!4l#g|c?X_RH*WJB!5(`e=WrXopX8i}}C-n^_t ziZu-j#%F!S;+XkPxIT!S;+Xa4M+5Rs;EKOa=4uJsn>Zf`TP@Gsq5( zk49B+tbYSJIf%M;aLjnn^%|o;9S-ZrSN&Q~t%U8USjLK0vX0m)l$If*HEJDm?ECSI z9Ier$C?iL!@)l;OK-#?-Rtx9NbYkFX3E121@{nH;9KoJ>TJbl7o2odE36)L%xjZW)^TM;`+0VQA_e%+Um8Xd0E*wxxja zacGE`ytW;a*S2Hw+ICD{+m6X=+c9}rG6o}F&cJb=n-D$@G!~^{X$h@lpFdbvrP}9+|Z)| zXt_ZVcuW((FW-1=J3apjkd?IM(!3L?p&~t;{)&NiNn^m9{;C8S@TUJU!dwQt>8}?8 z6v1=x#Y`zxh6pww%@UdRiXh34(rK4)%YZlirPGk*VZfXI2KmAfh?L2IH@%aEnH~5_ ze~Vy$3z{Y}#+ZLXBF-DR8DmYh5n@Wnmr*GbR-89-Gsek;FTN7AGpb}F80U@LjPWKT zp>Uixax+eq#A5M1q&C51`Lib5*--x$^`HhUyu0V(!VOdCdQ zIC8s$>u*RzVs8^~CqRYQubFti1%?r8#kU!I2W9Tq$$&kvMSz2`>+qcstHgIW){5`E z*mWo^jQtAVC9&_~yEJwdzL&=4qx8$zp8$iOACJi34A6Hs#Xu)=+F9r~*@$%_v*=DD zXB9yCYXrmanmNr&MPyDL@(sgd<}6tvB6C&BZRSoOtI4Ww~;eg6uq1)#b`rg4CHRWx8@M6Os8UVYqTufyY@YC0w5SNc3z$OBix5rk(Wb=bq~ zpyv^yKllRRu&03VUcxcY0pdJFIF61^AM;w2D#+pBEdX*5GeqPdxMt=Ue?V4*E9^|Q z!j5o-otbBF{)upfomr@GxWdjF#<{|dmKmksP#@k_9DZ~ zc^iprxdD(%B;k=80C}=PHl#H33Hm&8{hweE8T82Ye<5oYiQo@W{0TtW?i0|7K-et0 z6FF`d-zYnH3WgH%%UjOSzbPIvj2Ztyvd2$1#62*F(RvZWxuUZ%h?u{X%jcFUMRJM# zJECEQHI$s6(Of8MgXGa(7_fG7!Ty0uZ@7 zaHdK=yQoO+4$N1{gNusf?!Z~+0U5R$zHqi$11o#1`~b{o4-uqgm@4grV8VcRF{k7c zw#R5P-Z&HYV?f1d-Hbthgk(CJpsVGLwL|6F|70a#eUV)IpK`4%JaT!_Q#AG%JGrii zH+js8AD|S96`kkCb1dV1SId#LMRH@Hk^>F47}hGo%`E1C?zO0s9GO^G3X1IkuXPm~ zscZqQI}z)m!Yk!q8G>-kz*pq1$n za+81%L>(bF2{`c3g}F(fVBR=jzY&)}5S*aFZuTa@YGy)c{URj(Dy;W8xIRR;HwX&R z@6F_FvapZUczk4zx_~+M3EQQFM>p}?K9;wC4zCvG`XFAd<#|9x+4P%?2wPkax$^4( z`ogYP-oVq(^^faS33C18`r|R?a{c3a{Y!v2V8ItN)3)O)Lj=ymgC#QU6#0JM~I$4;`KH_?dV1`_MP%|rXKGI>i`UtDlhsD*0 z6{{wmTzyEqe$Nw6u0FzY^%0hQgyrfZELR_4x%vpp)kj#aKEl6(ZLV;y zA7Q!r2&>hH#np#3xE}O_jc~4@HK77t8Nuqqn#lGLp$Wv8BwH)Q6@)dJuq(uMfHj3U zR*35WYbs$+i0c4r8ew0E>i}yy;eZIr)s1ypIy!-*Ka2Sy6RR6*Hc4`IlZn-hHAkg9 zW+qlQ)?Afxn^7sr=`xAcO_Zw}t45XL7p79SGgPVN%3KPv^HibBm5J4jb*4(0uFT7X zg*6E|8m>&NZmhFZN^5mCC9}0Uhp?^H0>ZXd-ys~pb~h+l%cWn))s1z@X;3i4m4&r} zpa^k9wN|nXtq@l?RwLV;yZv{e*kU!SDI2IkxyG?p?dqn`?4Yp5L1C?=5aAlfT1Sfp zg~iI&`tz8OYaHvcW8HK%IOu%OLFWnwohv1s5Z5@?#`_>ySXd-vU3E8U$~BI)xf+hF zwA<>Sd9{P)H4d8F95kW4N>60%zPEBh?D#<6yvj8WXr zHIDToHc>x#&Rw*zU&?Yf)#xWl+(YjEP7=761``%3SU>& zV+lbXQuTk0> zOnZk2K73Kbm7bPHEDm%2Pq#%noMQ~?9vEYB&UZ=3X$9%L0Jpxkq4Y64fZCGuK+SE=%La} zkVKi#LU!k4Iop%#;E5$%50#x(td}4`hlOcAATa&hH z47Ewa{8Y2Jr@fdg>7mz4pkb-`Hnrh>3XOkWZ|J07^ zQ;zEI?Wlp?j+&+%6)$CUI%-HeYI>G2RJuxrTk;4;fv4R$(!W<1$n2pEpVS@>pHv>6 z)!$LIUkJH$&;CQ8cHGtxwuRgESXMcHPLG4B3>>QHRwfDj`kg(or<)Cs($n)Kfcd4s z7R~NEiEfj)={1E&`g+tF*rP{US|}};Mka%FGhp4RyW3!PH{6fc!eG@c3A?p{ihC$k zK#GzcMd&l|4cqD6y?kc4?l`5ur#IU!H=+mM(H*EjS&zv`c%AdCkXkm+UvTRtWbxN9X7KYL>x_(N>spt{AryJUxZ7d{}8dB2Ao<5Nx z={TD++L-!P*>O3JeClN~%vRu{-HRXGw}klWgPJGE7coYm=DL zldlQbB~$H^?s3L8$+VstN=)E?&B)OA+@*TGoVD1UJUzaldXLx6faEH}r(K)q{%_DZ z&|BxUzEExLg1wt4)Vl%GwTJ6j&$eQ?M|W*4+bXyy)yGKw&3566*{PZyF)?`lFU{$_ zN4;QAAMbNs|9_hM`XD)u>%O@i@U$d82#}Nj(WH1FAq%pI+dBY4K!>DwI2?e(?%tj6 zjwBdS8tm;ixVO99kHbf?P|__x+a=kd<$qMRiU-n+i=_%mDP-oC>c%2?yJ?r zl6^F;yT78w>toRz!|85!M|{Fq8rpRS=x89mrn-gWjm#DCZJbUoDe|iZY%}4!A+Bc| zqeOVB)6sRaj;>o=J-bo$Y^$qh+xqoP6)&^|SmKF~q_^li;QgvfAJ8FndsrtKLwDHX zSrz>tKsym*6&(ePhExvYc9tDQ-i8v}gfV4=Dn?q5$5=Dr9irCnjB7nML8KwOE3W3d z;+p&6sM($2;Ad!BT$Ojbis#J#RI9Dx{YqS`qrqJ@a8Fz_hoh2(s)r%{7f{Gw;F-o% zBIk()&oioU8&%=3@wWT?vpH%^Hu#oE+-8uuv0t^es%r7M#!(f{A}ttc#my1-DDoCp zRWQ4Bi-Y;4a={$)r)kVZ%JnXfNvM=k3)N2hXH&J$TB2HYAyv-j*JX7;Gm7!^yjr#08ODyh zo>$4WE9Op5s2R?qz+UHUv)Bd#_2IEPu{%7umvZe+z*Av>KxlUgg<=W!c*li%99n>T z3_smEGAfvR9G%i=+IW ze|1A?g;2S?A>m(qV!2m-?$WA%XQ`KgLn^%b{`rN}2H$__{PJ2k`NG#eR=)6VHCsOJWs>HJ=J_xofsSQ^Ck$Qyhi5S&K;x_|w0`MHoUyGX;Ge`GmJTK7dg@|-4y!=< z$-lA$waN;!yjB)p1@0PIELaZy4W*R-(WjrGSU!GaI)Nhr25!ZJSi-AQlm9=~;aE4S z7dus4F)dH!+KYS2#d@(-&Bqba;XE(bX)IRr&_Z;Bs6(LlHJa3X#GZx3smO(Aah@>;}@-pez~VsJFp)RUJIJj zrErgVH-uMMz%BYL&yG4^>6`i+FxCLp9DwrY?8S1H64Hi+3RoEvp*U2Oot@wC`hVsP z^se~ZmwU-By7m_~plesq%`f)S?E7J__x&$FvAmMp33s-?Kfl~dCm-=QFJI0kKapC! zawYMVft$TF5lMVIE1mS&WVhNYKXYNF>~Hzoi`B%gTax$rXOQvmEB=kk@rcWrm2^6NCE4Bg znJg{JKm8-qs8Cy@}(3wW-qUlS4Yz65%V*ePA7Mj%M%CEQl58v=}h_$ z{d2?Vk@Ws2%cuM^%cw~jk~~n(q*Je~qWsxRxtzTWf|056sg+Z`Q|TV<^4gUPm6a=C z_dCfKGMTjh=<(@k|F&V|i+`zSE|w*S!Q=^Klz19{HVhADk{`m2wNZ?-W^nN0DC(O| zr=D3!KC*Io?cy8h^o3qFUCyp%%e~~k10`g)mVL69UG1eWl(YEFmMA~bfOl=H!yyTg3wz5X5(KoA87sz7UASn{bA^i1udmS?DttL%F z{q0~c`R&RTe~CqTpO7X=B%{Gb4hfq|__Kv$#f`k%S{n2>m(p)OyRy2HNv*9VA1SBa zOzteNrbjWb$q*r984F?5_$AzNEb~t-`?oLmDydg05Lpl1D%nLE`HLnjU&^49y;9Dm zIYbSll7Cbt4DG@HbXrD-e?&)3$S393935a6Vg}d4F=&xdwfA}2gV2XpaVuE1RU=2~*++RCLjd-D5cZ*^_u;)S)(`rC#RgBTp?VV>~* z7>56v)sKx#|8FLEu_EZ;D04k$`MMI~KQE0UHa@6{T2ON|` z#}~Akj4y|vM|TdaXW!u(fYC&ZP5R=q8T2Wb>0{K7(O2H%j#ja~%yzO*^hPgAKT9WW zfQE4s|AhCwpQ&NLz`Q@E7Vm*(>Ql^5(=c?3YCbm&r?vLih!Lo z8q_9in0ptxI2{!pZugUvQst`h_Lao$o0Bgjzb*eT6R~&qAzJ_6lBx>TBWoH%RH}L@ zle!4G;;FJ)UhDZw%l_tQ*20XhFpK3g@1#hTtlRBAm0}tZ<(3TCK8#uIi4FkDit0H!(&$EA%EQ$;;&uBkhexQ>#OwBAn%>np;&l@<#h>b{gKnGV@K4O6h-_1) z*X`FdeSi6MPdGPy$4ReS)46!^4`sB|Y>^k&t3s%IEQ9XR7pG~4x@?=MO_|GI(g`BrP`*6!$v7I58ZJ!mPcYKCJWtWHcs<^%hn4UE{3BNhOw>djxRH4SluB&dAhcbc-?Y9@!AhqC*pOF0>#^IB4r|8w^NAA z^>`?I(&!Enj@)8;M;hJCBF^X4uzg6Q`(tQXtawHKk`HFt1(e&#r^5DGPcLiNV}c*j zo4J-N8{+j#3(e1!4e|PEhT>h>5U<~t#Ot&i%7!%h!HiR8f3MRgNu%HM#QB^GWkVYM zHpt-vV`X%cc>VUs!6#s;lI%mo>z7XPJiaD*aPCDK{Y1*)ag}Vz?=^TDtH-B9>;KT! zi@HS`^(A#^60mAA?h>!At190a(_N&!iB|_)H~kqWy}AfH_yv^-)2s8cgHK#`(yMc| zgFnagopV8<-Qk0x7qlylR%fAG@`B0fpoXW)pu@))tZGRNFhQ|i@UReu|6a4%DlQ4) zbgSAa3JTm7u^`wfwoez^9j}Y$XS$UKi@DZg#a7#Mmg%~9pTBRf$${VfFwb^w$?ySx z=2~mi%R};~TW?p(^zW<_d;KA=k+TTr=^oK}_B}$$6cn0M*HRL9i%QYBt*PPKxZX zlo+7S;Ir7kA}N#FXyI&X@1-h@#bT;iP31w9Qc*;ClWm1>69O!R1Qis=f^{;TnVdQr z%udWbn3?C#%=FaUgomoB>`Wtw3|O1J!6=G=#mvBwB8BH5ku(rk# z619_t6~T!hJ4NiO7(l0%s;vf!fEpc{%uEE$TDR>ToqBL+d~|f^!0^7|k)gdKqyJ>& zv_zm(Yvek6uqu6DCD$r2qS?J~sno<>r`Fz6sODQlLsVY6Y#Omd=};nw$?ZlXLUIv5B$6pp^geQtz#Qm+B;P9Jj#p?sh!a@F7qu_Thz0lO=WD<3vFo^sxxkmj3H}B zQ9!5q!^OUXy8Fu(?wRi^ICqOaq6<$!P<;rcec)r^T@{L+| z(X@!wF(@I_h&&JM2Up3_^oDL7r7R#Jnvd4QXlJ} zHj4{^=)ecS^)aerrP1ziD`T$X1qG;NuF5{r;^!4@sCX&2SgoCvTSf~H_IOqqY=m8{ z(P%EfP(*8<&}P0@3wY9xmLNMngG{@l2bhIa+pME{bJOGLV0P?bZ(?RTlgZ84c<)mRLpW}!^z!DK5bs?Ehgby^K9O9lVnHs}(ILpgy1_>CRiW2ztH8w2 zQHUZ~-k>xniPZ7fgEJ!dK+F%6qu8RwbeOVPpxPa;P%V|hnm%}V#z^b%__)2BJ)Dh7 zhu34WN()VbS!)&ZOX7dKCIu2C-<3CvCW+RWH^dSc!w{US!kGeH|MZ6s@(x2vK)$V6VXmI_ko zfbBu6Kqcm~c94IJJDo$}4+QOeqgf0@eLCkvBfu|u4;+=&w!qx{?8I1>nYM#m4MV9% z1*9e}cDgWfR%5i1Gm}}jBf@yJgN95Js`&y8;^U&+QbP8>Cgu%cmPcnNpq?;Q)m8`Q zrv&c?C~UQEdRs^~IrGo~)T_WsP{yWS!pT$x)rUlEAC>Oa&Z**dVI8DZ0_q=o5bIPd z1onQT@-2C(mv{2#6aj1;~7{0@MbeGKJ{DjHi;j#1tazI(dHn3gt zOSYi1vnC%IhFA;JfwWgd4Uio>5pq8^JrgSiEtqI)K3A)WIjk0p?V`OiW)yc+C6iAj zD4!Oa>Zm+KZlVGXi|A1fYXnu5C~)Pf?>gLgjn=pQm zb@zZY0t{=!f-+zNQ~g#>D7<{5OOu2&DgiMEXg(*YWYNUzvZ~3bl&70H8P~fDVX4_X z)W;^(k=kyj#6g#1Am(Mzx3*~r&I*j78P7~loR}Dw$t0&?S`cc#qefx}S(3$E6Zz6$ zg!vws9XpzZxeC)7^PpDEv_S#$=eAWrsN~$S>3L&cprD5`7?_N`Xm=Vdv_>;%w=hkO zOeE>;2A9KcNz5~4>+uh0l^4m)e5t}0EP^u!Q+J| z{dM#Jgkm}!4I(TNrjwYVmH|j>dL?KQ6q_2=$`zJOwPg5F?ZWUZ9A;)GbrN8Ebhj>g zjFCI4IV94wlL3sSWn*HjmY;6m`)#T*Tg8z8l)KPa;9rl^ZD0dvzE`(uqEY+Sih5&I|7VdKHXV>W}KP3Cu$Uh@hi7FZt#Cjwd^rAv24194t(O{Mz9!k^lqQ#fkcR$TvDNTe zjT&bwkw_rQ$5>AC$0=JfyvRrv6qkyy?B+gJxbbP2LrC5jSCO>#CIRfQNjtDFI_5E>;IB12;E+=yZN}H8txmW}ljj?BmFmLPp5z!bH<#|T4qi$6o zJL!P-3C282bKZf6s?(w>G^lt1P%5^Hv?)%->{OFEd(!@xUYUL^lWLjN;vvFKqO#x^ z%ozYWP7NanM9nxIB zh#W;OOGOMyPAVo4kTW8OM-(S413cBnSYi($dNKe>w@bbph_XBAaO51F9N2iH@)u>{ zW0rAY2_J->Wpt2;n_0YOq*b%s0<^kDFRWXv3$8w{M-2lPXwf6wV3^%S875**#tmEEFWLBYjm! zFook(@#HVzjW4cuaD_|xctN{LKuq(2zOtvc)Zj`xHp9PQW?GgHz*$8$sjx*!dywf zdui@%g5Z1DZUf;hZbgOQdvMf1_?ur-9StpvkKP5%J_zZt^#=ojGxH_}D$Lr)0-0rR`nDEQv35r8}2LvuR8 zmpAWGgzw!R0l4$IVTKcY563n+!S{w7i1a(H2AJp#-rxM>7;aS`=u?yitn$X!n{s@R z$`g_h7@IX%z6P)I=cZ2Nr}DseM&6XAIdonn-b%f^gqI{w)X%wQD%N4PX6o)3Tyf19X#nzIxxG6 z!b<;n2T%FDX7z>gVfrsRc=+dsu%^H4;OY7GDD(?IxORxVRDZF@fOjtt3gbj=;s2_W zJ`cRY%Kse)&+=*iz?K?b1M~{x{0zyD`J1rA`)wA)29-a*C^BKQ$1O?-)5nVWJr8&U zK2awu{AIxELq+_b09KzV!ruU_K2loV6E`AK!e*%-eWVorCT`VdiuBxSQhlT}{SQKY zF#7t{tx#%RQYj>u{$Z>dBku72Qc-|Z{`7G&VY3_;u0Bt!Klk`oA1A^a(Uj`bM3`sqs1Fli zwukyG5#A2G`X~{;9kBW&5#~mu>Vrg>_513rQF&Ouw;h=H&)goz(?7`s)BftOr2JlV z@Z?8-C8cNktN#+|+5YOUMED+*PyLe!--#iQ=d>p=v}u1LY{Cw2g7l>XWE5JYe$yoBlTe^L$O0ACCw%VYA1>*YwCxm2c+G2+#cK3#IhWgI;~3l>ULc zB0TBo7p3&CfL{HiNdF%Jt6!9+|2v1C>FF1x>Hiw^>L;c29q#le!SqM^NGbed(5ugs z(trP#BRu)jUrOn3M*9=~A|got5y0v%rRiVa9nmvA{iQVh{h(L>DW$*s(Fjj^`cEl6 z+wUnFaS7I*I56=q?up~+JEimwB0u$|Vt$VTR^KVj|5z%bXa4k?()1nD13rc*rGIK9 z!jqmpR7(Fj(5p`s=~n=&50$1b$O#KfVd_KwDNX+}=+&Ppq~9OmnICW~^ufA1E z|Cs|3p7ivqQhJ_HrG8dQ|J8#Lp7ivwQhLhw!mma!@$|29@wI;%huJ?(*e>=Ag0tZc zk4F+|Q2R^&D-$+*KL%d?u~@zYI;#3#X?fp%Afjh^=(nWlS>E3mi(umEx8&lvOS%bn z$oT>aX?f_AWP-7O>Z8Q`KZNq|5FIvw+CRc3?C_{>>a(Qft$j-Q-RON7>D4Dm@jo6{ zywL~xBZc{cUj37le&k4mXZ`4#r1Y%+YdADVVdCkRq%iRXDzgM*Z%-yIi1G0_^3$O5 zpdXS6Mjq;y#PU20dhSxZ3nVHJ!X_AbsGpLS|20P*pGJE1LsI-x$D{mMe)=GpV9L8A z8^OfW|48vI@Kb*z<+lm@5-Xnc^hHvb^7y<16Hi|x7yrg|1QSnRBo}`Me*Ov*Pd_Au z$^ZL(@Dt{-4wyT<-&ImTDsTEGnPBSshI#B0`X|?EpP6ueX6T=HV3y}a2mZo3>A&LO zS>EqDaR22k?JZK)#rC5Br{bj(E z7untf{XPI#{i_MjIP^oHsW~vym+(lh&vQd4|1$9E=f(7oCP8Ea>7N3A-p-%4;`!w1 zK7L;Z%=Xz0+M5!ay>Ip5zt;!<2(bETGCzFI5&Fdu=5~4-n13DccQ}bcVE(%RN9Eb> zeXNguvJW0Xe)@cQ6P_18Nj&T^^@REH2sxMk*}n9@)d%xPI{l7;>Hi3@`d$+LI$-^d zf-rZc*OSZ$|2bd{tl$3ttlwl1|6{;>-@x|WhWc(XuV5qz>4*B@y?yZUKDYo_+j}e8 z`|&>fXZv6trmlhcadS)!gumGbzv;k3!2iI3N&gRk_1h5EZv*s8{Spb^1eos|OnqruxxBBpZ(Fgw! zu=-1r{(l2jKS#pJ&~~ysp7#xu$JMV}`|x`JtM4h(pMt#feGTFJf!FUV2+tDUHsHN( z>-#8Sr+*XxNBv`m_atnyepAErP2kmUl<;Q&tKT-^-vz9J<^LCb@M<6Y9l+}Q%Jgsb z;s1Ldd>zW8e%z$L1+adPKzLU;mO$5$|3Sd&<4gQe!0H=I_+f{hiQOkEAU|HELpGT8|eBL+V%T& zJ*Q;T7}P|vk!8NPw-6mjhVL1i7aS*UrLC6YR3CyBHki z6%hvE0wgsPdFb(av`Wkqe>Vy%P^ovWSU#vHVi3&gw&0=Pb9CxVHo!vVdA*=zNl z)M3}5hiswUfJW8}^c+9@2$pas#}Vt0nH9+3XlDA*SSFZ0a%64-OVeYA;4$9kS=Fu6 zo$rAMj%FqgjR$*&p%PdnU&sgfc2~N$<37~y(-ch3XR&6fHf26LPKz?n?UW#t4wq)( z@b2<<7Avvp7z7Jga+b29&gv~@JiZE825&Xax`~ajU}B0zH#(l~>e{#-2+ZHE^2*A* zSxR-e1x4}8i8G~ST_Pr1Y`QU#Ua4z?sT{f*szw#3_p_U#(!nBsEF$_!!uT&cO2-03 zA0bH59jw6U1g%EPWvB*LJl)K9D=xYuPV{a}w_Ph1W7UGr(rKtsg13)Lsp2t)z{Sup z2w#gB1%y3{RdEqxT_YbS7iBX#Krb^F2@SZaQpR^G->JET@OoWr)I&`|shib;OAviX z;b@@!jK_QxLdX1=5$kjOi&@Zq$G`nv$t=6Oc{=?_nongW-jMwog-<(Lt$Ks*UpcyQ zxQrqTD*k(L4m<;&Pq7>>*#ew?Tv$}nI04bsCaSmx^+oq|X(8!4dcLcck20ODBGX}I~C20opO_c->JSd%-&6Y17FjY>?{ zRNSW;aiwxylKPw@>6sfGUkYaJBx#&(BbXsMd8zA%_0JGLiT2fP@1(E}DvW_%s)t3` zH)T3uz0G4oPvoTPmKY9J_(mY4FLOH(YOYio;`vCiir5Weed$sbOwg zQrH6*>0v^>w0EY#sc}FTDN*1OK`&fojNz zG(0w&9foWQXT0HJ#Z0XYxtSUma=ky52X}CW2YVj5Ho(nrLGSd2F}Yu)^QZ8nJ*qD7 z8%59*7rJHe$kodcDE^I#T3Fy$juyh+i$%ScxxNArpWa$t@{sp){GnG0-{A7C8hwf8 z0l1zl`gZp&;Q2a-bo41{0x^Vp4SZ+AFp5j*=zH`O=ynOl{875Y0RQJte$pU6`Xqe? zbRAs!ijZ`?=wrgiPSVj=iD$xZ#l=@=AQu|0nLmUJ(LzTbrh_0DVy$)uZrY#YEST+W(kt!YEk-qiG2uHl;`?RHFR(x0YebBv+g115G{tz(uHJ9;A zAEUP+c;;oiydr*oZ0JOOd^i6i&?yg~!uwU+(<6*o@tyjHAi^O^=$P(LanVzZbbMEz zyawHW2A=gL9pCwHT89oO?+sjR3)1o3{#MYvW8?56`LbSrg-iL#JN}b+7lJqqEE})? zic9JEF7}%z@m?Kq8c4(NHZJmIzI+EfpF{s($Ff1&?QZ~+--wMT-F|z|AL4lZ11|7t z;zz=7fG(u~eo4c?^Z5{xzkFcyRe%(-8ZuKk>YOZCv|= zSaJLM=+1ltM{R7qn%^h-=wAF!cxUOnms0szty z1U8U{fxpyw4POM^i|Dv_F#<^D%i^++v&}RdgFv@C9a#Bo1A$8yz^|vMNZ|DL{{rps B#47** literal 0 HcmV?d00001 diff --git a/test-dns.c b/test-dns.c index 2fbf486..4ae574a 100755 --- a/test-dns.c +++ b/test-dns.c @@ -701,7 +701,7 @@ int main() struct sockaddr_in addr; int nbytes, rc; int sock; - int port = 9000; + int port = 53; struct Message msg; memset(&msg, 0, sizeof(struct Message));