NetworkDataCountLayer.cpp (4548B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "NetworkDataCountLayer.h" 8 #include "nsSocketTransportService2.h" 9 #include "prmem.h" 10 #include "prio.h" 11 12 namespace mozilla { 13 namespace net { 14 15 static PRDescIdentity sNetworkDataCountLayerIdentity; 16 static PRIOMethods sNetworkDataCountLayerMethods; 17 static PRIOMethods* sNetworkDataCountLayerMethodsPtr = nullptr; 18 19 class NetworkDataCountSecret { 20 public: 21 NetworkDataCountSecret() = default; 22 23 uint64_t mSentBytes = 0; 24 uint64_t mReceivedBytes = 0; 25 }; 26 27 static PRInt32 NetworkDataCountSend(PRFileDesc* fd, const void* buf, 28 PRInt32 amount, PRIntn flags, 29 PRIntervalTime timeout) { 30 MOZ_RELEASE_ASSERT(fd->identity == sNetworkDataCountLayerIdentity); 31 32 NetworkDataCountSecret* secret = 33 reinterpret_cast<NetworkDataCountSecret*>(fd->secret); 34 35 PRInt32 rv = 36 (fd->lower->methods->send)(fd->lower, buf, amount, flags, timeout); 37 if (rv > 0) { 38 secret->mSentBytes += rv; 39 } 40 return rv; 41 } 42 43 static PRInt32 NetworkDataCountWrite(PRFileDesc* fd, const void* buf, 44 PRInt32 amount) { 45 return NetworkDataCountSend(fd, buf, amount, 0, PR_INTERVAL_NO_WAIT); 46 } 47 48 static PRInt32 NetworkDataCountRecv(PRFileDesc* fd, void* buf, PRInt32 amount, 49 PRIntn flags, PRIntervalTime timeout) { 50 MOZ_RELEASE_ASSERT(fd->identity == sNetworkDataCountLayerIdentity); 51 52 NetworkDataCountSecret* secret = 53 reinterpret_cast<NetworkDataCountSecret*>(fd->secret); 54 55 PRInt32 rv = 56 (fd->lower->methods->recv)(fd->lower, buf, amount, flags, timeout); 57 if (rv > 0) { 58 secret->mReceivedBytes += rv; 59 } 60 return rv; 61 } 62 63 static PRInt32 NetworkDataCountRead(PRFileDesc* fd, void* buf, PRInt32 amount) { 64 return NetworkDataCountRecv(fd, buf, amount, 0, PR_INTERVAL_NO_WAIT); 65 } 66 67 static PRStatus NetworkDataCountClose(PRFileDesc* fd) { 68 if (!fd) { 69 return PR_FAILURE; 70 } 71 72 PRFileDesc* layer = PR_PopIOLayer(fd, PR_TOP_IO_LAYER); 73 74 MOZ_RELEASE_ASSERT(layer && layer->identity == sNetworkDataCountLayerIdentity, 75 "NetworkDataCount Layer not on top of stack"); 76 77 NetworkDataCountSecret* secret = 78 reinterpret_cast<NetworkDataCountSecret*>(layer->secret); 79 layer->secret = nullptr; 80 layer->dtor(layer); 81 delete secret; 82 return fd->methods->close(fd); 83 } 84 85 nsresult AttachNetworkDataCountLayer(PRFileDesc* fd) { 86 if (!sNetworkDataCountLayerMethodsPtr) { 87 sNetworkDataCountLayerIdentity = 88 PR_GetUniqueIdentity("NetworkDataCount Layer"); 89 sNetworkDataCountLayerMethods = *PR_GetDefaultIOMethods(); 90 sNetworkDataCountLayerMethods.send = NetworkDataCountSend; 91 sNetworkDataCountLayerMethods.write = NetworkDataCountWrite; 92 sNetworkDataCountLayerMethods.recv = NetworkDataCountRecv; 93 sNetworkDataCountLayerMethods.read = NetworkDataCountRead; 94 sNetworkDataCountLayerMethods.close = NetworkDataCountClose; 95 sNetworkDataCountLayerMethodsPtr = &sNetworkDataCountLayerMethods; 96 } 97 98 PRFileDesc* layer = PR_CreateIOLayerStub(sNetworkDataCountLayerIdentity, 99 sNetworkDataCountLayerMethodsPtr); 100 101 if (!layer) { 102 return NS_ERROR_FAILURE; 103 } 104 105 NetworkDataCountSecret* secret = new NetworkDataCountSecret(); 106 107 layer->secret = reinterpret_cast<PRFilePrivate*>(secret); 108 109 PRStatus status = PR_PushIOLayer(fd, PR_NSPR_IO_LAYER, layer); 110 111 if (status == PR_FAILURE) { 112 delete secret; 113 PR_Free(layer); // PR_CreateIOLayerStub() uses PR_Malloc(). 114 return NS_ERROR_FAILURE; 115 } 116 return NS_OK; 117 } 118 119 void NetworkDataCountSent(PRFileDesc* fd, uint64_t& sentBytes) { 120 PRFileDesc* ndcFd = PR_GetIdentitiesLayer(fd, sNetworkDataCountLayerIdentity); 121 MOZ_RELEASE_ASSERT(ndcFd); 122 123 NetworkDataCountSecret* secret = 124 reinterpret_cast<NetworkDataCountSecret*>(ndcFd->secret); 125 sentBytes = secret->mSentBytes; 126 } 127 128 void NetworkDataCountReceived(PRFileDesc* fd, uint64_t& receivedBytes) { 129 PRFileDesc* ndcFd = PR_GetIdentitiesLayer(fd, sNetworkDataCountLayerIdentity); 130 MOZ_RELEASE_ASSERT(ndcFd); 131 132 NetworkDataCountSecret* secret = 133 reinterpret_cast<NetworkDataCountSecret*>(ndcFd->secret); 134 receivedBytes = secret->mReceivedBytes; 135 } 136 137 } // namespace net 138 } // namespace mozilla