|
1 // Copyright (c) 2004-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 // flow.h - IPv6/IPv4 flow information |
|
15 // IPv6/IPv4 flow information. |
|
16 // |
|
17 |
|
18 |
|
19 |
|
20 /** |
|
21 @file flow.h |
|
22 @publishedPartner |
|
23 @released |
|
24 */ |
|
25 |
|
26 #ifndef __FLOW_H__ |
|
27 #define __FLOW_H__ |
|
28 |
|
29 #define SYMBIAN_NETWORKING_UPS |
|
30 |
|
31 #include <es_prot.h> |
|
32 #include <nifmbuf.h> |
|
33 #include "in_pkt.h" |
|
34 #include "apibase.h" |
|
35 |
|
36 // |
|
37 // TFlowStatus |
|
38 // |
|
39 /** |
|
40 * Type of the flow status (some symbolic enum names). |
|
41 * @since v7.0 |
|
42 * @publishedPartner |
|
43 * @released |
|
44 */ |
|
45 enum TFlowStatus |
|
46 { |
|
47 /** |
|
48 * (< 0) Flow is in error state. |
|
49 * |
|
50 * All other system wide error codes also indicate a flow error state. |
|
51 * To recover, the flow must be reconnected. |
|
52 */ |
|
53 EFlow_DOWN = KErrNotReady, |
|
54 /** |
|
55 * (= 0) Flow is ready to send data. |
|
56 */ |
|
57 EFlow_READY = 0, |
|
58 /** |
|
59 * (= 1) Flow is temporarily blocked. |
|
60 * |
|
61 * This is used when the flow is waiting for the connection setup. |
|
62 * When there is a possibility that flow could change into EFLow_READY |
|
63 * state, the notifier is notified with MProviderNotify::CanSend(). |
|
64 */ |
|
65 EFlow_PENDING = 1, |
|
66 /** |
|
67 * (= 2) Flow is temporarily blocked. |
|
68 * |
|
69 * This is used when the flow is blocked due to congestion (e.g. lower level |
|
70 * buffers are full). When congestion clears and if there is a possibility |
|
71 * that flow could change into EFLow_READY state, the notifier is notified |
|
72 * with MProviderNotify::CanSend(). |
|
73 */ |
|
74 EFlow_HOLD = 2 |
|
75 #ifdef SYMBIAN_TCPIPDHCP_UPDATE |
|
76 , |
|
77 EFlow_NOTCONFIGURE = 3 |
|
78 #endif //SYMBIAN_TCPIPDHCP_UPDATE |
|
79 }; |
|
80 |
|
81 // MProviderNotify |
|
82 // *************** |
|
83 class MProviderNotify : public MInetBase |
|
84 /** |
|
85 * Receiver of the notifications of the status changes in the flow. |
|
86 * |
|
87 * Note that the two functions CanSend() and Error() are a subset of MSocketNotify. This allows |
|
88 * a Service Access Point to implement the interface just by calling the equivalent |
|
89 * MSocketNotify functions. |
|
90 * @since v7.0 |
|
91 * @publishedPartner |
|
92 * @released |
|
93 */ |
|
94 { |
|
95 public: |
|
96 /** |
|
97 * Flags that the flow might be ready to change into the EFlow_READY status |
|
98 * |
|
99 * The flow is (or has been) in EFlow_PENDING or EFlow_HOLD state. The flow |
|
100 * owner can now check if flow really can be changed into EFlow_READY state. |
|
101 * The state is updated by calling RFlowContext::Status (or some other functions |
|
102 * that implicitly refresh the flow state by calling internally the |
|
103 * CFlowContext::RefreshFlow function). |
|
104 * |
|
105 * Even if this function is called, the flow can still be in error or blocked |
|
106 * state. This is because, for example, when congestion clears, all flows |
|
107 * waiting for that event are notified, but some earlier notified flow may |
|
108 * already have refilled all the buffers. |
|
109 */ |
|
110 virtual void CanSend() = 0; |
|
111 /** |
|
112 * The flow has entered an error state. |
|
113 * |
|
114 * Error state in a flow is permanent and requires a new connect (CFlowContext::Connect) |
|
115 * to be cleared. A new connect occurs implicitly at FlowContext::Status (or some |
|
116 * at some other functions), if flows connection parameters have been modified |
|
117 * since the last connect (CFlowContext::iChanged is 1). |
|
118 * |
|
119 * @param aError Flow error code |
|
120 * @param anOperationMask A bitmask of MSocketNotify::TOperationBitmasks values |
|
121 * specifying which pending operations are affected by the error up-call. |
|
122 */ |
|
123 virtual void Error(TInt aError, TUint anOperationMask=MSocketNotify::EErrorAllOperations) = 0; |
|
124 virtual void NoBearer(const TDesC8& aConnectionParams) = 0; |
|
125 virtual void Bearer(const TDesC8 &aConnectionInfo) = 0; |
|
126 virtual TInt CheckPolicy(const TSecurityPolicy&, const char *) |
|
127 { |
|
128 return KErrNone; |
|
129 }; |
|
130 }; |
|
131 |
|
132 |
|
133 // |
|
134 // RFlowContext |
|
135 // ************ |
|
136 // |
|
137 class MFlowManager; |
|
138 class CFlowContext; |
|
139 class CNifIfBase; |
|
140 |
|
141 // *WARNING*: |
|
142 // Because RFlowContext is used as a member of RMBufSendInfo, which may |
|
143 // get moved around, the RFlowContext handle *MUST* not contain anything |
|
144 // that breaks if it is copied bit-by-bit from one memory area to another! |
|
145 // (for example don't even think of adding link fields and linking |
|
146 // RFlowContext's into a list!) -- msa |
|
147 // |
|
148 class RFlowContext |
|
149 /** |
|
150 * A handle to a flow context. |
|
151 * |
|
152 * The main purpose of this class is to provide automatic reference counting |
|
153 * for flow context users. |
|
154 * |
|
155 * A typical use for a RFlowContext object is to: |
|
156 * @li allocate a context to a handle through the flow manager (Open()) |
|
157 * @li set appropriate flow parameters (the upper layer protocol associated with |
|
158 * the flow, destination and source addresses) |
|
159 * @li use the flow to send packets out |
|
160 * @li release the context (Close()) from the handle. |
|
161 * @since v7.0 |
|
162 * @publishedPartner |
|
163 * @released |
|
164 */ |
|
165 { |
|
166 public: |
|
167 inline RFlowContext() : iFlow(0) |
|
168 /** |
|
169 * Default constructor. |
|
170 * |
|
171 * This creates a handle without any assigned flow context. |
|
172 */ |
|
173 {} |
|
174 IMPORT_C TInt Open(MFlowManager *aManager, const TSockAddr &aDst, const TSockAddr &aSrc, TUint aProtocol = 0, TUint aIcmpType = 0, TUint aIcmpCode = 0); |
|
175 IMPORT_C TInt Open(MFlowManager *aManager, TUint aProtocol = 0); |
|
176 IMPORT_C TInt Open(RFlowContext &aContext, RMBufPktInfo *aInfo = NULL); |
|
177 IMPORT_C TInt Clone(const RFlowContext &aFlow); |
|
178 IMPORT_C TInt ReOpen(); |
|
179 IMPORT_C TInt Connect(); |
|
180 |
|
181 inline TBool IsOpen() |
|
182 /** |
|
183 * Tests if context is attached |
|
184 */ |
|
185 {return iFlow != NULL;} |
|
186 |
|
187 IMPORT_C void SetRemoteAddr(const TSockAddr &aAddr); |
|
188 IMPORT_C void SetLocalAddr(const TSockAddr &aAddr); |
|
189 IMPORT_C void SetProtocol(TUint aProtocol); |
|
190 IMPORT_C void SetIcmpType(TUint aType, TUint aCode = 0); |
|
191 IMPORT_C MProviderNotify *SetNotify(MProviderNotify *aProvider); |
|
192 IMPORT_C TInt Status(); |
|
193 IMPORT_C void Grab(RFlowContext &aContext); |
|
194 IMPORT_C void Copy(RFlowContext &aContext); |
|
195 IMPORT_C void Close(); |
|
196 IMPORT_C CNifIfBase *Interface() const; |
|
197 |
|
198 #ifdef SYMBIAN_TCPIPDHCP_UPDATE |
|
199 IMPORT_C TBool IsNdResolutionPending(); //RFC 4861 - Section 7.2.2 |
|
200 #endif //SYMBIAN_TCPIPDHCP_UPDATE |
|
201 inline CFlowContext *FlowContext() const |
|
202 /** Gets a pointer to the flow context object (CFlowContext) |
|
203 * attached to the handle. |
|
204 * |
|
205 * This can be used for more detailed control of the flow parameters. |
|
206 * |
|
207 * The returned pointer has limited validity, |
|
208 * and it should not be stored in any members of permanent objects. |
|
209 * In addition, care must be taken not to call any operation that could |
|
210 * destroy the flow context as a side effect. |
|
211 * |
|
212 * If there is a need for longer validity of the retrieved pointer, |
|
213 * the CFlowContext::Open and CFlowContext::Close methods can be used |
|
214 * to protect it. |
|
215 * |
|
216 * @return |
|
217 * The flow context object. |
|
218 */ |
|
219 { return iFlow; } |
|
220 private: |
|
221 /** The flow context. */ |
|
222 CFlowContext *iFlow; |
|
223 }; |
|
224 |
|
225 |
|
226 |
|
227 // ****************************** |
|
228 // RMBufSendInfo, RMBufSendPacket |
|
229 // ****************************** |
|
230 class RMBufSendInfo : public RMBufPktInfo |
|
231 /** |
|
232 * Information for outgoing packets. |
|
233 * |
|
234 * This extends the packet information class to record the flow context. |
|
235 * @since v7.0 |
|
236 * @publishedPartner |
|
237 * @released |
|
238 */ |
|
239 { |
|
240 public: |
|
241 /** Flow context for the packet. */ |
|
242 RFlowContext iFlow; |
|
243 }; |
|
244 |
|
245 /** @since v5.0 */ |
|
246 typedef class RMBufInfoPacketBase<RMBufSendInfo> RMBufSendPacket; |
|
247 |
|
248 // TFlowInfo |
|
249 // ********* |
|
250 class TFlowInfo |
|
251 /** |
|
252 * Collects the information which defines a flow |
|
253 * (The Upper Layer Flow Information). This is a |
|
254 * member of CFlowContext. |
|
255 * |
|
256 * @since v7.0s |
|
257 */ |
|
258 { |
|
259 public: |
|
260 /** |
|
261 * Current remote addess as set by upper layer. |
|
262 * |
|
263 * Must always be specified before a flow can be connecte or |
|
264 * used for sending packets. |
|
265 * |
|
266 * See RFlowContext::SetRemoteAddr, CFlowContext::RemoteAddr |
|
267 */ |
|
268 TInetAddr iRemote; |
|
269 /** |
|
270 * Current local address (system or application selected). |
|
271 * |
|
272 * See RFlowContext::SetLocalAddr, CFlowContext::LocalAddr |
|
273 */ |
|
274 TInetAddr iLocal; |
|
275 /** |
|
276 * The protocol associated with the flow. |
|
277 * |
|
278 * See RFlowContext::SetProtocol, CFlowContext::Protocol |
|
279 */ |
|
280 TUint8 iProtocol; |
|
281 /** |
|
282 * ICMP type, when protocol is ICMP (or similar). |
|
283 * |
|
284 * See RFlowContext::SetIcmpType, CFlowContext::GetIcmpTypeCode |
|
285 */ |
|
286 TUint8 iIcmpType; |
|
287 /** |
|
288 * ICMP code, when protocol is ICMP (or similar). |
|
289 * |
|
290 * See RFlowContext::SetIcmpType, CFlowContext::GetIcmpTypeCode |
|
291 */ |
|
292 TUint8 iIcmpCode; |
|
293 /** |
|
294 * Set when upper layer set the local address. |
|
295 * |
|
296 * When set, the stack assumes the upper layer has specified |
|
297 * the source address of the flow. When not set, the stack |
|
298 * chooses the source address. |
|
299 * |
|
300 * This flag is cleared or set by the RFlowContext::SetLocalAddr(). |
|
301 * The flag is cleared when address is unspecified and set otherwise. |
|
302 * Initial value is unset, if SetLocalAddr is never called. |
|
303 * |
|
304 * See also CFlowContext::IsLocalSet |
|
305 */ |
|
306 TUint iLocalSet:1; |
|
307 /** |
|
308 * Set when interface errors should not affect the flow. |
|
309 * |
|
310 * When an interface goes down (or reports an error), all flows |
|
311 * that are currently connected (routed) to this interface, are |
|
312 * also set into error error state (effectively, causing a |
|
313 * socket error to the applications). |
|
314 * |
|
315 * When this flag is set, flow is not set to the error state. However, |
|
316 * if interface is going down, the flow is put into hold/pending |
|
317 * state (until another or same interface becomes again available). |
|
318 * |
|
319 * See also the socket option: #KSoNoInterfaceError |
|
320 */ |
|
321 TUint iNoInterfaceError:1; |
|
322 /** |
|
323 * Set when this flow should not try to bring up the interface. |
|
324 * |
|
325 * When a connect is attempted on a flow and it fails due to |
|
326 * missing routes (no suitable interfaces up or configured yet), the |
|
327 * stack signals the NIFMAN (NoBearer notify function). |
|
328 * |
|
329 * When this flag is set, NIFMAN is not notified and the flow is |
|
330 * just placed into hold/pending state to wait for possible interface |
|
331 * or route to appear. |
|
332 * |
|
333 * @note |
|
334 * NoBearer does not exisit in pre 7.0s systems. In such |
|
335 * systems the stack itself activates the "netdial process" in |
|
336 * this situation. |
|
337 */ |
|
338 TUint iNoInterfaceUp:1; |
|
339 /** |
|
340 * Set when flow is used for packet forwarding. |
|
341 * |
|
342 * This flag, when set, disables the source address checking. |
|
343 * Normally the stack works in "strong model" and requires that |
|
344 * a packet has a valid source address on the interface. |
|
345 * Forwarded packets have other than local source address and |
|
346 * the check must be disabled. |
|
347 * |
|
348 * This can only be set internally or from the hooks. There is no |
|
349 * application level socket option to set this. |
|
350 */ |
|
351 TUint iForwardingFlow:1; |
|
352 // Note! Cannot use TScopeType below, because it would make the |
|
353 // bitfield into signed and fail on tests like: |
|
354 // x.iLockType == EScopeType_NET |
|
355 // even if x.iLockType has value EScopeType_NET!!! -- msa |
|
356 /** |
|
357 * Locked scope-1 (0..15) [TScopeType]. |
|
358 * |
|
359 * This valid only when iLockId is non-zero. |
|
360 */ |
|
361 TUint iLockType:4; |
|
362 /** |
|
363 * Current Locking Id. |
|
364 * |
|
365 * Value ZERO is unlocked. Non-Zero value is a zone id in the scope |
|
366 * specified by iLockType. |
|
367 */ |
|
368 TUint32 iLockId; |
|
369 }; |
|
370 |
|
371 |
|
372 // ************ |
|
373 // CFlowContext |
|
374 // ************ |
|
375 // A base class of the Flow Context, cannot be instantiated as is |
|
376 // |
|
377 class COptionValue; |
|
378 class MFlowHook; |
|
379 class MInterfaceManager; |
|
380 |
|
381 class CFlowContext : public CBase |
|
382 /** |
|
383 * The flow context instance. |
|
384 * |
|
385 * The CFlowContext has several public methods, but not all of them are safe |
|
386 * (or even legal) to use in all situations. |
|
387 * |
|
388 * CFlowContext is a reference counted object. Whenever a pointer is |
|
389 * stored for long term duration, the Open() must be called, and when |
|
390 * pointer is no more used, a close must be called. This object is only |
|
391 * deleted indirectly via use of Close(). The delete operator is never |
|
392 * used explicitly from outside. |
|
393 * |
|
394 * Base class for a flow context. |
|
395 * @since v7.0 |
|
396 * @publishedPartner |
|
397 * @released |
|
398 */ |
|
399 { |
|
400 friend class MFlowManager; |
|
401 friend class RFlowContext; |
|
402 protected: |
|
403 IMPORT_C CFlowContext(const void *aOwner, MFlowManager *aManager); |
|
404 IMPORT_C CFlowContext(const void *aOwner, MFlowManager *aManager, CFlowContext &aFlow); |
|
405 // Destructor should not be exported, it should be private! -- msa |
|
406 IMPORT_C virtual ~CFlowContext(); |
|
407 |
|
408 #ifdef SYMBIAN_NETWORKING_UPS |
|
409 /** |
|
410 Indicate whether the flow has a provider above it. |
|
411 @return ETrue if it has, else EFalse. |
|
412 */ |
|
413 inline TBool HasProvider() const; |
|
414 |
|
415 |
|
416 inline void *GetProviderApiL(const TDesC8& aApiName, TUint* aVersion); |
|
417 #endif //SYMBIAN_NETWORKING_UPS |
|
418 |
|
419 public: |
|
420 IMPORT_C void Close(); |
|
421 |
|
422 inline void Open() |
|
423 /** |
|
424 * Increments a reference count on the context |
|
425 */ |
|
426 { iRefs++; } |
|
427 IMPORT_C TInt Status(); |
|
428 IMPORT_C void SetStatus(TInt aStatus); |
|
429 IMPORT_C TInt StoreOption(TUint aLevel, TUint aName, const TDesC8 &aOption); |
|
430 IMPORT_C TInt RetrieveOption(TUint aLevel, TUint aName, TDes8 &aOption) const; |
|
431 |
|
432 inline TPacketHead &Head() |
|
433 /** |
|
434 * Gets access to precomputed information for the outbound packet flow. |
|
435 * |
|
436 * @return Precomputed information for the outbound packet flow |
|
437 */ |
|
438 { return iHead; } |
|
439 |
|
440 /** |
|
441 * @defgroup getselectors Retrieve current selector fields |
|
442 * |
|
443 * @{ |
|
444 */ |
|
445 |
|
446 inline TUint LocalPort() const |
|
447 /** |
|
448 * Gets the flow's local port. |
|
449 * @return current local port |
|
450 */ |
|
451 { return iInfo.iLocal.Port(); } |
|
452 |
|
453 inline TUint RemotePort() const |
|
454 /** |
|
455 * Gets the flow's remote port. |
|
456 * @return current remote port |
|
457 */ |
|
458 { return iInfo.iRemote.Port(); } |
|
459 |
|
460 inline TUint Protocol() const |
|
461 /** |
|
462 * Gets the flow protocol. |
|
463 * @return current protocol |
|
464 */ |
|
465 { return iInfo.iProtocol; } |
|
466 |
|
467 inline const TInetAddr &LocalAddr() const |
|
468 /** |
|
469 * Gets the flow's local address. |
|
470 * |
|
471 * The local address may have been selected by the system, if |
|
472 * the transport layer didn't set it (left it unspecified or |
|
473 * explicitly set unspecified address to it). |
|
474 * |
|
475 * @note |
|
476 * All addresses in the flow context are kept in IPv6 format |
|
477 * (using IPv4 mapped addresses for IPv4 flows). |
|
478 * |
|
479 * @return Local address. |
|
480 */ |
|
481 { return iInfo.iLocal; } |
|
482 |
|
483 inline TBool IsLocalSet() const |
|
484 /** |
|
485 * Gets the flow's local address status. |
|
486 * |
|
487 * The local address can be selected by the stack, or application |
|
488 * can have set it into a specific value. When this address status |
|
489 * have value ETrue, the stack assumes that the local address has |
|
490 * been chosen by the application or upper layer protocol. When |
|
491 * status is EFalse, the stack selects the source |
|
492 * address for the flow when the flow is connected |
|
493 * (CFlowContext::Connect). |
|
494 * |
|
495 * The RFlowContext::SetLocalAddress will set this status to EFalse, |
|
496 * if the address is unspecified address, and to ETrue otherwise. |
|
497 * |
|
498 * @note |
|
499 * If an application requires using the unspecified source address |
|
500 * in packets (IPv4 <tt>0.0.0.0</tt> or IPv6 <tt>::</tt>), it must use |
|
501 * the socket option #KSoNoSourceAddressSelect (level #KSolInetIp) |
|
502 * <em>after</em> it has performed the RSocket::Bind() to uspecified |
|
503 * address. |
|
504 * |
|
505 * Some upper layer protocols may also set this status, after the |
|
506 * connection is established (TCP). |
|
507 * |
|
508 * @return ETrue, if local addr is set |
|
509 */ |
|
510 { return iInfo.iLocalSet != 0; } |
|
511 |
|
512 inline const TInetAddr &RemoteAddr() const |
|
513 /** |
|
514 * Gets the flow's remote address. |
|
515 * |
|
516 * @return Remote address. |
|
517 */ |
|
518 { return iInfo.iRemote; } |
|
519 |
|
520 inline void GetIcmpTypeCode(TUint8 &aType, TUint8 &aCode) const |
|
521 /** |
|
522 * Gets the flow's ICMP type and code. |
|
523 * |
|
524 * @retval aType Icmp (or other) type |
|
525 * @retval aCode Icmp (or other) code |
|
526 */ |
|
527 { aType = iInfo.iIcmpType; aCode = iInfo.iIcmpCode; } |
|
528 |
|
529 inline TScopeType LockType() const |
|
530 /** |
|
531 * Gets the flow's locking type [0..15]. |
|
532 * |
|
533 * The locking type tells the type of the lock id. The type has no |
|
534 * meaning if the lock id has zero value (= flow is not locked).. |
|
535 * |
|
536 * @return current type of LockId (IF=0, IAP=1, NET=15). |
|
537 */ |
|
538 { return (TScopeType)iInfo.iLockType; } |
|
539 |
|
540 inline TUint32 LockId() const |
|
541 /** |
|
542 * Gets the flows lock id. |
|
543 * |
|
544 * A flow can be locked to a specified scope. When locked (non-zero), |
|
545 * the flow can only be connected to an interface within the locked |
|
546 * scope. |
|
547 * |
|
548 * The id value is a plain 32 bit number and the domain of this |
|
549 * value is defined by the locking type (CFlowContext::LockType). |
|
550 * |
|
551 * @return current lock id (IAP, NET or IF). Not locked, if ZERO |
|
552 */ |
|
553 { return iInfo.iLockId; } |
|
554 |
|
555 /** @} */ |
|
556 |
|
557 /** |
|
558 * @defgroup packetsize Accessing parameters of the packet size |
|
559 * |
|
560 * In all, return |
|
561 * @li < 0, indicates an error or value not known |
|
562 * @li = 0, (interpretation not fixed) |
|
563 * @li > 0, the indicated value |
|
564 * |
|
565 * Some assertations that should be true |
|
566 * @li PathMtu() > HeaderSize() |
|
567 * @li HeaderSize() >= sizeof(TInet6HeaderIP) |
|
568 * @li InterfaceSMtu() >= PathMTU() |
|
569 * @li InterfaceRMtu() > sizeof(TInet6HeaderIP) |
|
570 * |
|
571 * @{ |
|
572 */ |
|
573 |
|
574 inline TInt PathMtu() const |
|
575 /** |
|
576 * Gets the Path MTU of the flow. |
|
577 * |
|
578 * @return |
|
579 * @li < 0, indicates an error or value not yet known (for example, |
|
580 * if accessed before the flow is connected or interface is up) |
|
581 * @li = 0, value not known |
|
582 * |
|
583 * @li > 0, a real value |
|
584 */ |
|
585 { return iPathMtu; } |
|
586 |
|
587 inline TInt HeaderSize() const |
|
588 /** |
|
589 * Gets the amount of the protocol overhead in the packet from all of the lower layers. |
|
590 * |
|
591 * The value is defined only for a flow that has been connected. |
|
592 * (CFlowContext::Connect). |
|
593 * |
|
594 * HeaderSize () > 0 (at least IPv4 or IPv6 header size) |
|
595 * |
|
596 * @return |
|
597 * @li < 0, indicates an error or value not yet known (for example, |
|
598 * if accessed before the flow is connected or interface is up) |
|
599 * @li = 0, value not known |
|
600 * @li > 0, a real value |
|
601 */ |
|
602 { return iHdrSize; } |
|
603 |
|
604 /** |
|
605 * Gets the raw send MTU of the attached interface. |
|
606 * |
|
607 * The value is defined only for a flow that has been connected. |
|
608 * (CFlowContext::Connect). |
|
609 * |
|
610 * @return |
|
611 * @li < 0, indicates an error or value not yet known (for example, |
|
612 * if accessed before the flow is connected or interface is up) |
|
613 * @li = 0, value not known |
|
614 * @li > 0, a real value |
|
615 */ |
|
616 virtual TInt InterfaceSMtu() const = 0; |
|
617 /** |
|
618 * Gets the raw receive MTU of the interface. |
|
619 * |
|
620 * The value is defined only for a flow that has been connected. |
|
621 * (CFlowContext::Connect). |
|
622 * |
|
623 * @return |
|
624 * @li < 0, indicates an error or value not yet known (for example, |
|
625 * if accessed before the flow is connected or interface is up) |
|
626 * @li = 0, value not known |
|
627 * @li > 0, a real value |
|
628 */ |
|
629 virtual TInt InterfaceRMtu() const = 0; |
|
630 /** @} */ |
|
631 |
|
632 /** |
|
633 * Gets an option from the flow context. |
|
634 * |
|
635 * A set of options can be read from the flow context. |
|
636 * |
|
637 * In addition to internally supported options, |
|
638 * any registered outbound hook can add support for additional options |
|
639 * (see MIp6Hook::GetFlowOption documentation). |
|
640 * |
|
641 * The function is called part of the normal option processing. |
|
642 * |
|
643 * @param aLevel The option level |
|
644 * @param aName The option name |
|
645 * @param aOption The option value |
|
646 * @return |
|
647 * KErrNone, or KErrNotSuppoted if option cannot be read from the flow context. |
|
648 */ |
|
649 virtual TInt GetOption(TUint aLevel, TUint aName, TDes8 &aOption) const = 0; |
|
650 |
|
651 /** |
|
652 * Sets an option to the flow context. |
|
653 * |
|
654 * A set of options can be set to the flow context. |
|
655 *. |
|
656 * In addition to internally supported options, |
|
657 * any registered outbound hook can add support for additional options |
|
658 * (see MIp6Hook::SetFlowOption documentation). |
|
659 * |
|
660 * The function is called part of the normal option processing. |
|
661 * |
|
662 * @param aLevel The option level |
|
663 * @param aName The option name |
|
664 * @param aOption The option value |
|
665 * @return |
|
666 * KErrNone, or KErrNotSuppoted if option cannot be set from the flow context. |
|
667 */ |
|
668 virtual TInt SetOption(TUint aLevel, TUint aName, const TDesC8 &aOption) = 0; |
|
669 |
|
670 /** |
|
671 * Gets the currently connected interface. |
|
672 * |
|
673 * @return |
|
674 * The currently connected interface, |
|
675 * if the flow is properly connected, otherwise NULL. |
|
676 * The returned pointer has limited validity, and it should not be stored |
|
677 * in any members of permanent objects. |
|
678 */ |
|
679 virtual CNifIfBase *Interface() const = 0; |
|
680 |
|
681 /** |
|
682 * Gets the interface manager of the TCP/IP stack.. |
|
683 * |
|
684 * @return |
|
685 * The interface manager. |
|
686 */ |
|
687 virtual MInterfaceManager *Interfacer() const = 0; |
|
688 |
|
689 /** |
|
690 * Sends a packet to the attached interface. |
|
691 * |
|
692 * This is a low level function intended for the IP layer itself. |
|
693 * Send bypasses all the installed hooks and path mtu processing. |
|
694 * The raw data in the packet is passed to the interface as is. |
|
695 * (for the normal way of sending a packet, see MNetworkService::Send). |
|
696 * |
|
697 * If the flow is not connected, the Send drops the packet and the |
|
698 * return is KErrNotReady. |
|
699 * |
|
700 * The destination address of the information block may get changed |
|
701 * into link layer destination address, if the stack is handling the |
|
702 * neighbour discovery on the link (ARP for IPv4, ICMPv6 Neighbor |
|
703 * discovery for IPv6). |
|
704 * |
|
705 * If the destination is a multicast address, and if that address |
|
706 * is also joined by some application(s), then a copy of the packet |
|
707 * is sent to the inbound direction (MNetworkService::Process), |
|
708 * unless disabled by #KSoIp6MulticastLoop socket option. |
|
709 * |
|
710 * @param aPacket |
|
711 * The data packet (assumed to be RMBufInfoPktBase in "packed" state) |
|
712 * @param aSource |
|
713 * The source protocol instance (passed as is to the interface). Optional, |
|
714 * and usually NULL. |
|
715 * @return |
|
716 * is defined similarly as the equivalent methods of the interfaces and |
|
717 * protocols, as follows: |
|
718 * @li < 0, |
|
719 * an error: the packet is not sent, but is dropped by Send(). |
|
720 * @li = 0, |
|
721 * indicates that the interface received the packet, but is also signaling |
|
722 * that its reluctance to receive more packets. All flows attached to this |
|
723 * interface are automatically set into EFlow_HOLD state. |
|
724 * @li > 0, |
|
725 * indicates that the interface received the packet and is willing to |
|
726 * receive more after this. |
|
727 */ |
|
728 virtual TInt Send(RMBufChain &aPacket, CProtocolBase* aSource = NULL) = 0; |
|
729 |
|
730 /** Attaches a flow to a route and an interface. */ |
|
731 virtual void Connect() = 0; |
|
732 /** Disconnects the flow, and remove all hooks. */ |
|
733 virtual void Disconnect() = 0; |
|
734 /** Recomputes the current flow status. */ |
|
735 virtual void RefreshFlow() = 0; |
|
736 /** |
|
737 * Sets "changed" state to flow(s). |
|
738 * |
|
739 * Sets the iChanged flag that indicates that connect information has changed. |
|
740 * |
|
741 * When any component of the system determines that a flow or set |
|
742 * of flows require an open phase (reconnect), the component can use the |
|
743 * this function to force a reconnect of the flow on the next outgoing packet. |
|
744 * |
|
745 * @param aScope determines what flows are affected: |
|
746 * @li 0: set iChanged on current flow |
|
747 * @li 1: set iChanged on all flows with same route entry, |
|
748 * @li 2: set iChanged on all flows with same interface, |
|
749 * @li > 2: set iChanged on all existing flows |
|
750 * |
|
751 * @return |
|
752 * Number of flows affected (regardless of their previous iChanged state) |
|
753 */ |
|
754 virtual TInt SetChanged(const TInt aScope = 0) = 0; |
|
755 #ifdef SYMBIAN_TCPIPDHCP_UPDATE |
|
756 /* RFC 4861: Sec 7.2.2 Verifies any pending ND packets exists on a route during ND |
|
757 */ |
|
758 virtual TBool IsNdPacketPendingResolution() {return EFalse; } ; // Base implementation |
|
759 #endif //SYMBIAN_TCPIPDHCP_UPDATE |
|
760 inline void NoBearer(const TDesC8& aConnectionParams); |
|
761 inline void Bearer(const TDesC8 &aConnectionInfo); |
|
762 inline TInt CheckPolicy(const TSecurityPolicy& aPolicy, const char *aDiagnostic); |
|
763 |
|
764 protected: |
|
765 /** The owner of the flow (untyped ID data). */ |
|
766 const void *const iOwner; |
|
767 /** The flow manager that created this object. */ |
|
768 MFlowManager *const iMgr; |
|
769 |
|
770 /** Contains the object reference count. |
|
771 * |
|
772 * For a single reference, this is 0. |
|
773 */ |
|
774 TInt iRefs; |
|
775 /** The flow's status. |
|
776 * |
|
777 * @li = 0: up and running |
|
778 * @li > 0: pending |
|
779 * @li < 0: error. |
|
780 */ |
|
781 TInt iStatus; |
|
782 public: |
|
783 /** The Upper Layer Flow Information */ |
|
784 TFlowInfo iInfo; |
|
785 protected: |
|
786 /** |
|
787 * Set when flow needs a reconnect (selector information changed). |
|
788 * |
|
789 * When this is set (1), RFlowContext::Status (and some other methods) will |
|
790 * automaticly call CFlowContext::Connect for the flow. Primary reason for |
|
791 * this to be set is that the flow selector information has been changed |
|
792 * (@ref setselectors). |
|
793 * |
|
794 * This can be set explicitly by the CFlowContext::SetChanged function (or |
|
795 * MFlowManager::SetChanged). |
|
796 */ |
|
797 TUint iChanged:1; |
|
798 public: |
|
799 /** |
|
800 * Flag that indicates that NIF HOLD return should not block the flow. |
|
801 * |
|
802 * After a packet send a NIF can return a value that indicates that no |
|
803 * more packets are to be sent to it, until it allows it again via |
|
804 * the CProtocolBase::StartSending call. Normally, such indication |
|
805 * sets the flow into HOLD state. |
|
806 * |
|
807 * When this flag is set, flow is not put into HOLD. This flag should |
|
808 * only be used by a hook that have other means of enforcing the flow |
|
809 * control (for example QOS). |
|
810 */ |
|
811 TUint iIgnoreFlowControl:1; |
|
812 /** Precomputed packet header information. */ |
|
813 TPacketHead iHead; |
|
814 /** |
|
815 * The current Path MTU |
|
816 * |
|
817 * Set from the path MTU of the connected interface. May change |
|
818 * dynamically due to ICMP "packet too big" or other events. |
|
819 */ |
|
820 TUint iPathMtu; |
|
821 /** |
|
822 * The header overhead by IP layer and hooks |
|
823 * |
|
824 * The iHdrSize is initialized to 0 at the beginning of the MIp6Hook::OpenL |
|
825 * phase. |
|
826 * The final value at the end of the OpenL phase is saved, and this value |
|
827 * will be the initial value at the beginning of the MFlowHook::ReadyL phase. |
|
828 * |
|
829 * The final value at the end of the ReadyL phase must be the total amount |
|
830 * of header space required by the layers below the transport (upper layer |
|
831 * protocol). The space available for the upper layer header and payload |
|
832 * is: iPathMtu - iHdrSize. |
|
833 * |
|
834 * The hook can add the header space requirement in OpenL or ReadyL |
|
835 * method. If it does it in OpenL, it does not need to touch the |
|
836 * iHdrSize in ReadyL method (for example, IPSEC only knows the |
|
837 * exact required header space at ReadyL phase). |
|
838 * |
|
839 * If a hook uses the TPacketHead::iPacket member to store precomputed |
|
840 * headers, which are automaticly appended to each packet, it must include |
|
841 * the amount into iHdrSize (it must carefully compute the change of length |
|
842 * in iPacket, if it adds new data there). |
|
843 * |
|
844 * The stack includes implicitly the header space for INNERMOST IP header |
|
845 * (which is also the final IP header, if no tunneling is present). Any hook, |
|
846 * that does tunneling, must include the OUTER IP header requirements into |
|
847 * the iHdrSize (a tunneling hook is ADDING the outer header!). |
|
848 */ |
|
849 TUint iHdrSize; |
|
850 private: |
|
851 /** Receives state change upcalls. Also the owner of the flow. */ |
|
852 MProviderNotify *iProvider; |
|
853 /** Storage for any other options. */ |
|
854 COptionValue *iStorage; |
|
855 }; |
|
856 |
|
857 |
|
858 inline void CFlowContext::NoBearer(const TDesC8& aConnectionParams) |
|
859 /** Passes NoBearer call to owner, if present. */ |
|
860 { |
|
861 if (iProvider) |
|
862 iProvider->NoBearer(aConnectionParams); |
|
863 } |
|
864 inline void CFlowContext::Bearer(const TDesC8 &aConnectionInfo) |
|
865 /** Passes Bearer call to owner, if present. */ |
|
866 { |
|
867 if (iProvider) |
|
868 iProvider->Bearer(aConnectionInfo); |
|
869 } |
|
870 |
|
871 inline TInt CFlowContext::CheckPolicy(const TSecurityPolicy& aPolicy, const char *aDiagnostic) |
|
872 { |
|
873 return iProvider ? iProvider->CheckPolicy(aPolicy, aDiagnostic) : KErrNone; |
|
874 } |
|
875 |
|
876 #ifdef SYMBIAN_NETWORKING_UPS |
|
877 inline TBool CFlowContext::HasProvider() const |
|
878 { |
|
879 return (iProvider != NULL); |
|
880 } |
|
881 |
|
882 inline void *CFlowContext::GetProviderApiL(const TDesC8& aApiName, TUint* aVersion) |
|
883 { |
|
884 if (iProvider == NULL) |
|
885 { |
|
886 return NULL; |
|
887 } |
|
888 else |
|
889 { |
|
890 return iProvider->GetApiL(aApiName, aVersion); |
|
891 } |
|
892 } |
|
893 |
|
894 #endif //SYMBIAN_NETWORKING_UPS |
|
895 |
|
896 // ********* |
|
897 // MFlowHook |
|
898 // ********* |
|
899 class MFlowHook : public MInetBase |
|
900 /** |
|
901 * Abstract base class for flow hooks. |
|
902 * |
|
903 * Flow hook providers implement this class. They register the hook using |
|
904 * MIp6Hook::BindFlowHook(), and return an instance from MIp6Hook::OpenL(). |
|
905 * |
|
906 * @note |
|
907 * The same instance of MFlowHook can be returned for multiple flows, |
|
908 * if the logic of the hook does not require unique instance for each flow. |
|
909 * |
|
910 * The object can be implemented as reference counted object: last reference |
|
911 * removed by Close deletes the object. |
|
912 * |
|
913 * @since v7.0 |
|
914 * @publishedPartner |
|
915 * @released |
|
916 * |
|
917 * Example: |
|
918 * @dontinclude mflowhook.cpp |
|
919 * @skip MFlowHook |
|
920 * @until //- |
|
921 */ |
|
922 { |
|
923 public: |
|
924 /** |
|
925 * Increment reference count. |
|
926 * |
|
927 * The Open and Close functions must implement a reference |
|
928 * counting system. The Close function must destroy the current |
|
929 * instance, when the last reference is removed. |
|
930 * |
|
931 * Non-NULL return from MIp6Hook::OpenL() counts as one reference, and |
|
932 * the stack is guaranteed to call the matching Close exactly once. |
|
933 * |
|
934 * If a hook creates a new instance for each flow at OpenL, it can |
|
935 * leave the reference count as initial ZERO, if it implements a |
|
936 * Close, which deletes the object when the count goes negative. |
|
937 * |
|
938 * If a hook returns an existing instance at OpenL, it must |
|
939 * increment the reference count by one. |
|
940 * |
|
941 * Example: |
|
942 * @dontinclude mflowhook.cpp |
|
943 * @skip ::Open( |
|
944 * @until //- |
|
945 */ |
|
946 virtual void Open() = 0; |
|
947 /** |
|
948 * On an interface connecting, asks the hook if a flow is ready. |
|
949 * |
|
950 * The ReadyL calls propagate interface ready state up the |
|
951 * flow. The calls to hooks are made in reverse order; |
|
952 * the closest to interface is called first. The call informs |
|
953 * this hook that everything is ready from this hook to the interface. |
|
954 * Now it this hooks turn to check the ready state of the flow. |
|
955 * |
|
956 * @param aHead |
|
957 * Address information of the flow. |
|
958 * @return |
|
959 * from the ReadyL is the new status of the flow and has the following |
|
960 * implications |
|
961 * @li == 0, hook is ready, proceed to the next one or mark the flow |
|
962 * as READY, if this was the first hook. |
|
963 * @li > 0, hook is not ready, the ready calling is stopped and the |
|
964 * returned value is the (pending) state of the flow. |
|
965 * The hook MUST send a signal later to release this state to |
|
966 * reactivate the ReadyL call chain. |
|
967 * @li < 0, hook detected an unrecoverable error on flow |
|
968 * |
|
969 * @exception |
|
970 * If the ReadyL leaves, the leave status will become |
|
971 * the flow status (the leave status must be negative, or KErrGeneral |
|
972 * is substituted for it) |
|
973 * |
|
974 * Example: |
|
975 * @dontinclude mflowhook.cpp |
|
976 * @skip ::ReadyL( |
|
977 * @until //- |
|
978 */ |
|
979 virtual TInt ReadyL(TPacketHead &aHead) = 0; |
|
980 /** |
|
981 * Apply send transformations. |
|
982 * |
|
983 * The ApplyL is called by IP protocol for outbound packet. The aPacket |
|
984 * is in "unpacked" state (RMBufPacketBase::Unpack). |
|
985 * |
|
986 * @param aPacket |
|
987 * a complete packet to be processed (if needed) by the hook. |
|
988 * The packet includes the IP header. |
|
989 * @param aInfo |
|
990 * information block associated with the packet (a hook must not |
|
991 * break this association!) |
|
992 * @return |
|
993 * @li = 0, (KErrNone) hook processed the packet, proceed with the next. |
|
994 * @li < 0, (error code) hook discarded the packet for some reason, send is |
|
995 * aborted. |
|
996 * @li > 0, restart hook processing [the actual utility of this is |
|
997 * still under consideration, maybe removed if no sensible |
|
998 * use found.] |
|
999 * |
|
1000 * @exception |
|
1001 * if ApplyL leaves, the packet is dropped. |
|
1002 * |
|
1003 * Example: |
|
1004 * @dontinclude mflowhook.cpp |
|
1005 * @skip ::ApplyL( |
|
1006 * @until //- |
|
1007 */ |
|
1008 virtual TInt ApplyL(RMBufSendPacket &aPacket, RMBufSendInfo &aInfo) = 0; |
|
1009 /** |
|
1010 * Decrement references and destroy if last. |
|
1011 * |
|
1012 * Example: |
|
1013 * @dontinclude mflowhook.cpp |
|
1014 * @skip ::Close( |
|
1015 * @until //- |
|
1016 */ |
|
1017 virtual void Close() = 0; |
|
1018 }; |
|
1019 |
|
1020 class CFlowInternalContext; |
|
1021 |
|
1022 class MFlowManager : public MInetBase |
|
1023 /** |
|
1024 * The flow manager interface. |
|
1025 * |
|
1026 * The use of MFlowManager is mostly hidden behind the RFlowContext, |
|
1027 * but the upper layer must be aware of its existence. |
|
1028 * Currently, the MFlowManager interface is included into the MnetworkService |
|
1029 * (and is implemented by the IP6 protocol instance), |
|
1030 * which must be used whenever an instance of MFlowManager is required. |
|
1031 * @since v7.0 |
|
1032 * @publishedPartner |
|
1033 * @released |
|
1034 */ |
|
1035 { |
|
1036 public: |
|
1037 /** |
|
1038 * Increase the "users" counter. |
|
1039 * |
|
1040 * The count of current "users" is used in determining whether to |
|
1041 * keep or release resources. This in turn, may cause the disconnect |
|
1042 * of a data connection. |
|
1043 * |
|
1044 * The stack leaves it up to the upper layers to decide what is counted as a |
|
1045 * "user". IncUsers() and DecUsers() should be used to give this information |
|
1046 * to the underlying system. By default, each opened socket is counted as |
|
1047 * one user. |
|
1048 */ |
|
1049 virtual void IncUsers() = 0; |
|
1050 /** |
|
1051 * Decrease the "users" counter. |
|
1052 * For details, see IncUsers(). |
|
1053 */ |
|
1054 virtual void DecUsers() = 0; |
|
1055 // |
|
1056 // Use of the following methods is through the |
|
1057 // RFlowContext handle |
|
1058 // |
|
1059 /** |
|
1060 * Creates a new (empty) instance of a CFlowContext. |
|
1061 * |
|
1062 * @param aOwner Identifies the flow's owner (typically an RFlowContext handle) |
|
1063 * @param aProtocol Protocol ID |
|
1064 * @return New object |
|
1065 */ |
|
1066 virtual CFlowContext *NewFlowL(const void *aOwner, TUint aProtocol) = 0; |
|
1067 /** |
|
1068 * Creates a copy of an instance of a CFlowContext. |
|
1069 * |
|
1070 * @param aOwner Identifies the flow's owner (typically an RFlowContext handle) |
|
1071 * @param aFlow Object to copy |
|
1072 * @return New object |
|
1073 */ |
|
1074 virtual CFlowContext *NewFlowL(const void *aOwner, CFlowContext &aFlow) = 0; |
|
1075 /** |
|
1076 * Sets the connect information changed flag on all flows. |
|
1077 * @return Number of flows. |
|
1078 */ |
|
1079 virtual TInt SetChanged() const = 0; |
|
1080 |
|
1081 |
|
1082 //protected: |
|
1083 |
|
1084 /** Internal API between flow and flow manager. @publishedPartner */ |
|
1085 virtual TInt FlowSetupHooks(CFlowInternalContext &aFlow) = 0; |
|
1086 /** Internal API between flow and flow manager. @publishedPartner */ |
|
1087 virtual void FlowStartRefresh(CFlowInternalContext &aFlow) = 0; |
|
1088 // |
|
1089 // Flow option handling |
|
1090 // |
|
1091 /** Internal API between flow and flow manager. @publishedPartner */ |
|
1092 virtual TInt GetFlowOption(TUint aLevel, TUint aName, TDes8 &aOption, const CFlowContext &aFlow) const = 0; |
|
1093 /** Internal API between flow and flow manager. @publishedPartner */ |
|
1094 virtual TInt SetFlowOption(TUint aLevel, TUint aName, const TDesC8 &aOption, CFlowContext &aFlow) = 0; |
|
1095 }; |
|
1096 |
|
1097 #endif |