Tuesday, 12 January 2016

Sniffing the traffic on the loopback interface on Windows with RawCap

If you ever had to write a chunk of code for inter-process communication via Internet Protocol (IP) you must have came across using the loopback interfaceIPv4 address 127.0.0.1 is usually the address of this virtual interface and also the address that hostname localhost  resolves to. You would, at least for tests, set one process (server) listening on some port on the localhost while the other process (client) would connect to the server and start their data exchange. 

In order to check the data sent from one end to another, we can use any kind of process output (standard output, log, ...) provided that given process actually shows that data. But what if there is no such output? We have to find a way how to sniff the traffic between these two parties.

RawCap is one of free tools capable of sniffing packets on the loopback interface. It collects packets and stores them in the file in pcap format. This file can be opened in Wireshark.

In order to demonstrate RawCap packet capturing we can use ready-made networking application which can serve both as a server and a client - Ncat. It comes as a part of Nmap for Windows and uses TCP by default.

Once Nmap is installed, open console window in C:\Program Files (x86)\Nmap directory and  type the following:


> ncat -v -4 -l localhost 6789


-v (or --verbose) sets verbose output
-4 instructs ncat to use IPv4 addresses only
-l (or --listen) switch makes Ncat to listen for incoming connections on the provided hostname and port. localhost will be resolved to 127.0.0.1 and I also used an arbitrary port which was free - 6789.

We effectively have server running now but before we run the client it is necessary to start capturing packets. From the directory with RawCap.exe we have to open terminal window with Administrator's privileges and run RawCap.exe (which has to be run as Administrator). Now we just have to follow the instructions. RawCap lists network interfaces and asks which interface shall be monitored. We have to type in the number next to the loopback interface. In the next step we can set the name of the packet dump file or just leave default name which is dumpfile.pcap. At this point we have started sniffing packets on the localhost!


> RawCap.exe
Interfaces:
0. 169.xxx.xxx.xxx Local Area Connection Ethernet
1. 169.xxx.xxx.xxx Local Area Connection* 2 Wireless80211
2. 169.xxx.xxx.xxx Ethernet Ethernet
3. 169.xxx.xxx.xxx Ethernet 2 Ethernet
4. 169.xxx.xxx.xxx Local Area Connection 2 Ethernet
5. 127.0.0.1 Loopback Pseudo-Interface 1 Loopback
6. 192.xxx.xxx.xxx Wireless Network Connection 2 Wireless80211
Select interface to sniff [default '0']: 5
Output path or filename [default 'dumpfile.pcap']:
Sniffing IP : 127.0.0.1
File : dumpfile.pcap
Packets : 0


Let's now start the client. We have to open another terminal window in Nmap's directory and run another instance of Ncat which will try to establish TCP connection with the localhost:6789 endpoint:


> ncat -v 127.0.0.1 6789


Both server and client show the state of their current connections:

Server:

> ncat -v -4 -l localhost 6789
Ncat: Version 7.01 ( https://nmap.org/ncat )
Ncat: Listening on 127.0.0.1:6789
Ncat: Connection from 127.0.0.1.
Ncat: Connection from 127.0.0.1:9323.



Client:

> ncat -v 127.0.0.1 6789
Ncat: Version 7.01 ( https://nmap.org/ncat )
Ncat: Connected to 127.0.0.1:6789.



So far, only TCP handshake has taken place in the communication between these two instances of Ncat. We can expect that RawCap has captured at least these 3 packets so far (SYN, SYN-ACK, ACK). Let's now send some user data. By default Ncat works as an echo server which means that it echoes any text message it receives. If we type in the client "hello from client", that string will appear on the server's output. The same happens if we go the other way round and send message from the server to the client. Once we want to stop communication, we can use CTRL-C combination to stop one process. The other will get disconnected and also terminate. We can use the same combination in order to stop RawCap.exe.

At the end of the session we have:

Server:


Client:


RawCap.exe:



RawCap.exe saved all captured packets in file dumpfile.pcap. If we open this file in Wireshark and filter out all packets with TCP port 6789 we can see packets exchanged between our Ncat processes:


If we follow that TCP stream we can see exact text messages sent between client and server:


Friday, 1 January 2016

How to use internal type as a unit test argument

Behavioral tests sometimes require access to types which are internal for the SUT assembly. If those types are used in test methods, test assembly name has to be specified through InternalsVisibleToAttribute in SUT assembly. For example, if MyAppTests is a library containing tests for classes within MyApp we have to do the following:
  • in MyAppTests: add the reference to MyApp so all public types are visible
  • in MyApp: specify MyAppTests as the assembly in which internal types are visible. The following line has to be added to MyApp/Properties/AssemblyInfo.cs:

[assembly: InternalsVisibleTo("MyAppTests")]



This makes internal types visible within unit tests. But if we want to pass such types as arguments to unit tests (via TestCase or TestCaseSource attributes), compiler will complain about inconsistent accessibility.

For example, if we have public class (SUT) and internal enum:


and the following test:


Compiler issues an error:

Error CS0051 Inconsistent accessibility: parameter type 'MyEnum' is less accessible than method 'MyClass_Tests.Foo_Does_This_When_MyEnum_Is_Value1_or_Value2(MyEnum)'

Unit test methods have to be public, otherwise unit test runners will not be able to see them or would report that test fails (Nunit Test Adapter also issues error message: "Method is not public"). Unit tests are public API so types of their arguments also have to be public (visible in any assembly, not just in test library).

The solution for this is to pass arguments to test method as type object and then cast them back to the original internal type:


In this particular case, when internal type is enum, we could gave passed type int instead of object but for any other custom internal type, object is the only solution.


Thread which explains reasons why NUnit fails but does not ignore non-public test methods.

Thursday, 31 December 2015

Performance tests

Code can always be optimized in terms of resources used. It makes sense adding performance tests when resources matter and their acceptable usage is a part of the requirements.

Resources can be time, memory, number of threads, sockets etc...but probably most measured are time and memory.

These tests are integration tests because:
- they rely on external factors (they are system- and hardware-dependent)
- asserted results can vary in time
- they can take much time to execute

An example of performance test is verifying that some algorithm performs some task within the acceptable time range.

There is a question on their consistency: e.g. the same algorithm takes more time to execute on slower machines so how to determine pass/fail criteria?



Further reading:
https://en.wikipedia.org/wiki/Software_performance_testing
http://www.dynatrace.com/en/javabook/performance-in-continuous-integration.html
http://stackoverflow.com/questions/751626/performance-testing-best-practices-when-doing-tdd
http://stackoverflow.com/questions/2870322/performance-testing-versus-unit-testing
http://stackoverflow.com/questions/457605/how-to-measure-code-performance-in-net
http://stackoverflow.com/questions/969290/exact-time-measurement-for-performance-testing
http://stackoverflow.com/questions/15181358/how-can-i-unit-test-performance-optimisations-in-c


Thursday, 24 December 2015

DRY in action - Use lambda to fixate method's argument


In the following example we have a situation where Foo() calls Bar() multiple times. Within each Foo() call, it passes to Bar() different value for string argument but always the same value for int argument:

Output:


i = 123, s = test1
i = 123, s = test2
i = 123, s = test3
i = 456, s = test1
i = 456, s = test2
i = 456, s = test3


To avoid unnecessary repetition we can introduce one level of indirection - a lambda which calls Bar() and provides it string value via its own argument and int value via capturing argument passed to Foo(). After refactoring:

Output:


i = 123, s = test1
i = 123, s = test2
i = 123, s = test3
i = 456, s = test1
i = 456, s = test2
i = 456, s = test3


Monday, 21 December 2015

OperationCanceledException vs TaskCanceledException when task is canceled


In my previous post, "How to cancel a Task", I mentioned that MSDN recommends throwing OperationCanceledException from a cancelled task. But the following example shows that canceling .NET methods makes them throw a different exception type - TaskCanceledException:

Output:


System.Threading.Tasks.TaskCanceledException: A task was canceled.
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Program.d__1.MoveNext()
Task.IsCanceled: True
Task.IsFaulted: False
Task.Exception: null


So why .NET does not follow its own rules? Why exception thrown in the example above was not OperationCanceledException?

I asked this question on SO and this is how I interpret the answer I got:

(1) System.OperationCanceledException class has been around longer than TPL. MSDN describes it as: "The exception that is thrown in a thread upon cancellation of an operation that the thread was executing." It is intended to be thrown from a thread in which operation is executed. .NET async API are actually synchronous operations (return Task, not marked as async). They don't have additional thread involved which makes OperationCanceledException not appropriate exception to be thrown.

(2) It is different to cancel a Task (setup of the engine which will execute "real work", user's operation) than to cancel operation itself. For example, we can pass already cancelled token to a task or can simply create already cancelled task. Operation and its thread are not started at all in these cases but if we await such task and catch OperationCanceledException we might think they were actually started. So it makes sense to use different type of the exception in these two different scenarios.

Example 1: Already canceled token is passed to task factory method:

Output:


System.Threading.Tasks.TaskCanceledException: A task was canceled.
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Program.d__1.MoveNext()
Task.IsCanceled: True
Task.IsFaulted: False
Task.Exception: null


Example 2: Awaiting task which is created as already canceled:

Output:


System.Threading.Tasks.TaskCanceledException: A task was canceled.
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Program.d__1.MoveNext()
Task.IsCanceled: True
Task.IsFaulted: False
Task.Exception: null


From the points made above we can conclude that caller of the cancelable task can expect two types of exceptions:OperationCanceledException and TaskCanceledException. As the latter derives from the former, it is enough to handle OperationCanceledException if we want to handle the case of canceled task:




Further reading:
SO Q&A: OperationCanceledException VS TaskCanceledException when task is canceled
SO Q&A: Difference between OperationCanceledException and TaskCanceledException?
Andrew L Arnott: Recommended patterns for CancellationToken

Sunday, 20 December 2015

How to cancel a Task


It is a good practice to offer users a chance to cancel some long-running operation. Such operation usually has to run asynchronously and in a TPL-based design is modeled as a method returning a Task.

Cancellation model requires some flag which is accessible by the caller and from inside the operation. Caller sets the flag when wants operation to be cancelled. Operation regularly checks the flag or is subscribed to the event "flag has been set" and if flag has been set, operation will stop doing the work. This model is in .NET abstracted with two types: CancellationTokenSource class and CancellationToken structure. Caller uses CancellationTokenSource to initiate cancellation and operation uses CancellationToken to check whether it has been cancelled.

When designing an API, if provision for operation cancellation is required, we have to add a CancellationToken to a list of method's arguments. API caller invokes CancellationTokenSource.Cancel method which sets CancellationToken.IsCancellationRequested to true. Target method checks this property and can either silently return or throw OperationCanceledException. The latter approach is better as only in this case returning task will come to Canceled state.

The following code depicts the whole process of task cancellation:

CancellationToken.ThrowIfCancellationRequested() method simply checks CancellationToken.IsCancellationRequested and if it's true, it throws OperationCanceledException. The output of the code above is:


.........System.OperationCanceledException: The operation was canceled.
   at System.Threading.CancellationToken.ThrowIfCancellationRequested()
   at MyService.d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Program.d__1.MoveNext()
Task.IsCanceled: True
Task.IsFaulted: False
Task.Exception: null


The following code shows that the await-ed task does not get aware that the task it holds got canceled if method silently returns on cancellation:

Output:

..........Task.IsCanceled: False
Task.IsFaulted: False
Task.Exception: null


Further reading:
Andrew Arnott - Recommended patterns for CancellationToken
MSDN: Task Cancellation

Saturday, 19 December 2015

await VS Wait() when Task throws exception

await and Wait() are two versions of the operation "wait for the task to complete": one is asynchronous (non-blocking) and the other one is synchronous (blocking). They are both capable of capturing the exception thrown from the task but they behave in a different way when propagating exception information up the stack: they themselves throw different type of exception.


await (case 1) propagates the original exception so the output is:


System.ArgumentNullException: Value cannot be null.
   at Program.<>c.b__1_0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Program.d__1.MoveNext()
Task.Status: Faulted
Task.IsFaulted: True
Task.Exception: System.AggregateException: One or more errors occurred. ---> System.ArgumentNullException: Value cannot be null.
   at Program.<>c.b__1_0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Program.d__1.MoveNext()
   --- End of inner exception stack trace ---
---> (Inner Exception #0) System.ArgumentNullException: Value cannot be null.
   at Program.<>c.b__1_0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Program.d__1.MoveNext()<---


Wait() (case 2) wraps original exception in System.AggregateException:


System.AggregateException: One or more errors occurred. ---> System.ArgumentNullException: Value cannot be null.
   at Program.<>c.b__1_0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.Wait()
   at Program.d__1.MoveNext()
---> (Inner Exception #0) System.ArgumentNullException: Value cannot be null.
   at Program.<>c.b__1_0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()<---

Task.Status: Faulted
Task.IsFaulted: True
Task.Exception: System.AggregateException: One or more errors occurred. ---> System.ArgumentNullException: Value cannot be null.
   at Program.<>c.b__1_0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
   --- End of inner exception stack trace ---
---> (Inner Exception #0) System.ArgumentNullException: Value cannot be null.
   at Program.<>c.b__1_0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()<---


Note that Task.Exception in both cases holds System.AggregateException. This difference comes from the desire of async-await implementers to keep use of await as simple as possible and to make its use to look like synchronous code as much as possible. System.AggregateException is not used in synchronous code (in non-TPL code) and we there always catch the first exception that is thrown from a try-block. That is why await is designed in such way so it throws only the first exception from a task (or aggregate of tasks) as usually we are interested only in that first exception (we usually handle the first error that occurs).