Cooja - How to assign different services to a mote/node? - contiki

I need to create a network of 10 motes. I want each mote to provide 3 services with s1 = 0.25, s2 = 0.5 and s3 = 0.025. Also, I want to identify / select selfish / malicious mote(s).
Any help will be highly appreciated.

A solution to this should not be complicated to write yourself but I guess you can look at using the service registration and dissemination hack (servreg-hack) application in contiki. The operation of the application is very simple, all the application does is enable nodes to advertise services that they offer by broadcasting a SERVICE_ID (which is just an unsigned 8-bit integer). When a another node in the vicinity of the broadcasting node receives a message it stores the SERVICE_ID and the address of the node that sent the message. If the node needs a service, it can then just look up the address of a node that offers the service by calling the servreg_hack_lookup function.
The unicast-sender and unicast receiver applications in the examples section of the contiki distribution (Contiki/examples/ipv6/simple-udp-rpl) use servreg_hack.
So on both nodes you would initialise the servreg app by calling
servreg_hack_init();
then on the service provider you would register a service by calling
servreg_hack_register(SERVICE_ID, service_provider_ip_addr);
this service would then be received and registered on the service user node. The service user would can then call
service_provider_ipaddr = servreg_hack_lookup(SERVICE_ID);
to get the address of the node that provides the service identified by SERVICE_ID.

Related

How do I use Event Store DB client without continued memory usage growth?

I am using the event store client for .Net and I am struggling to find the correct way to use the client. When I register the client as a singleton in the .Net dependency injection and run my application over an extended period of time memory usage grows continuously with each subscription.
I create and register the client in the following way. A full minimal application that experiences the problem can be found here.
var esdbConnectionString = configuration.GetValue("ESDB_CONNECTION_STRING", "esdb://admin:changeit#localhost:2113?tls=false");
var eventStoreClientSettings = EventStoreClientSettings.Create(esdbConnectionString);
var eventStoreClient = new EventStoreClient(eventStoreClientSettings);
services.AddSingleton(eventStoreClient);
My application has a high number of short streams over an extended period of time
To Reproduce
Steps to reproduce the behavior:
Register EventStoreClient as singleton as reccomended in the documentation.
Subscribe to a very high number of streams over an extended time.
Cancel the CancellationToken sent into the stream subscription and let it be garbage collected.
Watch memory usage of service grow.
How I am creating and subscribing to streams:
var streamName = CreateStreamName();
var payload = new PingEvent { StreamNr = _currentStreamNumber };
var eventData = new EventData(Uuid.NewUuid(), typeof(PingEvent).Name, EventSerialization.SerializeEventData(payload));
await _client.AppendToStreamAsync(streamName, StreamState.Any, new[] { eventData });
var streamCancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(30));
await _client.SubscribeToStreamAsync(streamName, FromStream.Start, async (sub, evnt, token) =>
{
if (evnt.Event.EventType == "PongEvent")
{
_previousStreamIsDone = true;
streamCancellationTokenSource.Cancel();
}
},
cancellationToken: streamCancellationTokenSource.Token);
Approaches attempted
Registering as Transient or Scoped
If I register the client as Transient or Scoped in .Net DI it is throwing thousands of exceptions internally and causing multiple problems.
Manually handling lifetime of client
By having a singleton service that handles the lifetime of the client I have attempted to every once in a while dispose of the client and create a new one, ensuring that there exists only one instance of the client at the same time. This results in same problem as registering the service as Transient or Scoped.
I am using version 22.0.0 of the Event Store client in .Net 6 against Event Store Database 21.10.0. The problems happens both when running on windows and on the standard aspnet:6.0 linux docker container.
By inspecting the results of these dotnet-dumps the memory growth seem to be happening inside this HashSet of ActiveCalls in the gRPC client.
I am hoping to find a way of using the client that does not lead to memory growth.
In your reproduction the leaked calls are coming from the extra read that you are issuing while processing an event received on the subscription.
There is an open issue (https://github.com/EventStore/EventStore-Client-Dotnet/issues/219) at the moment to deal with this better, but currently if you issue a read but don't consume all the events and don't cancel the read, then the call remains open. In your case this is happening if the slave has managed to reply Pong before the master has issued the read that results from receiving its own Ping in the subscription. That read will then contain the Ping and the Pong, only the Ping is read, and the call remains open.
For now, if you cancel those reads by passing the cancellation token that you are cancelling into the ReadStreamAsync call in ReadFromStartOfStreamToEnd, it should resolve your problem.
In case it's helpful for you, you can see the number of Current Calls live rather than waiting a long time to see the effect on memory:
dotnet-counters monitor --counters "Grpc.Net.Client" -p <processid>

Photon. OnRoomListUpdate doesn't work after restart WI-FI on Android

PUN2.31 Photon lib: 4.1.6.0
Unity 2019.4.26f1
Hello dear friends!
I have a simple app with rooms. Master creates room, client can join room, client can leave room. If master leaves room client leaves room too. Its ok, its working. (for example Master - UnityEditor, client - AndroidBuild).
When the master creates a room, an callbacks OnRoomListUpdated is triggered for the client correctly.
But if client in lobby and he disconnected from server, then he connected to server, all callbacks is working correctly (OnConnectedToMaster, OnJoinedLobby e.t.c) its ok.
Debug.Log("Client IsConnected = " + PhotonNetwork.IsConnected);
Debug.Log("Client InLobby = " + PhotonNetwork.InLobby);
These logs are true when client reconnected.
But now, if master creates room, client can't join because OnRoomListUpdated callback is not triggering.
Can anyone help or know some reasons of this problem?
Here is a link to video of my problem (at the end of video I restarted WI-FI): https://youtu.be/wkDFxIMfzH8
Master and client had different AppVersion.
Mistake in my code. This part of code I wrote in Awake, but had to write this in callback OnConnectedToMaster
PhotonNetwork.GameVersion = Application.version;

How to get solace queue statistics from Solclient API? c#

I am looking to retrieve some Solace queue stats e.g. the current messages spooled count out of the maximum limit for us to set a threshold to stop publishing more messages to the queue.
Also, to subscribe to vpn events to track message discard rates.
By the time we receive errors e.g. MaxMsgUsageExceeded/SpoolOverQuota, it will be too late.
I can't seem to find any of these on SolaceSystems.Solclient.Messaging API
https://docs.solace.com/API-Developer-Online-Ref-Documentation/net/html/7f10bcf6-19f4-beff-0768-ced843e35168.htm
Would be great if someone could help
(using C# for this)
To poll for Solace queue stats from your C# application, you could use legacy SEMP over the message bus to make a SEMP request for the details that you want. Semp (Solace Element Management Protocol) is a request/reply protocol that uses an XML schema to identify all managed objects available in a message broker. Applications can use SEMP to manage and monitor a message broker.
To allow for legacy SEMP to be used over the message bus, as opposed to the management interface, it first needs to be enabled on the Solace PubSub+ message broker at the VPN level.
To publish a SEMP request with the Solace .Net Messaging API, perform the following steps:
Create a Session.
Create the message topic. “#SEMP//SHOW”
ITopic topic = ContextFactory.Instance.CreateTopic( “#SEMP/<router name>/SHOW”);
Create a request message and set its Destination to the topic in Step 2:
IMessage requestMsg = ContextFactory.Instance.CreateMessage();
requestMsg.Destination = topic;
Set the SEMP request string as the binary attachment.
string SOLTR_VERSION = "8_4_0" //change to the message-broker's version
string SEMP_SHOW_QUEUE = "<rpc semp-version=\"soltr/" + SOLTR_VERSION +
"<show><queue><name>queueName</name><detail></detail></queue></show></rpc>";
requestMsg.BinaryAttachment = Encoding.UTF8.GetBytes(SEMP_SHOW_QUEUE);
Call the SendRequest(…) method on Session.
IMessage replyMsg;
ReturnCode rc = session.SendRequest(requestMsg, out replyMsg, timeout);
The SEMP response is returned in replyMsg.
Obtain the binary attachment data from the reply message:
replyMsg.BinaryAttachment
The binary attachment contains the SEMP reply for the command topic in the publish request.
The Solace PubSub+ message broker does raise an event when an egress message is discarded. However, it is only sent out approximately once every 60 seconds for the specified client so it is not possible to get these exact rates.
It is possible for your .NET application to subscribe to VPN-level events over the message-bus. To do this, you must first enable the Solace PubSub+ message broker to publish the events. You can then subscribe to the special topic and receive the events as messages.
The topic to subscribe to is:
#LOG/<level>/VPN/<routerName>/<eventName>/<vpnName>
The different levels can use the * wildcard. For example, if you wish to subscribe to all VPN events of all levels for the VPN apple on router QA-NY1, the topic string would be:
#LOG/*/VPN/QA-NY1/*/apple
SEMP (starting in v2) is a RESTful API for configuring, monitoring, and administering a Solace PubSub+ broker.
1-The swapper page link is SEMP V2 API
2-The Swagger metadata definitions URL is located # http://{solace-sever-url}/SEMP/v2/config/spec
3- From Visual studio, add REST API Client
4-In the configuration dialog pass swagger metadata URL (defined at step 2), for code purpose I choose SolaceSemp as input value parameter for client namespace input.
4 Once you click ok, VS will create the client along with the models under SolaceSemp namespace
5 Start using the client as per following
using SolaceSemp;
using Microsoft.Rest;
var credentials = new BasicAuthenticationCredentials();
credentials.UserName = "place user name";
credentials.Password = "place password";
using (var client = new SolaceSempClient(credentials))
{
var model = client.GetAboutApi();
}

NEPacketTunnelProvider Sniffer iOS

As I recently found this paper describing a sniffing mechanism for iOS using Apple's NEPacketTunnelProvider Extension, I got curious and it made me want to understand it from a technical point of view. As I usually don't work at a deep network layer like that, I'm not able to comprehend it in the detail I'd like to. As Charles Proxy for iOS must do something very similar without requiring supervised devices, I assume the approach which the author of the paper presented in 2016 might be still working nowadays.
The author claimed that "Everything like IP packet parsing, building
an IP packet or parsing a DNS response had to be implemented ourselves." As I want to fully understand that, I tried to build it myself. I build a NetworkExtension and a message loop for the packetFlow of the NEPacketTunnelProvider. I was able to obtain the ip datagrams and tried to parse them. I used unsigned integers of the corresponding size for the source and target ip, the transport protocol and ip version, but I'm unsure how to handle the treat the payload. My parser uses the ptr.load(fromByteOffset: <offset>, as:<DataType>.self) where ptr is a UnsafeRawPointer to access the packet flow information. Since the data might exceed the storage of UInt64, I don't know how to access and store the payload in a proper way.
Furthermore, I figured that the source IP is always 192.168.20.1 (set as my interface's NEIPv4Settings address) and my target ip is always 192.168.2.1 (my dummy NEDNSSettings server). This leads me to my first questions: Are those DNS queries? Will the datagram packet claim any further information about the actual target? Would that mean that I have to somehow execute the request to the DNS server and reroute the packet to the target which I will obtain from that DNS query?
The next step would be to implement a TCP / UDP handling, right? My current parsing approach is able to distinguish between UDP, TCP and ICMP (even though I don't have investigated in the last one yet). Therefore, I'd iterate over the datagrams and lookup whether they require a UPD or TCP session/connection and transfer the datagram. The problem I currently see their from a conceptional point of view: How do I know which source/target port to use for TCP/UPD connections/sessions? As far as I know, this information is not part of the IP Packet itself (since it's rather some information we need on transport layer level, not on network layer level).
Additionally, I found a project called Specht on github. It uses a self-written library called NEKit which somehow also uses the NEPacketTunnelProvider approach. When I understand their approach correctly, they managed to somehow build a local proxy server by writing some observer mechanisms in order to handle the requests, but since I'm relatively new to networking and swift, I'm not sure whether I understand that completely correct or whether I just haven't find all those TCP/UDP and/or DNS logic. Is this project comparable to the approach of the paper and charles proxy?
One last question: Charles proxy is in most cases able to show the hostname of the target. I'm currently just able to see destination ip addresses (which aren't real destination ip addresses, but the address of my DNS server). How am I able to see the hostname as human readable text? Does Charles do a nslookup somehow? Does Charles obtain that information out of the datagrams?
I know it's quite ambitious of me with much missing knowledge in this topic, to build something similar for test reasons, but I'm still motivated to look deeper into that topic and also have the feeling that I have understand already some key points, but unfortunately not enough to solve the puzzle... Maybe you're able to give me some more hints to get a better understanding. If there might be even an easier way to archive a similar behavior (to see outgoing connections on hostname level), I'd be interested in these as well :-)
I've published a Beta Proxyman iOS (website) - a Network Sniffer by using NEPacketTunnelProvider and Network Extension, so I might have experienced to answer some of your questions.
IP Package, IP Diagram, DNS, How to parse it?
Luckily, there is another way to set up a NEPacketTunnelProvider to provide you with an HTTP Message, not IP Package (it's too low-level, and you have to deal with the Parser, DNS, ...)
HTTP Message is easier to parse because there are plenty of reliable libraries (e.g. http-parser from nodeJS)
How to build a Network Sniffer on iOS?
It's a complicated question to answer, I would break it into small chunks:
MitM / Proxy Server
Firstly, you need a working MitM Proxy Server, which is capable of proxying and intercepting the HTTP/HTTPS Traffic. You can implement it by using SwiftNIO or CocoaAsyncSocket.
How does it work?
In general, the data flow might look like this:
The Internet -> iPhone -> Your Network Extension (VPN) -> Forward to your Local Proxy Server (in the Network Extension) -> Mitm/Proxy Server starts intercepting or monitoring the traffic -> Save to a local database (in Shared Container Group) -> Forward again to the destination server.
From the main app, you can receive the data by reading the local database.
The reason why we need a local database is that the Network Extension and the Main app are two different processes, so they could not communicate directly like a normal app.
Show me the code?
In the Network extension, let start a Proxy Server at Host:Port, then init the NetworkSetting, like the sample:
private func initTunnelSettings(proxyHost: String, proxyPort: Int) -> NEPacketTunnelNetworkSettings {
let settings: NEPacketTunnelNetworkSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "127.0.0.1")
/* proxy settings */
let proxySettings: NEProxySettings = NEProxySettings()
proxySettings.httpServer = NEProxyServer(
address: proxyHost,
port: proxyPort
)
proxySettings.httpsServer = NEProxyServer(
address: proxyHost,
port: proxyPort
)
proxySettings.autoProxyConfigurationEnabled = false
proxySettings.httpEnabled = true
proxySettings.httpsEnabled = true
proxySettings.excludeSimpleHostnames = true
proxySettings.exceptionList = [
"192.168.0.0/16",
"10.0.0.0/8",
"172.16.0.0/12",
"127.0.0.1",
"localhost",
"*.local"
]
settings.proxySettings = proxySettings
/* ipv4 settings */
let ipv4Settings: NEIPv4Settings = NEIPv4Settings(
addresses: [settings.tunnelRemoteAddress],
subnetMasks: ["255.255.255.255"]
)
ipv4Settings.includedRoutes = [NEIPv4Route.default()]
ipv4Settings.excludedRoutes = [
NEIPv4Route(destinationAddress: "192.168.0.0", subnetMask: "255.255.0.0"),
NEIPv4Route(destinationAddress: "10.0.0.0", subnetMask: "255.0.0.0"),
NEIPv4Route(destinationAddress: "172.16.0.0", subnetMask: "255.240.0.0")
]
settings.ipv4Settings = ipv4Settings
/* MTU */
settings.mtu = 1500
return settings
}
Then start a VPN,
let networkSettings = initTunnelSettings(proxyHost: ip, proxyPort: port)
// Start
setTunnelNetworkSettings(networkSettings) { // Handle success }
Then forward the package to your local proxy server:
let endpoint = NWHostEndpoint(hostname: proxyIP, port: proxyPort)
self.connection = self.createTCPConnection(to: endpoint, enableTLS: false, tlsParameters: nil, delegate: nil)
packetFlow.readPackets {[weak self] (packets, protocols) in
guard let strongSelf = self else { return }
for packet in packets {
strongSelf.connection.write(packet, completionHandler: { (error) in
})
}
// Repeat
strongSelf.readPackets()
}
From that, your local server can receive the packages then forwarding to the destination server.
Don't forget to save all traffic log to the local database, then notifying the main app to reload it.
One last question: Charles proxy is in most cases able to show the hostname of the target. I'm currently just able to see destination ip addresses (which aren't real destination ip addresses, but the address of my DNS server). How am I able to see the hostname as human readable text? Does Charles do a nslookup somehow? Does Charles obtain that information out of the datagrams?
Since we don't deal with IP Package, we don't need to implement the DNS Resolver. If you need a DNS, you can config like the following code:
let dnsSettings = NEDNSSettings(servers: ["8.8.8.8", "1.1.1.1"])
settings.dnsSettings = dnsSettings
As we receive the HTTP Message package, you can get hostname for free (From the Request's URL or Host Header)
Hope that my answer could help you.

How to set max connections in AP configuration of esp8266?

I want to connect only one client at a time with esp8266. Second client trying to connect should disconnect immediately.But I can't find 'max_connection' like parameter in
ap.configuration()
Allowed parameters are essid, password, channel, authmode
Is there a way to achieve this ?
You can use wifi_softap_set_config() with config.max_connections.
From reference

Resources