113 // Open and activate the UDP socket for DNS traffic (unless already done) |
113 // Open and activate the UDP socket for DNS traffic (unless already done) |
114 TInt ActivateSocket(); |
114 TInt ActivateSocket(); |
115 // Process socket errors |
115 // Process socket errors |
116 TInt HandleError(TInt aReason, const TInetAddr *aServer = NULL); |
116 TInt HandleError(TInt aReason, const TInetAddr *aServer = NULL); |
117 // Close and deactivate the UDP socket for DNS traffic |
117 // Close and deactivate the UDP socket for DNS traffic |
118 void DeactivateSocket(TInt aReason); |
118 TBool DeactivateSocket(TInt aReason); |
119 // Handle receive compeleted, keep receiver active |
119 // Handle receive compeleted, keep receiver active |
120 void RunReader(const TMsgBuf &aMsg, const TInetAddr &aFrom); |
120 void RunReader(const TMsgBuf &aMsg, const TInetAddr &aFrom); |
121 // Handle send completed, keep sender active (if work to do) |
121 // Handle send completed, keep sender active (if work to do) |
122 void RunWriter(TRequestStatus &aStatus); |
122 void RunWriter(TRequestStatus &aStatus); |
123 //seed id generator |
123 //seed id generator |
128 inline TBool IsListen() const { return iListen != 0; } |
128 inline TBool IsListen() const { return iListen != 0; } |
129 inline TBool IsOpened() const { return iOpened; } |
129 inline TBool IsOpened() const { return iOpened; } |
130 inline void ResetErrorCount() { iErrorCount = 0;} |
130 inline void ResetErrorCount() { iErrorCount = 0;} |
131 // A link chain used by the CDnsSocket to keep track of multiple writers |
131 // A link chain used by the CDnsSocket to keep track of multiple writers |
132 CDnsSocketWriter *iNext; |
132 CDnsSocketWriter *iNext; |
|
133 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
134 RConnection iAttachedConn; //< The connection on which the DNS socket may be opened on |
|
135 #endif |
|
136 |
|
137 // Network ID associated with the writer; |
|
138 TInt iNetworkIdofWriter; |
|
139 inline void SetDeferredDelete() { iDeferredDelete = ETrue; } |
133 |
140 |
134 private: |
141 private: |
135 void RunL(); |
142 void RunL(); |
136 void DoCancel(); |
143 void DoCancel(); |
137 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
144 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
138 TBool CanUseConnection(); |
145 TBool CanUseConnection(); |
139 #endif |
146 #endif |
140 |
147 |
141 CDnsSocket &iMaster; //< The connection to the CDnsSocket owning this |
148 CDnsSocket &iMaster; //< The connection to the CDnsSocket owning this |
142 RSocket iSocket; //< The DNS socket |
149 RSocket iSocket; //< The DNS socket |
143 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
150 |
144 RConnection iAttachedConn; //< The connection on which the DNS socket may be opened on |
|
145 #endif |
|
146 TUint iDeactivateCount; //< Count number of deactivations (needed in reply processing) |
151 TUint iDeactivateCount; //< Count number of deactivations (needed in reply processing) |
147 TUint iErrorCount; //< Count number of consecutive errors in RunL (read and write) |
152 TUint iErrorCount; //< Count number of consecutive errors in RunL (read and write) |
148 TUint iListen; //< = 1, if socket is listening TCP socket, waiting on accept. |
153 TUint iListen; //< = 1, if socket is listening TCP socket, waiting on accept. |
149 TUint iTCP; //< = 1, if socket is a connected TCP socket |
154 TUint iTCP; //< = 1, if socket is a connected TCP socket |
150 TUint iOpened:1; //< = 1, if the socket is open |
155 TUint iOpened:1; //< = 1, if the socket is open |
157 TInetAddr iTo; //< Filled with the destination address of the query |
162 TInetAddr iTo; //< Filled with the destination address of the query |
158 TRequestQueue iSendQueue; //< Requests waiting to be sent |
163 TRequestQueue iSendQueue; //< Requests waiting to be sent |
159 TRequestQueue iWaitQueue; //< Requests waiting for a reply |
164 TRequestQueue iWaitQueue; //< Requests waiting for a reply |
160 TDnsRequest *iSending; //< The request currently being sent, if non-NULL |
165 TDnsRequest *iSending; //< The request currently being sent, if non-NULL |
161 CDnsSocketReader *iReader; //< The reader object |
166 CDnsSocketReader *iReader; //< The reader object |
|
167 TBool iDeferredDelete; |
162 }; |
168 }; |
163 |
169 |
164 void TDnsRequest::Cancel() |
170 void TDnsRequest::Cancel() |
165 { |
171 { |
166 CDnsSocketWriter *const writer = iQueueLink.Writer(); |
172 CDnsSocketWriter *const writer = iQueueLink.Writer(); |
191 HBufC8 *iInMsg; //< The real allocated buffer |
197 HBufC8 *iInMsg; //< The real allocated buffer |
192 TInt iAllocatedLength; //< The real max length of the buffer |
198 TInt iAllocatedLength; //< The real max length of the buffer |
193 TPtr8 iBuf; //< The current receive buffer |
199 TPtr8 iBuf; //< The current receive buffer |
194 }; |
200 }; |
195 |
201 |
196 CDnsSocketWriter::CDnsSocketWriter(CDnsSocket &aMaster) : CActive(0), iMaster(aMaster) |
202 CDnsSocketWriter::CDnsSocketWriter(CDnsSocket &aMaster) : CActive(0), iMaster(aMaster), iDeferredDelete(EFalse) |
197 { |
203 { |
198 LOG(Log::Printf(_L("CDnsSocketWriter[%u]::CDnsSocketWriter([%u])"), this, &aMaster)); |
204 LOG(Log::Printf(_L("CDnsSocketWriter[%u]::CDnsSocketWriter([%u])"), this, &aMaster)); |
|
205 iNetworkIdofWriter = -1; |
199 CActiveScheduler::Add(this); |
206 CActiveScheduler::Add(this); |
200 |
207 |
201 TTime seed; |
208 TTime seed; |
202 seed.UniversalTime(); |
209 seed.UniversalTime(); |
203 iSequence = seed.Int64(); |
210 iSequence = seed.Int64(); |
556 // this return must not try to reactivate the |
569 // this return must not try to reactivate the |
557 // reader or writer. |
570 // reader or writer. |
558 return (mark != iDeactivateCount); |
571 return (mark != iDeactivateCount); |
559 } |
572 } |
560 |
573 |
561 void CDnsSocketWriter::DeactivateSocket(TInt aReason) |
574 TBool CDnsSocketWriter::DeactivateSocket(TInt aReason) |
562 { |
575 { |
563 LOG(Log::Printf(_L("CDnsSocketWriter[%u]::DeactivateSocket() Entry"), this)); |
576 LOG(Log::Printf(_L("CDnsSocketWriter[%u]::DeactivateSocket() Entry"), this)); |
564 if (!iOpened ) |
577 if (!iOpened ) |
565 { |
578 { |
566 LOG(Log::Printf(_L("CDnsSocketWriter[%u]::DeactivateSocket() return without action"), this)); |
579 LOG(Log::Printf(_L("CDnsSocketWriter[%u]::DeactivateSocket() return without action"), this)); |
567 return; // Nothing to do if not open |
580 return ETrue; // Nothing to do if not open |
568 } |
581 } |
569 // Grab current set of requests away, so that |
582 // Grab current set of requests away, so that |
570 // potentially newly entered requests won't |
583 // potentially newly entered requests won't |
571 // get affected by this... |
584 // get affected by this... |
572 // |
585 // |
601 while ((rq = wait.Remove()) != NULL) |
614 while ((rq = wait.Remove()) != NULL) |
602 { |
615 { |
603 rq->iQueueLink.SetWriter(0); |
616 rq->iQueueLink.SetWriter(0); |
604 rq->Abort(iMaster, aReason); |
617 rq->Abort(iMaster, aReason); |
605 } |
618 } |
606 LOG(Log::Printf(_L("CDnsSocketWriter[%u]::DeactivateSocket() complete"), this)); |
619 if (iRunReader) |
|
620 { |
|
621 LOG(Log::Printf(_L("CDnsSocketWriter[%u]::DeactivateSocket() complete and defer delete"), this)); |
|
622 return EFalse; |
|
623 } |
|
624 LOG(Log::Printf(_L("CDnsSocketWriter[%u]::DeactivateSocket() complete and allow delete"), this)); |
|
625 return ETrue; |
607 } |
626 } |
608 |
627 |
609 // |
628 // |
610 // CDnsSocketWriter::Remove |
629 // CDnsSocketWriter::Remove |
611 // ************************ |
630 // ************************ |
808 } |
827 } |
809 currentInfo = info(); |
828 currentInfo = info(); |
810 |
829 |
811 LOG(Log::Printf(_L("CDnsSocketWriter[%u]::CanUseConnection() currentInfo.NetId = %d "), this, currentInfo.iNetId)); |
830 LOG(Log::Printf(_L("CDnsSocketWriter[%u]::CanUseConnection() currentInfo.NetId = %d "), this, currentInfo.iNetId)); |
812 LOG(Log::Printf(_L("CDnsSocketWriter[%u]::CanUseConnection() iMaster.iNetworkId = %d "), this, iMaster.iNetworkId)); |
831 LOG(Log::Printf(_L("CDnsSocketWriter[%u]::CanUseConnection() iMaster.iNetworkId = %d "), this, iMaster.iNetworkId)); |
813 if(currentInfo.iNetId == iMaster.iNetworkId) |
832 //if(currentInfo.iNetId == iMaster.iNetworkId) |
|
833 if(currentInfo.iNetId == this->iNetworkIdofWriter) |
814 { |
834 { |
815 foundConnection = ETrue; |
835 foundConnection = ETrue; |
816 break; |
836 break; |
817 } |
837 } |
818 } |
838 } |
930 else |
950 else |
931 { |
951 { |
932 iWriter.ResetErrorCount(); |
952 iWriter.ResetErrorCount(); |
933 iWriter.RunReader(TMsgBuf::Cast(iBuf), iFrom); |
953 iWriter.RunReader(TMsgBuf::Cast(iBuf), iFrom); |
934 } |
954 } |
935 LOG(Log::Printf(_L("<-- CDnsSocketReader[%u]::RunL() -exit- iStatus=%d"), this, iStatus.Int())); |
955 LOG(Log::Printf(_L("<-- CDnsSocketReader[%u]::RunL() -exit-"), this)); |
936 } |
956 } |
937 |
957 |
938 void CDnsSocketReader::DoCancel() |
958 void CDnsSocketReader::DoCancel() |
939 { |
959 { |
940 LOG(Log::Printf(_L("CDnsSocketReader[%u]::DoCancel()"), this)); |
960 LOG(Log::Printf(_L("CDnsSocketReader[%u]::DoCancel()"), this)); |
981 // |
1001 // |
982 // Does nothing, if socket is already active |
1002 // Does nothing, if socket is already active |
983 // |
1003 // |
984 // Leaves, if socket cannot be activated |
1004 // Leaves, if socket cannot be activated |
985 */ |
1005 */ |
986 void CDnsSocket::ActivateSocketL(TUint aNetworkId) |
1006 CDnsSocketWriter * CDnsSocket::ActivateSocketL(TUint aNetworkId) |
987 { |
1007 { |
988 LOG(Log::Printf(_L("CDnsSocket[%u]::ActivateSocketL([NetId = %d])"), this, aNetworkId)); |
1008 LOG(Log::Printf(_L("CDnsSocket[%u]::ActivateSocketL([NetId = %d])"), this, aNetworkId)); |
989 |
1009 if(!iConnected) |
990 if (iConnected && IsOpened()) |
1010 { |
991 { |
1011 LOG(Log::Printf(_L("CDnsSocket::ActivateSocketL([NetId = %d]) connecting socket server"),aNetworkId)); |
992 LOG(Log::Printf(_L("CDnsSocket[%u]::ActivateSocketL([NetId = %d]) return without action"), this, aNetworkId)); |
1012 User::LeaveIfError(iSS.Connect()); |
993 return; // Already connected, nothing to do |
1013 iConnected = 1; |
994 } |
1014 } |
995 |
1015 // use default in case of default network ID |
996 User::LeaveIfError(iSS.Connect()); |
1016 if(aNetworkId == 0) |
997 iConnected = 1; |
1017 { |
998 iNetworkId = aNetworkId; |
1018 LOG(Log::Printf(_L("CDnsSocket::ActivateSocketL([NetId = %d]) using default writer"),aNetworkId)); |
999 |
1019 if(iWriter->IsOpened()) |
1000 const TInt ret = iWriter->ActivateSocket(); |
1020 { |
1001 if (ret != KErrNone) |
1021 return iWriter; |
1002 { |
1022 } |
1003 DeactivateSocket(ret); |
1023 else |
1004 User::Leave(ret); |
1024 { |
1005 } |
1025 const TInt ret = iWriter->ActivateSocket(); |
|
1026 if(ret != KErrNone) |
|
1027 { |
|
1028 DeactivateSocket(ret); |
|
1029 User::Leave(ret); |
|
1030 } |
|
1031 else |
|
1032 { |
|
1033 return iWriter; |
|
1034 } |
|
1035 } |
|
1036 |
|
1037 } |
|
1038 else |
|
1039 { |
|
1040 LOG(Log::Printf(_L("CDnsSocket::ActivateSocketL([NetId = %d]) Looking for"),aNetworkId)); |
|
1041 // Find the appropriate writer for the network Id |
|
1042 CDnsSocketWriter *loopWriter = iWriter; |
|
1043 while (1) |
|
1044 { |
|
1045 if(loopWriter->iNetworkIdofWriter == aNetworkId) |
|
1046 { |
|
1047 LOG(Log::Printf(_L("CDnsSocket::ActivateSocketL([NetId = %d]) found"),aNetworkId)); |
|
1048 if(loopWriter->IsOpened()) |
|
1049 { |
|
1050 return loopWriter; |
|
1051 } |
|
1052 else |
|
1053 { |
|
1054 const TInt ret = loopWriter->ActivateSocket(); |
|
1055 if(ret != KErrNone) |
|
1056 { |
|
1057 DeactivateSocket(ret); |
|
1058 User::Leave(ret); |
|
1059 } |
|
1060 else |
|
1061 { |
|
1062 return loopWriter; |
|
1063 } |
|
1064 } |
|
1065 } |
|
1066 if(loopWriter->iNext == NULL) |
|
1067 { |
|
1068 break; |
|
1069 } |
|
1070 else |
|
1071 { |
|
1072 loopWriter = loopWriter->iNext; |
|
1073 } |
|
1074 } |
|
1075 LOG(Log::Printf(_L("CDnsSocket::ActivateSocketL([NetId = %d]) Creating new"),aNetworkId)); |
|
1076 // create a new writer |
|
1077 loopWriter->iNext = CDnsSocketWriter::NewL(*this, -1); |
|
1078 loopWriter->iNext->iNetworkIdofWriter = aNetworkId; |
|
1079 const TInt ret = loopWriter->iNext->ActivateSocket(); |
|
1080 if(ret != KErrNone) |
|
1081 { |
|
1082 DeactivateSocket(ret); |
|
1083 User::Leave(ret); |
|
1084 } |
|
1085 else |
|
1086 { |
|
1087 return loopWriter->iNext; |
|
1088 } |
|
1089 } |
|
1090 return NULL; |
1006 } |
1091 } |
1007 |
1092 |
1008 /** |
1093 /** |
1009 // Change the current bind address and activate the |
1094 // Change the current bind address and activate the |
1010 // DNS socket. If socket is already active, the bind |
1095 // DNS socket. If socket is already active, the bind |
1104 // |
1190 // |
1105 CDnsSocketWriter *writer = iWriter->iNext; |
1191 CDnsSocketWriter *writer = iWriter->iNext; |
1106 iWriter->iNext = NULL; |
1192 iWriter->iNext = NULL; |
1107 |
1193 |
1108 iWriter->DeactivateSocket(aReason); |
1194 iWriter->DeactivateSocket(aReason); |
|
1195 LOG(Log::Printf(_L("CDnsSocket::DeactivateSocket Deativatuing other writers"))); |
1109 while (writer) |
1196 while (writer) |
1110 { |
1197 { |
1111 CDnsSocketWriter *tmp = writer; |
1198 CDnsSocketWriter *tmp = writer; |
1112 writer = tmp->iNext; |
1199 writer = tmp->iNext; |
1113 tmp->DeactivateSocket(aReason); |
1200 LOG(Log::Printf(_L("CDnsSocket::DeactivateSocket calling deactivate socket for writer"))); |
|
1201 TBool allowedToDelete = tmp->DeactivateSocket(aReason); |
|
1202 if (allowedToDelete) |
|
1203 { |
1114 delete tmp; |
1204 delete tmp; |
|
1205 } |
|
1206 else |
|
1207 { |
|
1208 tmp->SetDeferredDelete(); |
|
1209 } |
1115 } |
1210 } |
1116 // Oops... Should not close if re-activated ---FIX! |
1211 // Oops... Should not close if re-activated ---FIX! |
1117 if (iListening) |
1212 if (iListening) |
1118 { |
1213 { |
1119 iListening = 0; |
1214 iListening = 0; |
1168 // the default if parameter is omitted. The queue |
1263 // the default if parameter is omitted. The queue |
1169 // method will assign random id automatically. |
1264 // method will assign random id automatically. |
1170 // @li >= 0, |
1265 // @li >= 0, |
1171 // 16 bits of this value is used as id. |
1266 // 16 bits of this value is used as id. |
1172 */ |
1267 */ |
1173 void CDnsSocket::Queue(TDnsRequest &aRequest, const TInt aId) |
1268 void CDnsSocket::Queue(TDnsRequest &aRequest, CDnsSocketWriter * aWriter, const TInt aId) |
1174 { |
1269 { |
1175 iWriter->Queue(aRequest, aId); |
1270 if(aWriter == NULL) |
|
1271 { |
|
1272 // use default |
|
1273 iWriter->Queue(aRequest, aId); |
|
1274 } |
|
1275 else |
|
1276 { |
|
1277 aWriter->Queue(aRequest, aId); |
|
1278 } |
1176 } |
1279 } |
1177 |
1280 |
1178 |
1281 |
1179 // Queue a request for sending with a specific socket |
1282 // Queue a request for sending with a specific socket |
1180 // |
1283 // |
1181 TInt CDnsSocket::Queue(TDnsRequest &aRequest, const RSocket &aSocket, const TInt aId) |
1284 // Though the DNS socket writer instance was passed as part of this function, but not being used as this |
1182 { |
1285 // function matches the socket to find the appropriate writer instance |
1183 for (CDnsSocketWriter *writer = iWriter; writer != NULL; writer = writer->iNext) |
1286 TInt CDnsSocket::Queue(TDnsRequest &aRequest, const RSocket &aSocket, CDnsSocketWriter */* aWriter*/, const TInt aId) |
|
1287 { |
|
1288 for (CDnsSocketWriter *writer = iWriter; writer != NULL; writer = writer->iNext) |
1184 { |
1289 { |
1185 if (&aSocket == &writer->Socket()) |
1290 if (&aSocket == &writer->Socket()) |
1186 { |
1291 { |
1187 // Found it! |
1292 // Found it! |
1188 writer->Queue(aRequest, aId); |
1293 writer->Queue(aRequest, aId); |
1189 return KErrNone; |
1294 return KErrNone; |
1190 } |
1295 } |
1191 } |
1296 } |
|
1297 |
1192 return KErrNotFound; |
1298 return KErrNotFound; |
1193 } |
1299 } |
1194 |
1300 |
1195 |
1301 |
1196 /** |
1302 /** |
1202 // @param aTTL of the connection (= -1, the default, requests the system default). This is |
1308 // @param aTTL of the connection (= -1, the default, requests the system default). This is |
1203 // only effective if the connection is created. |
1309 // only effective if the connection is created. |
1204 // |
1310 // |
1205 // @return KErrNone, if queued successfully, or error code if failed. |
1311 // @return KErrNone, if queued successfully, or error code if failed. |
1206 */ |
1312 */ |
1207 TInt CDnsSocket::Queue(TDnsRequest &aRequest, const TInetAddr &aServer, const TInt aId, const TInt aTTL) |
1313 TInt CDnsSocket::Queue(TDnsRequest &aRequest, const TInetAddr &aServer, CDnsSocketWriter * /*aWriter*/, const TInt aId, const TInt aTTL) |
1208 { |
1314 { |
1209 // |
1315 // |
1210 // Locate or create connected Socket reader/writer instance |
1316 // Locate or create connected Socket reader/writer instance |
1211 // |
1317 // |
1212 CDnsSocketWriter *writer = iWriter->iNext; |
1318 CDnsSocketWriter *writer = iWriter->iNext; |
1246 // should happen). This preserves the old id of the request. |
1352 // should happen). This preserves the old id of the request. |
1247 // |
1353 // |
1248 // If a request is not currently queued, this does an implicit |
1354 // If a request is not currently queued, this does an implicit |
1249 // Queue. (a new id is generated). |
1355 // Queue. (a new id is generated). |
1250 // |
1356 // |
1251 // Exceptionally, the request assigns new ID when an incomplete query name |
|
1252 // is iterated to apply multiple domain suffices on |
|
1253 // the interface being used for sending requests |
|
1254 // |
|
1255 // @param aRequest the request to be resent. |
1357 // @param aRequest the request to be resent. |
1256 // @param aRetryWithSuffix flag set to identify retry requests |
|
1257 // on incomplete query names. Defaulted to FALSE |
|
1258 */ |
1358 */ |
1259 void CDnsSocket::ReSend(TDnsRequest &aRequest, TBool aRetryWithSuffix) |
1359 void CDnsSocket::ReSend(TDnsRequest &aRequest, CDnsSocketWriter * aWriter) |
1260 { |
1360 { |
1261 Queue(aRequest, (!aRetryWithSuffix && aRequest.IsQueued()) ? aRequest.Id() : -1); |
1361 Queue(aRequest, aWriter, aRequest.IsQueued() ? aRequest.Id() : -1); |
1262 } |
1362 } |
1263 |
1363 |
1264 /** |
1364 /** |
1265 // Add and activate a new secondary writer/reader unit. |
1365 // Add and activate a new secondary writer/reader unit. |
1266 // |
1366 // |