bool UDPSocketParent::RecvBind(const UDPAddressInfo& aAddressInfo, const bool& aAddressReuse, const bool& aLoopback) { UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, aAddressInfo.addr().get(), aAddressInfo.port())); if (NS_FAILED(BindInternal(aAddressInfo.addr(), aAddressInfo.port(), aAddressReuse, aLoopback))) { FireInternalError(__LINE__); return true; } nsCOMPtr<nsINetAddr> localAddr; mSocket->GetLocalAddr(getter_AddRefs(localAddr)); nsCString addr; if (NS_FAILED(localAddr->GetAddress(addr))) { FireInternalError(__LINE__); return true; } uint16_t port; if (NS_FAILED(localAddr->GetPort(&port))) { FireInternalError(__LINE__); return true; } UDPSOCKET_LOG(("%s: SendCallbackOpened: %s:%u", __FUNCTION__, addr.get(), port)); mozilla::unused << SendCallbackOpened(UDPAddressInfo(addr, port)); return true; }
bool UDPSocketParent::Init(const nsCString &aHost, const uint16_t aPort) { nsresult rv; NS_ASSERTION(mFilter, "No packet filter"); nsCOMPtr<nsIUDPSocket> sock = do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv); if (NS_FAILED(rv)) { FireInternalError(this, __LINE__); return true; } if (aHost.IsEmpty()) { rv = sock->Init(aPort, false); } else { PRNetAddr prAddr; PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr); PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr); if (status != PR_SUCCESS) { FireInternalError(this, __LINE__); return true; } mozilla::net::NetAddr addr; PRNetAddrToNetAddr(&prAddr, &addr); rv = sock->InitWithAddress(&addr); } if (NS_FAILED(rv)) { FireInternalError(this, __LINE__); return true; } mSocket = sock; net::NetAddr localAddr; mSocket->GetAddress(&localAddr); uint16_t port; nsCString addr; rv = ConvertNetAddrToString(localAddr, &addr, &port); if (NS_FAILED(rv)) { FireInternalError(this, __LINE__); return true; } // register listener mSocket->AsyncListen(this); mozilla::unused << PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("onopen"), UDPAddressInfo(addr, port), NS_LITERAL_CSTRING("connected")); return true; }
void UDPSocketParent::Send(const InputStreamParams& aStream, const UDPSocketAddr& aAddr) { nsTArray<mozilla::ipc::FileDescriptor> fds; nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(aStream, fds); if (NS_WARN_IF(!stream)) { return; } nsresult rv; switch(aAddr.type()) { case UDPSocketAddr::TUDPAddressInfo: { const UDPAddressInfo& addrInfo(aAddr.get_UDPAddressInfo()); rv = mSocket->SendBinaryStream(addrInfo.addr(), addrInfo.port(), stream); break; } case UDPSocketAddr::TNetAddr: { const NetAddr& addr(aAddr.get_NetAddr()); rv = mSocket->SendBinaryStreamWithAddress(&addr, stream); break; } default: MOZ_ASSERT(false, "Invalid address type!"); return; } if (NS_FAILED(rv)) { FireInternalError(__LINE__); } }
void UDPSocketParent::Send(const InfallibleTArray<uint8_t>& aData, const UDPSocketAddr& aAddr) { nsresult rv; uint32_t count; switch(aAddr.type()) { case UDPSocketAddr::TUDPAddressInfo: { const UDPAddressInfo& addrInfo(aAddr.get_UDPAddressInfo()); rv = mSocket->Send(addrInfo.addr(), addrInfo.port(), aData.Elements(), aData.Length(), &count); break; } case UDPSocketAddr::TNetAddr: { const NetAddr& addr(aAddr.get_NetAddr()); rv = mSocket->SendWithAddress(&addr, aData.Elements(), aData.Length(), &count); break; } default: MOZ_ASSERT(false, "Invalid address type!"); return; } if (NS_WARN_IF(NS_FAILED(rv)) || count == 0) { FireInternalError(__LINE__); } }
mozilla::ipc::IPCResult UDPSocketParent::RecvLeaveMulticast( const nsCString& aMulticastAddress, const nsCString& aInterface) { if (!mSocket) { NS_WARNING("multicast socket is closed"); FireInternalError(__LINE__); return IPC_OK(); } nsresult rv = mSocket->LeaveMulticast(aMulticastAddress, aInterface); if (NS_WARN_IF(NS_FAILED(rv))) { FireInternalError(__LINE__); } return IPC_OK(); }
bool UDPSocketParent::RecvLeaveMulticast(const nsCString& aMulticastAddress, const nsCString& aInterface) { nsresult rv = mSocket->LeaveMulticast(aMulticastAddress, aInterface); if (NS_WARN_IF(NS_FAILED(rv))) { FireInternalError(__LINE__); } return true; }
mozilla::ipc::IPCResult UDPSocketParent::RecvJoinMulticast(const nsCString& aMulticastAddress, const nsCString& aInterface) { nsresult rv = mSocket->JoinMulticast(aMulticastAddress, aInterface); if (NS_WARN_IF(NS_FAILED(rv))) { FireInternalError(__LINE__); } return IPC_OK(); }
NS_IMETHODIMP UDPSocketParent::OnPacketReceived(nsIUDPSocket* aSocket, nsIUDPMessage* aMessage) { // receiving packet from remote host, forward the message content to child process if (!mIPCOpen) { return NS_OK; } uint16_t port; nsCString ip; nsCOMPtr<nsINetAddr> fromAddr; aMessage->GetFromAddr(getter_AddRefs(fromAddr)); fromAddr->GetPort(&port); fromAddr->GetAddress(ip); nsCString data; aMessage->GetData(data); const char* buffer = data.get(); uint32_t len = data.Length(); UDPSOCKET_LOG(("%s: %s:%u, length %u", __FUNCTION__, ip.get(), port, len)); if (mFilter) { bool allowed; mozilla::net::NetAddr addr; fromAddr->GetNetAddr(&addr); nsresult rv = mFilter->FilterPacket(&addr, (const uint8_t*)buffer, len, nsIUDPSocketFilter::SF_INCOMING, &allowed); // Receiving unallowed data, drop. if (NS_WARN_IF(NS_FAILED(rv)) || !allowed) { if (!allowed) { UDPSOCKET_LOG(("%s: not allowed", __FUNCTION__)); } return NS_OK; } } FallibleTArray<uint8_t> fallibleArray; if (!fallibleArray.InsertElementsAt(0, buffer, len)) { FireInternalError(__LINE__); return NS_ERROR_OUT_OF_MEMORY; } InfallibleTArray<uint8_t> infallibleArray; infallibleArray.SwapElements(fallibleArray); // compose callback mozilla::unused << SendCallbackReceivedData(UDPAddressInfo(ip, port), infallibleArray); return NS_OK; }
NS_IMETHODIMP UDPSocketParent::OnPacketReceived(nsIUDPSocket* aSocket, nsIUDPMessage* aMessage) { // receiving packet from remote host, forward the message content to child process if (!mIPCOpen) { return NS_OK; } NS_ASSERTION(mFilter, "No packet filter"); uint16_t port; nsCString ip; nsCOMPtr<nsINetAddr> fromAddr; aMessage->GetFromAddr(getter_AddRefs(fromAddr)); fromAddr->GetPort(&port); fromAddr->GetAddress(ip); nsCString data; aMessage->GetData(data); const char* buffer = data.get(); uint32_t len = data.Length(); bool allowed; mozilla::net::NetAddr addr; fromAddr->GetNetAddr(&addr); nsresult rv = mFilter->FilterPacket(&addr, (const uint8_t*)buffer, len, nsIUDPSocketFilter::SF_INCOMING, &allowed); // Receiving unallowed data, drop. NS_ENSURE_SUCCESS(rv, NS_OK); NS_ENSURE_TRUE(allowed, NS_OK); FallibleTArray<uint8_t> fallibleArray; if (!fallibleArray.InsertElementsAt(0, buffer, len)) { FireInternalError(this, __LINE__); return NS_ERROR_OUT_OF_MEMORY; } InfallibleTArray<uint8_t> infallibleArray; infallibleArray.SwapElements(fallibleArray); // compose callback mozilla::unused << PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("ondata"), UDPMessage(ip, port, infallibleArray), NS_LITERAL_CSTRING("connected")); return NS_OK; }
mozilla::ipc::IPCResult UDPSocketParent::RecvOutgoingData(const UDPData& aData, const UDPSocketAddr& aAddr) { if (!mSocket) { NS_WARNING("sending socket is closed"); FireInternalError(__LINE__); return IPC_OK(); } nsresult rv; if (mFilter) { if (aAddr.type() != UDPSocketAddr::TNetAddr) { return IPC_OK(); } // TODO, Packet filter doesn't support input stream yet. if (aData.type() != UDPData::TArrayOfuint8_t) { return IPC_OK(); } bool allowed; const InfallibleTArray<uint8_t>& data(aData.get_ArrayOfuint8_t()); rv = mFilter->FilterPacket(&aAddr.get_NetAddr(), data.Elements(), data.Length(), nsISocketFilter::SF_OUTGOING, &allowed); // Sending unallowed data, kill content. if (NS_WARN_IF(NS_FAILED(rv)) || !allowed) { return IPC_FAIL(this, "Content tried to send non STUN packet"); } } switch(aData.type()) { case UDPData::TArrayOfuint8_t: Send(aData.get_ArrayOfuint8_t(), aAddr); break; case UDPData::TIPCStream: Send(aData.get_IPCStream(), aAddr); break; default: MOZ_ASSERT(false, "Invalid data type!"); return IPC_OK(); } return IPC_OK(); }