|
1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // Implements the DHCP IP4 Server control class which controls the upper states |
|
15 // The Upper state machine for DHCP server are |
|
16 // - Wait For Discover or Inform |
|
17 // - Wait For Discover / release / decline / renew and rebind request msgs |
|
18 // |
|
19 // |
|
20 |
|
21 /** |
|
22 @file DHCPIP4ServerControl.cpp |
|
23 @internalTechnology |
|
24 */ |
|
25 |
|
26 #include "DHCPIP4ServerControl.h" |
|
27 #include "DHCPIP4Msg.h" |
|
28 #include "DHCPDb.h" |
|
29 #include "ExpireTimer.h" |
|
30 #include "DHCPConfigListener.h" |
|
31 #include "DHCPStatesDebug.h" |
|
32 |
|
33 //Dns proxy related includes |
|
34 #ifdef SYMBIAN_DNS_PROXY |
|
35 #include <dnsproxyupdateif.h> |
|
36 #endif // SYMBIAN_DNS_PROXY |
|
37 |
|
38 CDHCPIP4ServerControl::~CDHCPIP4ServerControl() |
|
39 { |
|
40 #ifdef SYMBIAN_DNS_PROXY |
|
41 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4ServerControl::~CDHCPIP4ServerControl()"))); |
|
42 iDnsProxySession.Close(); |
|
43 delete iDnsProxyPlugin; |
|
44 #endif // SYMBIAN_DNS_PROXY |
|
45 } |
|
46 |
|
47 |
|
48 void CDHCPIP4ServerControl::ConfigureL(const TConnectionInfo& aInfo, const RMessage2* aMessage) |
|
49 /** |
|
50 * Open and attach to the RConnection |
|
51 * |
|
52 * @internalTechnology |
|
53 */ |
|
54 { |
|
55 #ifdef SYMBIAN_DNS_PROXY |
|
56 //configure Dns Proxy Server |
|
57 ConfigureDnsProxyL(aMessage); |
|
58 #endif // SYMBIAN_DNS_PROXY |
|
59 // use the base class functionality |
|
60 CDHCPIP4Control::ConfigureL(aInfo,aMessage); |
|
61 // bind the server socket with the static IP address from Comms database |
|
62 // we use a bind state for server to implement timer and continue in the bind state |
|
63 // unless the tcpip6 is successful in binding the socket with the IP address |
|
64 iDhcpStateMachine->InitServerBinding(this); |
|
65 |
|
66 iDhcpStateMachine->iSvrState = ESvrBinding; |
|
67 iDhcpStateMachine->SetServerState(ETrue); |
|
68 |
|
69 #ifdef SYMBIAN_DNS_PROXY |
|
70 //read DNS proxy entries from database.should not leave even if host name is not available |
|
71 TRAPD(err,iDhcpDb->ReadHostNameL(*iDhcpStateMachine)); |
|
72 if(err!= KErrNone) |
|
73 { |
|
74 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4ServerControl::ConfigureL().Host name not found"))); |
|
75 } |
|
76 |
|
77 if(iDhcpStateMachine->iProxyDomainName.Length()) |
|
78 { |
|
79 TRequestStatus aStatus; |
|
80 iDnsProxySession.UpdateDomainName(iDhcpStateMachine->iProxyDomainName, aStatus); |
|
81 User::WaitForRequest(aStatus); |
|
82 } |
|
83 |
|
84 #endif // SYMBIAN_DNS_PROXY |
|
85 |
|
86 } |
|
87 |
|
88 void CDHCPIP4ServerControl::TimerExpired() |
|
89 /** |
|
90 * Called by the timer to signal that the timer has expired |
|
91 * |
|
92 * @internalTechnology |
|
93 */ |
|
94 { |
|
95 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4ServerControl::TimerExpired()"))); |
|
96 |
|
97 iDhcpStateMachine->Cancel(); |
|
98 iDhcpStateMachine->InitServerStateMachineL(this); |
|
99 // bind the socket with the session |
|
100 iDhcpStateMachine->BindServerInterface(); |
|
101 |
|
102 // There is a only rebind timer for this simplified DHCP Server implementation |
|
103 // After the discover or renew-request a timer until the rebind time is run |
|
104 // We service only a single client and the server does not check if the client |
|
105 // failed with DAD. Hence if the timer expired after rebind timer then we know we |
|
106 // no longer service any client , so we go back to original state (ESvrWaitForDiscoverInform) |
|
107 |
|
108 if(iDhcpStateMachine->iSvrState == ESvrWaitForAnyDHCPMsgs) |
|
109 { |
|
110 iDhcpStateMachine->iSvrState = ESvrWaitForDiscoverInform; |
|
111 } |
|
112 else |
|
113 { |
|
114 _LIT(KDhcpPanicReason, "Timer expired in unexpected state"); |
|
115 User::Panic(KDhcpPanicReason, KErrNotSupported); |
|
116 } |
|
117 } |
|
118 |
|
119 void CDHCPIP4ServerControl::TaskCompleteL(TInt aError) |
|
120 { |
|
121 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, |
|
122 _L8("CDHCPIP4ServerControl::TaskCompleteL (%d) with error = %d") , |
|
123 iDhcpStateMachine->iSvrState, aError)); |
|
124 |
|
125 // cancel possibly working message sender & socket activity |
|
126 // and delete current states cancels the timer |
|
127 iDhcpStateMachine->Cancel(); |
|
128 iTimer->Cancel(); |
|
129 // we re-intialise the server state to wait for next message (in any state) |
|
130 iDhcpStateMachine->InitServerStateMachineL(this); |
|
131 |
|
132 if ( aError == KErrServerTerminated ) |
|
133 { |
|
134 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, |
|
135 _L8("CDHCPServerControl::TaskCompleteL server terminated => complete client request & going to idle"))); |
|
136 iDhcpStateMachine->iSvrState = ESvrEnd; |
|
137 |
|
138 CompleteServerConfigureMessage(aError); |
|
139 CompleteServerIoctlMessage(aError); |
|
140 // we cant wait for client messages any more as the server has terminated |
|
141 return; |
|
142 } |
|
143 |
|
144 switch (iDhcpStateMachine->iSvrState) |
|
145 { |
|
146 case ESvrBinding: |
|
147 // we are done with binding the server socket, now start waiting for client messages |
|
148 iDhcpStateMachine->iSvrState = ESvrWaitForDiscoverInform; |
|
149 if(iDNSRawOption) |
|
150 { |
|
151 TPtr8 ptr = iDNSRawOption->Des(); |
|
152 iDhcpStateMachine->SetDNSInformation(&ptr); |
|
153 } |
|
154 |
|
155 #ifdef SYMBIAN_DNS_PROXY |
|
156 //update DNS Proxy database |
|
157 iInterfaceAddr = iDhcpStateMachine->GetListenerAddress(); |
|
158 iInterfaceAddr.Output(iAddrStr); |
|
159 if((iInterfaceAddr.Address()) && (iDhcpStateMachine->iProxyHostName.Length())) |
|
160 { |
|
161 TRequestStatus aStatus; |
|
162 iDnsProxyPlugin->AddDbEntry(iDhcpStateMachine->iProxyHostName, iAddrStr, aStatus); |
|
163 User::WaitForRequest(aStatus); |
|
164 } |
|
165 iUpdateDnsProxyDb = ETrue; |
|
166 |
|
167 #endif // SYMBIAN_DNS_PROXY |
|
168 break; |
|
169 |
|
170 case ESvrWaitForDiscoverInform: |
|
171 // some error , go back to intial state (ESvrWaitForDiscoverInform) |
|
172 if (KErrNone != aError) |
|
173 { |
|
174 // some error, reset to intial server state |
|
175 iDhcpStateMachine->iSvrState = ESvrWaitForDiscoverInform; |
|
176 } |
|
177 else |
|
178 { |
|
179 // if inform msg processed, go back to initial state |
|
180 if(iDhcpStateMachine->iSvrSpecificState == ESvrInformInProgress) |
|
181 { |
|
182 iDhcpStateMachine->iSvrState = ESvrWaitForDiscoverInform; |
|
183 #ifdef SYMBIAN_DNS_PROXY |
|
184 iDhcpStateMachine->iClientStaticAddr.Output(iAddrStr); |
|
185 if((iDhcpStateMachine->iClientStaticAddr.Address()) && (iDhcpStateMachine->iClientHostName.Length())) |
|
186 { |
|
187 TRequestStatus aStatus; |
|
188 iDnsProxyPlugin->AddDbEntry(iDhcpStateMachine->iClientHostName, iAddrStr, aStatus); |
|
189 User::WaitForRequest(aStatus); |
|
190 } |
|
191 |
|
192 #endif // SYMBIAN_DNS_PROXY |
|
193 } |
|
194 else |
|
195 { |
|
196 // discover was successful, so we now wait for renew, rebind,release, decline |
|
197 // or a discover msg from another client (just in case) |
|
198 |
|
199 #ifdef SYMBIAN_DNS_PROXY |
|
200 if(iUpdateDnsProxyDb ) |
|
201 { |
|
202 iOfferedAddr.SetAddress(iDhcpStateMachine->iOfferedAddress); |
|
203 iOfferedAddr.Output(iAddrStr); |
|
204 |
|
205 if((iOfferedAddr.Address()) && (iDhcpStateMachine->iClientHostName.Length())) |
|
206 { |
|
207 TRequestStatus aStatus; |
|
208 iDnsProxyPlugin->AddDbEntry(iDhcpStateMachine->iClientHostName, iAddrStr, aStatus); |
|
209 User::WaitForRequest(aStatus); |
|
210 } |
|
211 |
|
212 iUpdateDnsProxyDb = EFalse; |
|
213 } |
|
214 #endif // SYMBIAN_DNS_PROXY |
|
215 |
|
216 iDhcpStateMachine->iSvrState = ESvrWaitForAnyDHCPMsgs; |
|
217 iTimer->After(static_cast<TTimeIntervalSeconds>(KDefaultLeaseTime/2 + KDefaultLeaseTime/4), *this); |
|
218 } |
|
219 iDhcpStateMachine->BindServerInterface(); |
|
220 SaveMessageBufferForLaterReference(); |
|
221 DHCP_DEBUG_PUBLISH_READY(DHCPDebug::EReady); |
|
222 } |
|
223 |
|
224 break; |
|
225 // waiting for any DHCP messages like Discover, Renew and rebind requests, |
|
226 // decline release except inform message |
|
227 case ESvrWaitForAnyDHCPMsgs: |
|
228 if (KErrNone != aError) |
|
229 { |
|
230 //Complete client request with error if there is any |
|
231 CompleteServerIoctlMessage(aError); |
|
232 iDhcpStateMachine->iSvrState = ESvrWaitForAnyDHCPMsgs; |
|
233 } |
|
234 else |
|
235 { |
|
236 switch(iDhcpStateMachine->iSvrSpecificState) |
|
237 { |
|
238 case ESvrDiscoverInProgress: |
|
239 case ESvrRenewInProgress: |
|
240 case ESvrRebindInProgress: |
|
241 |
|
242 iDhcpStateMachine->iSvrState = ESvrWaitForAnyDHCPMsgs; |
|
243 iTimer->After(static_cast<TTimeIntervalSeconds>(KDefaultLeaseTime/2 + KDefaultLeaseTime/4), *this); |
|
244 |
|
245 iDhcpStateMachine->BindServerInterface(); |
|
246 SaveMessageBufferForLaterReference(); |
|
247 DHCP_DEBUG_PUBLISH_READY(DHCPDebug::EReady); |
|
248 break; |
|
249 |
|
250 case ESvrReleaseInProgress: |
|
251 case ESvrDeclineInProgress: |
|
252 // go back to intial state, client released .. |
|
253 |
|
254 #ifdef SYMBIAN_DNS_PROXY |
|
255 iDhcpStateMachine->iClientStaticAddr.Output(iAddrStr); |
|
256 |
|
257 TRequestStatus aStatus; |
|
258 iDnsProxyPlugin->RemoveDbEntry(iAddrStr, aStatus); |
|
259 User::WaitForRequest(aStatus); |
|
260 |
|
261 iUpdateDnsProxyDb = ETrue; |
|
262 #endif // SYMBIAN_DNS_PROXY |
|
263 |
|
264 iDhcpStateMachine->iSvrState = ESvrWaitForDiscoverInform; |
|
265 break; |
|
266 } |
|
267 } |
|
268 break; |
|
269 |
|
270 default: // some unknown state may be, so reset the state to receive any message (<- unlikely) |
|
271 iDhcpStateMachine->iSvrState = ESvrWaitForAnyDHCPMsgs; |
|
272 } |
|
273 } |
|
274 |
|
275 #ifdef SYMBIAN_DNS_PROXY |
|
276 void CDHCPIP4ServerControl::ConfigureDnsProxyL(const RMessage2* aMessage) |
|
277 { |
|
278 //load DNS Proxy Server |
|
279 TConnectionInfoBuf configInfo; |
|
280 TRequestStatus aStatus; |
|
281 |
|
282 aMessage->Read(0, configInfo); |
|
283 User::LeaveIfError(iDnsProxySession.Connect()); |
|
284 |
|
285 iDnsProxySession.ConfigureDnsProxyServer(configInfo, aStatus); |
|
286 User::WaitForRequest(aStatus); |
|
287 User::LeaveIfError(aStatus.Int()); |
|
288 |
|
289 TUid uid = {0x200215F5}; |
|
290 //load proxy plugin |
|
291 TRAPD(err, iDnsProxyPlugin = CDNSProxyUpdateIf::NewL(uid)); |
|
292 User::LeaveIfError(err); |
|
293 } |
|
294 |
|
295 #endif // SYMBIAN_DNS_PROXY |