1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #include "MDNSResponderReply.h"
7 #include "mozilla/EndianUtils.h"
8 #include "private/pprio.h"
9 
10 namespace mozilla {
11 namespace net {
12 
BrowseReplyRunnable(DNSServiceRef aSdRef,DNSServiceFlags aFlags,uint32_t aInterfaceIndex,DNSServiceErrorType aErrorCode,const nsACString & aServiceName,const nsACString & aRegType,const nsACString & aReplyDomain,BrowseOperator * aContext)13 BrowseReplyRunnable::BrowseReplyRunnable(
14     DNSServiceRef aSdRef, DNSServiceFlags aFlags, uint32_t aInterfaceIndex,
15     DNSServiceErrorType aErrorCode, const nsACString& aServiceName,
16     const nsACString& aRegType, const nsACString& aReplyDomain,
17     BrowseOperator* aContext)
18     : Runnable("net::BrowseReplyRunnable"),
19       mSdRef(aSdRef),
20       mFlags(aFlags),
21       mInterfaceIndex(aInterfaceIndex),
22       mErrorCode(aErrorCode),
23       mServiceName(aServiceName),
24       mRegType(aRegType),
25       mReplyDomain(aReplyDomain),
26       mContext(aContext) {}
27 
28 NS_IMETHODIMP
Run()29 BrowseReplyRunnable::Run() {
30   MOZ_ASSERT(mContext);
31   mContext->Reply(mSdRef, mFlags, mInterfaceIndex, mErrorCode, mServiceName,
32                   mRegType, mReplyDomain);
33   return NS_OK;
34 }
35 
Reply(DNSServiceRef aSdRef,DNSServiceFlags aFlags,uint32_t aInterfaceIndex,DNSServiceErrorType aErrorCode,const char * aServiceName,const char * aRegType,const char * aReplyDomain,void * aContext)36 void BrowseReplyRunnable::Reply(DNSServiceRef aSdRef, DNSServiceFlags aFlags,
37                                 uint32_t aInterfaceIndex,
38                                 DNSServiceErrorType aErrorCode,
39                                 const char* aServiceName, const char* aRegType,
40                                 const char* aReplyDomain, void* aContext) {
41   MOZ_ASSERT(OnSocketThread(), "not on socket thread");
42 
43   BrowseOperator* obj(reinterpret_cast<BrowseOperator*>(aContext));
44   if (!obj) {
45     return;
46   }
47 
48   nsCOMPtr<nsIThread> thread(obj->GetThread());
49   if (!thread) {
50     return;
51   }
52 
53   thread->Dispatch(
54       new BrowseReplyRunnable(aSdRef, aFlags, aInterfaceIndex, aErrorCode,
55                               nsCString(aServiceName), nsCString(aRegType),
56                               nsCString(aReplyDomain), obj),
57       NS_DISPATCH_NORMAL);
58 }
59 
RegisterReplyRunnable(DNSServiceRef aSdRef,DNSServiceFlags aFlags,DNSServiceErrorType aErrorCode,const nsACString & aName,const nsACString & aRegType,const nsACString & domain,RegisterOperator * aContext)60 RegisterReplyRunnable::RegisterReplyRunnable(DNSServiceRef aSdRef,
61                                              DNSServiceFlags aFlags,
62                                              DNSServiceErrorType aErrorCode,
63                                              const nsACString& aName,
64                                              const nsACString& aRegType,
65                                              const nsACString& domain,
66                                              RegisterOperator* aContext)
67     : Runnable("net::RegisterReplyRunnable"),
68       mSdRef(aSdRef),
69       mFlags(aFlags),
70       mErrorCode(aErrorCode),
71       mName(aName),
72       mRegType(aRegType),
73       mDomain(domain),
74       mContext(aContext) {}
75 
76 NS_IMETHODIMP
Run()77 RegisterReplyRunnable::Run() {
78   MOZ_ASSERT(mContext);
79 
80   mContext->Reply(mSdRef, mFlags, mErrorCode, mName, mRegType, mDomain);
81   return NS_OK;
82 }
83 
Reply(DNSServiceRef aSdRef,DNSServiceFlags aFlags,DNSServiceErrorType aErrorCode,const char * aName,const char * aRegType,const char * domain,void * aContext)84 void RegisterReplyRunnable::Reply(DNSServiceRef aSdRef, DNSServiceFlags aFlags,
85                                   DNSServiceErrorType aErrorCode,
86                                   const char* aName, const char* aRegType,
87                                   const char* domain, void* aContext) {
88   MOZ_ASSERT(OnSocketThread(), "not on socket thread");
89 
90   RegisterOperator* obj(reinterpret_cast<RegisterOperator*>(aContext));
91   if (!obj) {
92     return;
93   }
94 
95   nsCOMPtr<nsIThread> thread(obj->GetThread());
96   if (!thread) {
97     return;
98   }
99 
100   thread->Dispatch(
101       new RegisterReplyRunnable(aSdRef, aFlags, aErrorCode, nsCString(aName),
102                                 nsCString(aRegType), nsCString(domain), obj),
103       NS_DISPATCH_NORMAL);
104 }
105 
ResolveReplyRunnable(DNSServiceRef aSdRef,DNSServiceFlags aFlags,uint32_t aInterfaceIndex,DNSServiceErrorType aErrorCode,const nsACString & aFullName,const nsACString & aHostTarget,uint16_t aPort,uint16_t aTxtLen,const unsigned char * aTxtRecord,ResolveOperator * aContext)106 ResolveReplyRunnable::ResolveReplyRunnable(
107     DNSServiceRef aSdRef, DNSServiceFlags aFlags, uint32_t aInterfaceIndex,
108     DNSServiceErrorType aErrorCode, const nsACString& aFullName,
109     const nsACString& aHostTarget, uint16_t aPort, uint16_t aTxtLen,
110     const unsigned char* aTxtRecord, ResolveOperator* aContext)
111     : Runnable("net::ResolveReplyRunnable"),
112       mSdRef(aSdRef),
113       mFlags(aFlags),
114       mInterfaceIndex(aInterfaceIndex),
115       mErrorCode(aErrorCode),
116       mFullname(aFullName),
117       mHosttarget(aHostTarget),
118       mPort(aPort),
119       mTxtLen(aTxtLen),
120       mTxtRecord(new unsigned char[aTxtLen]),
121       mContext(aContext) {
122   if (mTxtRecord) {
123     memcpy(mTxtRecord.get(), aTxtRecord, aTxtLen);
124   }
125 }
126 
127 NS_IMETHODIMP
Run()128 ResolveReplyRunnable::Run() {
129   MOZ_ASSERT(mContext);
130   mContext->Reply(mSdRef, mFlags, mInterfaceIndex, mErrorCode, mFullname,
131                   mHosttarget, mPort, mTxtLen, mTxtRecord.get());
132   return NS_OK;
133 }
134 
Reply(DNSServiceRef aSdRef,DNSServiceFlags aFlags,uint32_t aInterfaceIndex,DNSServiceErrorType aErrorCode,const char * aFullName,const char * aHostTarget,uint16_t aPort,uint16_t aTxtLen,const unsigned char * aTxtRecord,void * aContext)135 void ResolveReplyRunnable::Reply(DNSServiceRef aSdRef, DNSServiceFlags aFlags,
136                                  uint32_t aInterfaceIndex,
137                                  DNSServiceErrorType aErrorCode,
138                                  const char* aFullName, const char* aHostTarget,
139                                  uint16_t aPort, uint16_t aTxtLen,
140                                  const unsigned char* aTxtRecord,
141                                  void* aContext) {
142   MOZ_ASSERT(OnSocketThread(), "not on socket thread");
143 
144   ResolveOperator* obj(reinterpret_cast<ResolveOperator*>(aContext));
145   if (!obj) {
146     return;
147   }
148 
149   nsCOMPtr<nsIThread> thread(obj->GetThread());
150   if (!thread) {
151     return;
152   }
153 
154   thread->Dispatch(
155       new ResolveReplyRunnable(aSdRef, aFlags, aInterfaceIndex, aErrorCode,
156                                nsCString(aFullName), nsCString(aHostTarget),
157                                NativeEndian::swapFromNetworkOrder(aPort),
158                                aTxtLen, aTxtRecord, obj),
159       NS_DISPATCH_NORMAL);
160 }
161 
GetAddrInfoReplyRunnable(DNSServiceRef aSdRef,DNSServiceFlags aFlags,uint32_t aInterfaceIndex,DNSServiceErrorType aErrorCode,const nsACString & aHostName,const mozilla::net::NetAddr & aAddress,uint32_t aTTL,GetAddrInfoOperator * aContext)162 GetAddrInfoReplyRunnable::GetAddrInfoReplyRunnable(
163     DNSServiceRef aSdRef, DNSServiceFlags aFlags, uint32_t aInterfaceIndex,
164     DNSServiceErrorType aErrorCode, const nsACString& aHostName,
165     const mozilla::net::NetAddr& aAddress, uint32_t aTTL,
166     GetAddrInfoOperator* aContext)
167     : Runnable("net::GetAddrInfoReplyRunnable"),
168       mSdRef(aSdRef),
169       mFlags(aFlags),
170       mInterfaceIndex(aInterfaceIndex),
171       mErrorCode(aErrorCode),
172       mHostName(aHostName),
173       mAddress(aAddress),
174       mTTL(aTTL),
175       mContext(aContext) {}
176 
177 NS_IMETHODIMP
Run()178 GetAddrInfoReplyRunnable::Run() {
179   MOZ_ASSERT(mContext);
180   mContext->Reply(mSdRef, mFlags, mInterfaceIndex, mErrorCode, mHostName,
181                   mAddress, mTTL);
182   return NS_OK;
183 }
184 
Reply(DNSServiceRef aSdRef,DNSServiceFlags aFlags,uint32_t aInterfaceIndex,DNSServiceErrorType aErrorCode,const char * aHostName,const struct sockaddr * aAddress,uint32_t aTTL,void * aContext)185 void GetAddrInfoReplyRunnable::Reply(
186     DNSServiceRef aSdRef, DNSServiceFlags aFlags, uint32_t aInterfaceIndex,
187     DNSServiceErrorType aErrorCode, const char* aHostName,
188     const struct sockaddr* aAddress, uint32_t aTTL, void* aContext) {
189   MOZ_ASSERT(OnSocketThread(), "not on socket thread");
190 
191   GetAddrInfoOperator* obj(reinterpret_cast<GetAddrInfoOperator*>(aContext));
192   if (!obj) {
193     return;
194   }
195 
196   nsCOMPtr<nsIThread> thread(obj->GetThread());
197   if (!thread) {
198     return;
199   }
200 
201   NetAddr address;
202   address.raw.family = aAddress->sa_family;
203 
204   static_assert(sizeof(address.raw.data) >= sizeof(aAddress->sa_data),
205                 "size of sockaddr.sa_data is too big");
206   memcpy(&address.raw.data, aAddress->sa_data, sizeof(aAddress->sa_data));
207 
208   thread->Dispatch(
209       new GetAddrInfoReplyRunnable(aSdRef, aFlags, aInterfaceIndex, aErrorCode,
210                                    nsCString(aHostName), address, aTTL, obj),
211       NS_DISPATCH_NORMAL);
212 }
213 
214 }  // namespace net
215 }  // namespace mozilla
216