hal/gonk/UeventPoller.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* Copyright 2012 Mozilla Foundation and Mozilla contributors
michael@0 3 *
michael@0 4 * Licensed under the Apache License, Version 2.0 (the "License");
michael@0 5 * you may not use this file except in compliance with the License.
michael@0 6 * You may obtain a copy of the License at
michael@0 7 *
michael@0 8 * http://www.apache.org/licenses/LICENSE-2.0
michael@0 9 *
michael@0 10 * Unless required by applicable law or agreed to in writing, software
michael@0 11 * distributed under the License is distributed on an "AS IS" BASIS,
michael@0 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
michael@0 13 * See the License for the specific language governing permissions and
michael@0 14 * limitations under the License.
michael@0 15 */
michael@0 16
michael@0 17 #include <errno.h>
michael@0 18 #include <fcntl.h>
michael@0 19 #include <pthread.h>
michael@0 20 #include <signal.h>
michael@0 21 #include <string.h>
michael@0 22 #include <strings.h>
michael@0 23 #include <unistd.h>
michael@0 24
michael@0 25 #include <arpa/inet.h>
michael@0 26 #include <linux/types.h>
michael@0 27 #include <linux/netlink.h>
michael@0 28 #include <netinet/in.h>
michael@0 29 #include <sys/socket.h>
michael@0 30
michael@0 31 #include "nsDebug.h"
michael@0 32 #include "base/message_loop.h"
michael@0 33 #include "mozilla/FileUtils.h"
michael@0 34 #include "nsAutoPtr.h"
michael@0 35 #include "nsThreadUtils.h"
michael@0 36 #include "nsXULAppAPI.h"
michael@0 37
michael@0 38 #include "UeventPoller.h"
michael@0 39
michael@0 40 namespace mozilla {
michael@0 41 namespace hal_impl {
michael@0 42
michael@0 43 static void ShutdownUevent();
michael@0 44
michael@0 45 class NetlinkPoller : public MessageLoopForIO::Watcher
michael@0 46 {
michael@0 47 public:
michael@0 48 NetlinkPoller() : mSocket(-1),
michael@0 49 mIOLoop(MessageLoopForIO::current())
michael@0 50 {
michael@0 51 }
michael@0 52
michael@0 53 virtual ~NetlinkPoller() {}
michael@0 54
michael@0 55 bool OpenSocket();
michael@0 56
michael@0 57 virtual void OnFileCanReadWithoutBlocking(int fd);
michael@0 58
michael@0 59 // no writing to the netlink socket
michael@0 60 virtual void OnFileCanWriteWithoutBlocking(int fd)
michael@0 61 {
michael@0 62 MOZ_CRASH("Must not write to netlink socket");
michael@0 63 }
michael@0 64
michael@0 65 MessageLoopForIO *GetIOLoop () const { return mIOLoop; }
michael@0 66 void RegisterObserver(IUeventObserver *aObserver)
michael@0 67 {
michael@0 68 mUeventObserverList.AddObserver(aObserver);
michael@0 69 }
michael@0 70
michael@0 71 void UnregisterObserver(IUeventObserver *aObserver)
michael@0 72 {
michael@0 73 mUeventObserverList.RemoveObserver(aObserver);
michael@0 74 if (mUeventObserverList.Length() == 0)
michael@0 75 ShutdownUevent(); // this will destroy self
michael@0 76 }
michael@0 77
michael@0 78 private:
michael@0 79 ScopedClose mSocket;
michael@0 80 MessageLoopForIO* mIOLoop;
michael@0 81 MessageLoopForIO::FileDescriptorWatcher mReadWatcher;
michael@0 82
michael@0 83 const static int kBuffsize = 64 * 1024;
michael@0 84 uint8_t mBuffer [kBuffsize];
michael@0 85
michael@0 86 typedef ObserverList<NetlinkEvent> UeventObserverList;
michael@0 87 UeventObserverList mUeventObserverList;
michael@0 88 };
michael@0 89
michael@0 90 bool
michael@0 91 NetlinkPoller::OpenSocket()
michael@0 92 {
michael@0 93 mSocket.rwget() = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
michael@0 94 if (mSocket.get() < 0)
michael@0 95 return false;
michael@0 96
michael@0 97 int sz = kBuffsize;
michael@0 98
michael@0 99 if (setsockopt(mSocket.get(), SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)) < 0)
michael@0 100 return false;
michael@0 101
michael@0 102 // add FD_CLOEXEC flag
michael@0 103 int flags = fcntl(mSocket.get(), F_GETFD);
michael@0 104 if (flags == -1) {
michael@0 105 return false;
michael@0 106 }
michael@0 107 flags |= FD_CLOEXEC;
michael@0 108 if (fcntl(mSocket.get(), F_SETFD, flags) == -1)
michael@0 109 return false;
michael@0 110
michael@0 111 // set non-blocking
michael@0 112 if (fcntl(mSocket.get(), F_SETFL, O_NONBLOCK) == -1)
michael@0 113 return false;
michael@0 114
michael@0 115 struct sockaddr_nl saddr;
michael@0 116 bzero(&saddr, sizeof(saddr));
michael@0 117 saddr.nl_family = AF_NETLINK;
michael@0 118 saddr.nl_groups = 1;
michael@0 119 saddr.nl_pid = gettid();
michael@0 120
michael@0 121 do {
michael@0 122 if (bind(mSocket.get(), (struct sockaddr *)&saddr, sizeof(saddr)) == 0) {
michael@0 123 break;
michael@0 124 }
michael@0 125
michael@0 126 if (errno != EADDRINUSE) {
michael@0 127 return false;
michael@0 128 }
michael@0 129
michael@0 130 if (saddr.nl_pid == 0) {
michael@0 131 return false;
michael@0 132 }
michael@0 133
michael@0 134 // Once there was any other place in the same process assigning saddr.nl_pid by
michael@0 135 // gettid(), we can detect it and print warning message.
michael@0 136 printf_stderr("The netlink socket address saddr.nl_pid=%u is in use. Let the kernel re-assign.\n", saddr.nl_pid);
michael@0 137 saddr.nl_pid = 0;
michael@0 138 } while (true);
michael@0 139
michael@0 140 if (!mIOLoop->WatchFileDescriptor(mSocket.get(),
michael@0 141 true,
michael@0 142 MessageLoopForIO::WATCH_READ,
michael@0 143 &mReadWatcher,
michael@0 144 this)) {
michael@0 145 return false;
michael@0 146 }
michael@0 147
michael@0 148 return true;
michael@0 149 }
michael@0 150
michael@0 151 static nsAutoPtr<NetlinkPoller> sPoller;
michael@0 152
michael@0 153 class UeventInitTask : public Task
michael@0 154 {
michael@0 155 virtual void Run()
michael@0 156 {
michael@0 157 if (!sPoller) {
michael@0 158 return;
michael@0 159 }
michael@0 160 if (sPoller->OpenSocket()) {
michael@0 161 return;
michael@0 162 }
michael@0 163 sPoller->GetIOLoop()->PostDelayedTask(FROM_HERE, new UeventInitTask(), 1000);
michael@0 164 }
michael@0 165 };
michael@0 166
michael@0 167 void
michael@0 168 NetlinkPoller::OnFileCanReadWithoutBlocking(int fd)
michael@0 169 {
michael@0 170 MOZ_ASSERT(fd == mSocket.get());
michael@0 171 while (true) {
michael@0 172 int ret = read(fd, mBuffer, kBuffsize);
michael@0 173 if (ret == -1) {
michael@0 174 if (errno == EAGAIN || errno == EWOULDBLOCK) {
michael@0 175 return;
michael@0 176 }
michael@0 177 if (errno == EINTR) {
michael@0 178 continue;
michael@0 179 }
michael@0 180 }
michael@0 181 if (ret <= 0) {
michael@0 182 // fatal error on netlink socket which should not happen
michael@0 183 _exit(1);
michael@0 184 }
michael@0 185 NetlinkEvent netlinkEvent;
michael@0 186 netlinkEvent.decode(reinterpret_cast<char*>(mBuffer), ret);
michael@0 187 mUeventObserverList.Broadcast(netlinkEvent);
michael@0 188 }
michael@0 189 }
michael@0 190
michael@0 191 static void
michael@0 192 InitializeUevent()
michael@0 193 {
michael@0 194 MOZ_ASSERT(!sPoller);
michael@0 195 sPoller = new NetlinkPoller();
michael@0 196 sPoller->GetIOLoop()->PostTask(FROM_HERE, new UeventInitTask());
michael@0 197
michael@0 198 }
michael@0 199
michael@0 200 static void
michael@0 201 ShutdownUevent()
michael@0 202 {
michael@0 203 sPoller = nullptr;
michael@0 204 }
michael@0 205
michael@0 206 void
michael@0 207 RegisterUeventListener(IUeventObserver *aObserver)
michael@0 208 {
michael@0 209 MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
michael@0 210
michael@0 211 if (!sPoller)
michael@0 212 InitializeUevent();
michael@0 213 sPoller->RegisterObserver(aObserver);
michael@0 214 }
michael@0 215
michael@0 216 void
michael@0 217 UnregisterUeventListener(IUeventObserver *aObserver)
michael@0 218 {
michael@0 219 MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
michael@0 220
michael@0 221 sPoller->UnregisterObserver(aObserver);
michael@0 222 }
michael@0 223
michael@0 224 } // hal_impl
michael@0 225 } // mozilla
michael@0 226

mercurial