How to forward data packets through an alternative path via an alternative parent? - parent

For example, We have a RPL tree, and several data senders transmitting data packets to the sink. After a while, one of the senders stops sending or forwarding data to parent node because we assumed the parent node is suspicious. Instead of sending or forwarding the data packet via the suspicious node, it forwards the data packet through an alternative path via an alternative parent that is chosen from the parent list. What is an efficient and simple way to implement this scenario in Contiki?

What you want to do is to blacklist a specific parent (or multiple parents). To achieve that, you can add a new field uint8_t is_suspicious to the struct rpl_parent.
I assume that you have the logic for setting this flags already in place. Then, when doing the parent selection in RPL (the best_parent function in rpl-dag.c) you can look at the flag and exclude parents that have it set.
To the if condition in the existing code:
/* Exclude parents from other DAGs or announcing an infinite rank */
if(p->dag != dag || p->rank == INFINITE_RANK || p->rank < ROOT_RANK(dag->instance)) {
if(p->rank < ROOT_RANK(dag->instance)) {
PRINTF("RPL: Parent has invalid rank\n");
}
continue;
}
you would add another check: ... || p->is_suspicious).
Finally, you need to re-trigger the parent selection algorithm every time the is_suspicious status changes of a parent. One way to do that is to call the function rpl_process_parent_event.

Related

Checking if a node has a connected signal with "is_connected" gives errors if there are no signals connected

In my project I dynamically (through the code) create LineEdits with fields the user can change in a popup WindowDialogue. In the similar manner I connect each LineEdit with a signal (text_entered) to a function which saves the changes made.
So, I have a simple function, which manages the WindowDialogue closing, i.e. deletes all children:
for child in parent.get_children():
if child.is_connected("text_entered", self, "_function_name"):
child.disconnect("text_entered", self, "_function_name")
child.queue_free()
As you can see I specifically make a check if a child has connections to remove before deleting the child node from the memory. As it is, the code works correctly. However, every time the check goes through the nodes (in my cases Labels) that do not have a signal connected, I get this error in the debugger:
is_connected: Nonexistent signal: text_entered.
That is a logical statement from the engine I cannot argue with. My question is: is there a way to make my check go through without this error?
This code should not show any errors even if nothing is connected to the signal. Probably parent has some child that really doesn't have the text_entered signal.
You can check whether a node (or other object) has the given signal with has_signal:
for child in parent.get_children():
if child.has_signal("text_entered") and child.is_connected("text_entered", self, "_function_name"):
child.disconnect("text_entered", self, "_function_name")
child.queue_free()
However, there's usually no need. Signals are disconnected automatically when the node is freed.
(When using queue_free, the node is freed at the end of the frame, not immediately, so there are edge cases where something like this is needed. But I don't think this is one of those cases.)
You could also check the type of the Node. For example:
for child in parent.get_children():
if not child is LineEdit:
continue
# rest of the code
Or if you are like me you prefer this:
for child in parent.get_children():
var line_edit := child as LineEdit
if not is_instance_valid(line_edit):
continue
# rest of the code

Define new socket option for use in TCP kernel code

I'm trying to add some functionality to the TCP kernel code (in tcp_input.c). I want the code I've implemented to run only in certain situations. I want to add a control flag, which can be set from a user-space application.
I (think I) need to add a new socket option, so that I can accomplish the following with setsockopt().
kernel space:
if(tcp_flags.simulate_ecn_signal) {
// run code for simulating ecn signal
}
user space:
if(tcp_info.tcpi_retransmits > LIMIT) {
u8 simulate_ecn_signal = 1;
// set the flag, so that the kernel code runs
if (setsockopt(sock, IPPROTO_TCP, TCP_FLAGS, &simulate_ecn_signal, sizeof(simulate_ecn_signal)) < 0)
printf("Can't set data with setsockopt.\n");
}
In the example code above I've added an example flag simulate_ecn_signal which I thought could be a member of a (new) socket option (struct) called tcp_flags (that potentially could contain multiple flag values).
How do I define a new socket option, in order to accomplish this?

The detail function about epoll_insert

The epoll_insert function is called by sys_epoll_ctl.
There are some key steps in epoll_insert function :
Initialize the poll table using the queue callback : ep_ptable_queue_proc
And it will call the file->f_op->poll
If the file is already "ready" , then we drop it inside the ready list
/* If the file is already "ready" we drop it inside the ready list */
if ((revents & event->events) && !ep_is_linked(&epi->rdllink)) {
list_add_tail(&epi->rdllink, &ep->rdllist);
/* Notify waiting tasks that events are available */
if (waitqueue_active(&ep->wq))
wake_up_locked(&ep->wq);
if (waitqueue_active(&ep->poll_wait))
pwake++;
}
I don't understand why to check whether file is ready in epoll_insert function. Should we check it in ep_poll_callback function ?
ep_poll_callback is only called when the status of one of the file descriptors changes. If that were the only place that epoll descriptors were added to the read list, you could potentially miss events that occurred before you managed to add them to epoll. For instance, in a web server, you could miss a client's request if it was sent immediately after connecting.

Request.Filter in an IIS Managed Module

My goal is to create an IIS Managed Module that looks at the Request and filters out content from the POST (XSS attacks, SQL injection, etc).
I'm hung up right now, however, on the process of actually filtering the Request. Here's what I've got so far:
In the Module's Init, I set HttpApplication.BeginRequest to a local event handler. In that event handler, I have the following lines set up:
if (application.Context.Request.HttpMethod == "POST")
{
application.Context.Request.Filter = new HttpRequestFilter(application.Context.Request.Filter);
}
I also set up an HttpResponseFilter on the application.Context.Response.Filter
HttpRequestFilter and HttpResponseFilter are implementations of Stream.
In the response filter, I have the following set up (an override of Stream.Write):
public override void Write(byte[] buffer, int offset, int count)
{
var Content = UTF8Encoding.UTF8.GetString(buffer);
Content = ResponseFilter.Filter(Content);
_responseStream.Write(UTF8Encoding.UTF8.GetBytes(Content), offset, UTF8Encoding.UTF8.GetByteCount(Content));
}
ResponseFilter.Filter is a simple String.Replace, and it does, in fact, replace text correctly.
In the request filter, however, there are 2 issues.
The code I have currently in the RequestFilter (an override of Stream.Read):
public override int Read(byte[] buffer, int offset, int count)
{
var Content = UTF8Encoding.UTF8.GetString(buffer);
Content = RequestFilter.Filter(Content);
if (buffer[0]!= 0)
{
return _requestStream.Read(UTF8Encoding.UTF8.GetBytes(Content), offset, UTF8Encoding.UTF8.GetByteCount(Content));
}
return _requestStream.Read(buffer, offset, count);
}
There are 2 issues with this. First, the filter is called twice, not once, and one of the requests is just basically a stream of /0's. (the if check on buffer[0] filters this currently, but I think that I'm setting something up wrong)
Second, even though I am correctly grabbing content with the .GetString in the read, and then altering it in RequestFilter.Filter(a glorified string.replace()), when I return the byte encoded Content inside the if statement, the input is unmodified.
Here's what I'm trying to figure out:
1) Is there something I can check prior to the filter to ensure that what I'm checking is only the POST and not the other time it is being called? Am I not setting the Application.Context.Request.Filter up correctly?
2) I'm really confused as to why rewriting things to the _requestStream (the HttpApplication.Context.Request.Filter that I sent to the class) isn't showing up. Any input as to something I'm doing wrong would be really appreciated.
Also, is there any difference between HttpApplication.Request and HttpApplication.Context.Request?
edit: for more information, I'm testing this on a simple .aspx page that has a text box, a button and a label, and on button click assigns the text box text to the label's text. Ideally, if I put content in the textbox that should be filtered, it is my understanding that by intercepting and rewriting the post, I can cause the stuff to hit the server as modified. I've run test though with breakpoints in the module and in code, and the module completes before the code behind on the .aspx page is hit. The .aspx page gets the values as passed from the form, and ignores any filtering I attempted to do.
There's a few issues going on here, but for future reference, what explains the page receiving the unfiltered post, as well as the filter being evaluated twice is that you are likely accessing the request object in some way PRIOR to you setting the Request.Filter. This may cause it to evaluate the inputstream, running the currently set filter chain as is, and returning that stream.
For example, simply accessing Request.Form["something"] would cause it to evaluate the inputstream, running the entire filter chain, at that point in time. Any modification to the Request.Filters after this point in time would have no effect, and would appear that this filter is being ignored.
What you wanted to do is possible, but also ASP.NET provides Request Validation to address some of these issues (XSS). However, Sql Injection is usually averted by never constructing queries through string concatenation, not via input sanitizing, though defense-in-depth is usually a good idea.

How do I bind an action to a "create/remove new node" event in DynaTree?

Getting started with DynaTree. I'd like to bind some code to the event which is "adding a new node". The onCreate option seems to be fired when a node is rendered for the first time. Yes, this includes when a node is created, but it also includes when the tree is loaded and rendered, and when a collapsed subtree is expanded for the first time. So it doesn't seem appropriate. The same question applies to removing a node. Where are these events?
Thanks,
Marco.
So you want to execute code when you add a child? I did this by creating my own little function to add Nodes.
function addChildNode(NodeID, NodeName, ParentID){
jQuery("#tree2").dynatree("getTree").getNodeByKey(ParentID).addChild({title: NodeName, key: NodeID});
//Code you wish to be executed goes here
}
Then you simply call the function and pass in the NodeID (key), NodeName (title), ParentID (key).

Resources