Changeset 55856 in vbox
- Timestamp:
- May 13, 2015 9:01:06 PM (9 years ago)
- Location:
- trunk/src/VBox/Devices/Network/slirp
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/slirp/ip_icmp.c
r53776 r55856 90 90 }; 91 91 92 static void icmp_cache_clean(PNATState pData, int iEntries);93 92 94 93 int … … 99 98 100 99 #ifndef RT_OS_WINDOWS 100 TAILQ_INIT(&pData->icmp_msg_head); 101 101 102 if (iIcmpCacheLimit < 0) 102 103 { … … 129 130 fd_nonblock(pData->icmp_socket.s); 130 131 NSOCK_INC(); 131 132 LIST_INIT(&pData->icmp_msg_head);133 134 132 #else /* RT_OS_WINDOWS */ 135 133 if (icmpwin_init(pData) != 0) … … 149 147 icmpwin_finit(pData); 150 148 #else 151 icmp_cache_clean(pData, -1); 149 while (!TAILQ_EMPTY(&pData->icmp_msg_head)) 150 { 151 struct icmp_msg *icm = TAILQ_FIRST(&pData->icmp_msg_head); 152 icmp_msg_delete(pData, icm); 153 } 152 154 closesocket(pData->icmp_socket.s); 153 155 #endif 154 156 } 155 157 158 156 159 #if !defined(RT_OS_WINDOWS) 160 static struct icmp_msg * 161 icmp_msg_alloc(PNATState pData) 162 { 163 struct icmp_msg *icm; 164 165 #ifdef DEBUG 166 { 167 int iTally = 0; 168 TAILQ_FOREACH(icm, &pData->icmp_msg_head, im_queue) 169 ++iTally; 170 Assert(pData->cIcmpCacheSize == iTally); 171 } 172 #endif 173 174 if (pData->cIcmpCacheSize >= pData->iIcmpCacheLimit) 175 { 176 int cTargetCacheSize = pData->iIcmpCacheLimit/2; 177 178 while (pData->cIcmpCacheSize > cTargetCacheSize) 179 { 180 icm = TAILQ_FIRST(&pData->icmp_msg_head); 181 icmp_msg_delete(pData, icm); 182 } 183 } 184 185 icm = RTMemAlloc(sizeof(struct icmp_msg)); 186 if (RT_UNLIKELY(icm == NULL)) 187 return NULL; 188 189 TAILQ_INSERT_TAIL(&pData->icmp_msg_head, icm, im_queue); 190 pData->cIcmpCacheSize++; 191 192 return icm; 193 } 194 195 196 static void 197 icmp_attach(PNATState pData, struct mbuf *m) 198 { 199 struct icmp_msg *icm; 200 201 #ifdef DEBUG 202 { 203 /* only used for ping */ 204 struct ip *ip = mtod(m, struct ip *); 205 Assert(ip->ip_p == IPPROTO_ICMP); 206 } 207 #endif 208 209 icm = icmp_msg_alloc(pData); 210 if (RT_UNLIKELY(icm == NULL)) 211 return; 212 213 icm->im_so = &pData->icmp_socket; 214 icm->im_m = m; 215 } 216 217 218 void 219 icmp_msg_delete(PNATState pData, struct icmp_msg *icm) 220 { 221 if (RT_UNLIKELY(icm == NULL)) 222 return; 223 224 #ifdef DEBUG 225 { 226 struct icmp_msg *existing; 227 int iTally = 0; 228 229 TAILQ_FOREACH(existing, &pData->icmp_msg_head, im_queue) 230 ++iTally; 231 Assert(pData->cIcmpCacheSize == iTally); 232 233 Assert(pData->cIcmpCacheSize > 0); 234 TAILQ_FOREACH(existing, &pData->icmp_msg_head, im_queue) 235 { 236 if (existing == icm) 237 break; 238 } 239 Assert(existing != NULL); 240 } 241 #endif 242 243 TAILQ_REMOVE(&pData->icmp_msg_head, icm, im_queue); 244 pData->cIcmpCacheSize--; 245 246 icm->im_so->so_m = NULL; 247 if (icm->im_m != NULL) 248 m_freem(pData, icm->im_m); 249 250 RTMemFree(icm); 251 } 252 253 157 254 /* 158 255 * ip here is ip header + 64bytes readed from ICMP packet … … 185 282 case IPPROTO_ICMP: 186 283 icp = (struct icmp *)((char *)ip + (ip->ip_hl << 2)); 187 LIST_FOREACH(icm, &pData->icmp_msg_head, im_list)284 TAILQ_FOREACH(icm, &pData->icmp_msg_head, im_queue) 188 285 { 189 286 m0 = icm->im_m; … … 250 347 found = 1; 251 348 so = last_socket; 252 goto sofound;349 break; 253 350 } 254 351 for (so = head_socket->so_prev; so != head_socket; so = so->so_prev) … … 269 366 Log(("NAT:ICMP: unsupported protocol(%d)\n", ip->ip_p)); 270 367 } 271 sofound: 272 if (found == 1 && icm == NULL) 273 { 368 369 #ifdef DEBUG 370 if (found) 371 Assert((icm != NULL) ^ (so != NULL)); 372 #endif 373 374 if (found && icm == NULL) 375 { 376 /* 377 * XXX: Implies this is not a pong, found socket. This is, of 378 * course, wasteful since the caller will delete icmp_msg 379 * immediately after processing, so there's not much reason to 380 * clutter up the queue with it. 381 */ 382 AssertReturn(so != NULL, NULL); 383 384 /* 385 * XXX: FIXME: If the very first send(2) fails, the socket is 386 * still in SS_NOFDREF and so we will not report this too. 387 */ 274 388 if (so->so_state == SS_NOFDREF) 275 389 { 276 /* socket is shutdowning we've already sent ICMP on it.*/ 277 Log(("NAT: Received icmp on shutdowning socket (probably corresponding ICMP socket has been already sent)\n")); 390 /* socket is shutting down we've already sent ICMP on it. */ 391 Log(("NAT:ICMP: disconnected %R[natsock]\n", so)); 392 LogFlowFunc(("LEAVE: icm:NULL\n")); 278 393 return NULL; 279 394 } 280 icm = RTMemAlloc(sizeof(struct icmp_msg)); 395 396 if (so->so_m == NULL) 397 { 398 Log(("NAT:ICMP: no saved mbuf for %R[natsock]\n", so)); 399 LogFlowFunc(("LEAVE: icm:NULL\n")); 400 return NULL; 401 } 402 403 icm = icmp_msg_alloc(pData); 404 if (RT_UNLIKELY(icm == NULL)) 405 { 406 LogFlowFunc(("LEAVE: icm:NULL\n")); 407 return NULL; 408 } 409 410 Log(("NAT:ICMP: for %R[natsock]\n", so)); 411 icm->im_so = so; 281 412 icm->im_m = so->so_m; 282 icm->im_so = so; 283 found = 1; 284 Log(("hit:%R[natsock]\n", so)); 285 /*XXX: this storage not very long, 286 * better add flag if it should removed from lis 287 */ 288 LIST_INSERT_HEAD(&pData->icmp_msg_head, icm, im_list); 289 pData->cIcmpCacheSize++; 290 if (pData->cIcmpCacheSize > pData->iIcmpCacheLimit) 291 icmp_cache_clean(pData, pData->iIcmpCacheLimit/2); 292 LogFlowFunc(("LEAVE: icm:%p\n", icm)); 293 return (icm); 294 } 295 if (found == 1) 296 { 297 LogFlowFunc(("LEAVE: icm:%p\n", icm)); 298 return icm; 299 } 300 301 LogFlowFunc(("LEAVE: NULL\n")); 302 return NULL; 303 } 304 305 /** 306 * iEntries how many entries to leave, if iEntries < 0, clean all 307 */ 308 static void icmp_cache_clean(PNATState pData, int iEntries) 309 { 310 int iIcmpCount = 0; 311 struct icmp_msg *icm = NULL; 312 LogFlowFunc(("iEntries:%d\n", iEntries)); 313 if (iEntries > pData->cIcmpCacheSize) 314 { 315 LogFlowFuncLeave(); 316 return; 317 } 318 while(!LIST_EMPTY(&pData->icmp_msg_head)) 319 { 320 icm = LIST_FIRST(&pData->icmp_msg_head); 321 if ( iEntries > 0 322 && iIcmpCount < iEntries) 323 { 324 iIcmpCount++; 325 continue; 326 } 327 328 LIST_REMOVE(icm, im_list); 329 if (icm->im_m) 330 { 331 pData->cIcmpCacheSize--; 332 m_freem(pData, icm->im_m); 333 } 334 RTMemFree(icm); 335 } 336 LogFlowFuncLeave(); 337 } 338 339 static int 340 icmp_attach(PNATState pData, struct mbuf *m) 341 { 342 struct icmp_msg *icm; 343 struct ip *ip; 344 ip = mtod(m, struct ip *); 345 Assert(ip->ip_p == IPPROTO_ICMP); 346 icm = RTMemAlloc(sizeof(struct icmp_msg)); 347 icm->im_m = m; 348 icm->im_so = m->m_so; 349 LIST_INSERT_HEAD(&pData->icmp_msg_head, icm, im_list); 350 pData->cIcmpCacheSize++; 351 if (pData->cIcmpCacheSize > pData->iIcmpCacheLimit) 352 icmp_cache_clean(pData, pData->iIcmpCacheLimit/2); 353 return 0; 413 } 414 LogFlowFunc(("LEAVE: icm:%p\n", icm)); 415 return icm; 354 416 } 355 417 #endif /* !RT_OS_WINDOWS */ 418 356 419 357 420 /* … … 480 543 if (rc >= 0) 481 544 { 482 m->m_so = &pData->icmp_socket;483 545 icmp_attach(pData, m); 484 546 /* don't let m_freem at the end free atached buffer */ -
trunk/src/VBox/Devices/Network/slirp/ip_icmp.h
r53399 r55856 192 192 struct icmp_msg 193 193 { 194 LIST_ENTRY(icmp_msg) im_list;194 TAILQ_ENTRY(icmp_msg) im_queue; 195 195 struct mbuf *im_m; 196 196 struct socket *im_so; 197 197 }; 198 198 199 LIST_HEAD(icmp_storage, icmp_msg);199 TAILQ_HEAD(icmp_storage, icmp_msg); 200 200 201 201 int icmp_init (PNATState , int); 202 202 void icmp_finit (PNATState ); 203 203 struct icmp_msg * icmp_find_original_mbuf (PNATState , struct ip *); 204 void icmp_msg_delete(PNATState, struct icmp_msg *); 204 205 205 206 #ifdef RT_OS_WINDOWS -
trunk/src/VBox/Devices/Network/slirp/socket.c
r55741 r55856 1228 1228 { 1229 1229 LogFunc(("%R[natsock] hasn't stored it's mbuf on sent\n", icm->im_so)); 1230 LIST_REMOVE(icm, im_list); 1231 RTMemFree(icm); 1232 return; 1230 goto done; 1233 1231 } 1234 1232 … … 1241 1239 { 1242 1240 Log(("NAT: we haven't found echo for this reply\n")); 1243 return;1241 goto done; 1244 1242 } 1245 1243 /* … … 1254 1252 Log(("NAT: ECHO(%d) lenght doesn't match ECHOREPLY(%d)\n", 1255 1253 (ip->ip_len - hlen), (ip0->ip_len - (ip0->ip_hl << 2)))); 1256 return;1254 goto done; 1257 1255 } 1258 1256 } … … 1297 1295 /* m was freed */ 1298 1296 icm->im_m = NULL; 1299 icm->im_so->so_m = NULL; 1300 LIST_REMOVE(icm, im_list); 1301 pData->cIcmpCacheSize--; 1302 RTMemFree(icm); 1297 1298 done: 1299 icmp_msg_delete(pData, icm); 1303 1300 } 1304 1301
Note:
See TracChangeset
for help on using the changeset viewer.

