Netem is a great tool for simulating a WAN connection, with all the expected latency, jitter, packet loss, duplication, and bandwidth limitations. These instructions walk you through setting up a machine that sits between your server and client that emulates the behavior of a WAN connection. I use Fedora 14, so your distro may be a little different, but hopefully this post gets you pointed in the right direction.

The picture below shows the 2 most common configurations for a Netem box:

Netem Box Setup

I’ve always used the first configuration, but it doesn’t really matter.

1. Find a Suitable System

  • Any “reasonable” machine that can run Fedora 14 (I use an old Pentium 4 box since I don’t need to simulate a high-speed link)
  • It must have 2 network interfaces
  • It’s nice to use a smaller box if you want it to be portable

2. Install bridge-utils

Make sure you are root, and run:

brctl

to see if bridge-utils is installed. If it isn’t, run:

yum install bridge-utils.

Continue reading »

Tagged with:  
Tagged with:  

Cross-Platform IPv6 Socket Programming

On February 28, 2011, in Code Monkey, by Tom

IPv6 NetworkingWriting code that works on Windows, Linux, and Mac is frequently challenging. Socket programming is no exception. Modern versions of Linux and Mac have full implementations of the latest IPv6 socket API extensions defined in RFC 3493. Windows, however, has only a partial implementation of the original (deprecated) version, RFC 2553. This sounds worse than it is, but it’s something you have to consider.

Note: This post assumes you are already familiar with the socket extensions for IPv6 (RFC 3493).

Linux and Mac
Good news… they both fully support RFC 3493.

Windows
Windows IPv6 support varies based on which version you’re targeting. Microsoft started adding IPv6 in Windows 2000, and they’ve continued adding more of the socket extensions as time went on. Most of the core functionality is present in XP, and what’s missing is easily replaced by using Winsock calls directly (more on this later).

Windows gained IPv6 support while RFC 2553 was still the supported standard. Since then, it has been deprecated by RFC 3493. However, Microsoft doesn’t want to break existing code written against it’s API, so the older API lives on. The main impact of this is that sockaddr_in6 and sockaddr_storage are slightly different on Windows than Mac and Linux. The size of the structures across platforms is the same (the sa_family_t member was shortened), it’s just that the Windows structures don’t begin with the length member. For example:

// Linux and Mac
struct sockaddr_in6 {
    uint8_t      sin6_len;    /* Added in RFC 3493 */
    sa_family_t  sin6_family;
    ...
};
struct sockaddr_storage {
    uint8_t      ss_len;      /* Added in RFC 3493 */
    sa_family_t  ss_family;
    ...
};

// Windows
struct sockaddr_in6 {
    sa_family_t  sin6_family;
    ...
};
struct sockaddr_storage {
    sa_family_t  ss_family;
    ...
};

I’ve never had a problem with this, because the size of sockaddr_in6 is easily determined (sizeof(sockaddr_in6)) and I always end up casting sockaddr_storage to the specific type (sockaddr_in or sockaddr_in6) based on ss_family.

Besides the data structure differences, it’s important to remember that Microsoft added IPv6 support over multiple versions. Support first appeared in Windows 2000, but more of the extensions have been added over time. Most of the core functionality was present in XP (including multicast), but not everything is implemented as of Windows 7. It’s annoying, but I will say that what’s missing is easily replaced by using Winsock calls directly.

Here’s the breakdown of IPv6 socket extensions by Windows version:

Socket Extension 2K XP Vista 7 Comments
if_indextoname() x x GetAdaptersAddresses() for XP
if_nametoindex() x x GetAdaptersAddresses() for XP
if_nameindex() GetAdaptersAddresses() (XP, later)
if_freenameindex()
getaddrinfo() x x x x
getnameinfo() x x x x
freeaddrinfo() x x x x
gai_strerror() x x x x
inet_pton() x x WSAStringToAddress() (2000, XP)
inet_ntop() x x WSAAddressToString() (2000, XP)
All IN6_IS_ADDR_* macros x x x Ex: IN6_IS_ADDR_LOOPBACK()
struct sockaddr_storage x x x
Multicast support x x x

As you can see, you may still have to call Winsock directly depending on what version of Windows you are targeting. In my opinion, programming IPv6 on Windows is a lot easier if you only support XP and later, but I know that’s not always possible.

Summary

Modern operating systems all support IPv6. However, for business reasons, Windows has a slightly older version of the socket API which requires special consideration. My goal was to enumerate those differences to help make the transition to IPv6 smoother. Writing cross-platform code can be a fun challenge at times, but it’s also a little tedious. Hopefully, this post helps ease the pain.

Tagged with:  

How to Test if an Address is IPv4 or IPv6

On February 25, 2011, in Code Monkey, by Tom

Here’s a simple function using getaddrinfo() that will take an IP address and return the address family (AF_INET for IPv4, AF_INET6 for IPv6, etc). I works on both Linux and Windows. This function will also accept hostnames and return the address family of the first address returned. You can disable this feature (and the corresponding DNS lookup) by passing the AI_NUMERICHOST flag.

// Returns the address family of an address or hostname.
// AF_INET, AF_INET6, or -1 on error.
int getaddrfamily(const char *addr)
{
    struct addrinfo hint, *info =0;
    memset(&hint, 0, sizeof(hint));
    hint.ai_family = AF_UNSPEC;
    // Uncomment this to disable DNS lookup
    //hint.ai_flags = AI_NUMERICHOST;
    int ret = getaddrinfo(addr, 0, &hint, &info);
    if (ret)
        return -1;
    int result = info->ai_family;
    freeaddrinfo(info);
    return result;
}

See RFC 3493 for more information on the latest socket API for dealing with IPv6.

Tagged with:  

Using the Tcpreplay tools to edit a Wireshark capture (*.pcap), I wanted to change the destination address to be multicast. I knew the IP multicast address I wanted (server IP address with the first octet changed to 239), but I had to change the MAC address also.

Here’s the mapping, taken from a Microsoft TechNet article:

To support IP multicasting, the Internet authorities have reserved the multicast address range of 01-00-5E-00-00-00 to 01-00-5E-7F-FF-FF for… media access control (MAC) addresses.

To map an IP multicast address to a MAC-layer multicast address, the low order 23 bits of the IP multicast address are mapped directly to the low order 23 bits in the MAC-layer multicast address. Because the first 4 bits of an IP multicast address are fixed according to the class D convention, there are 5 bits in the IP multicast address that do not map to the MAC-layer multicast address. Therefore, it is possible for a host to receive MAC-layer multicast packets for groups to which it does not belong. However, these packets are dropped by IP once the destination IP address is determined.

For example, the multicast address 224.192.16.1 becomes 01-00-5E-40-10-01.

Happy hacking!

Tagged with:  

Setting the DHCP Hostname on Linux

On October 14, 2008, in Code Monkey, by Tom

I’m always forgetting how to register my machine name with the DHCP server so I can ping my box without having to remember my IP address. Here’s how to do it on Fedora Core 9:

  1. Set the hostname: `# hostname <hostname>`
  2. Add ‘HOSTNAME=<hostname>’ to ‘/etc/sysconfig/network’ (makes the change permanent).
  3. Add ‘DHCP_HOSTNAME=<hostname>’ to ‘/etc/sysconfig/network-scripts/ifcfg-eth0′
  4. Restart the networking service: `# service network restart`

Volia! Now you can connect to your box via hostname.

References:

Tagged with:  

Mastercard LogoCIO has a good interview with Rob Reeg, president of Mastercard’s Global Technology and Operations. He discusses their infrastructure and processing architecture. Definitely worth looking at if you’re interested in how credit card transactions are processed.

Interviewer: How big of an infrastructure do you have to support and maintain? It must be huge.

Reeg: Actually from a pure server footprint standpoint… we probably have fewer actual footprint servers because of techniques like virtualization that help us leverage one box to do multiple things.

Where it gets interesting is philosophically: We try to put [transaction] processing as close to our customers, the banks, as possible. When we talk about the global network, we have small servers that sit with the bank customers that connect to our network. What it does is it gives us intelligence there at the end of the network. So as a transaction comes through, we can take a look at that transaction and decide how do we best process that transaction for the benefit of all those four parties in the model.

As to processing, the majority of transactions we’re looking at relate to how do we process them as fast as possible in the most accurate way. The way to do that is by peer to peer: If you’re using your card in Europe, in London, say, and you swipe your card as you check out of hotel, we can route that transaction to the hotel’s acquiring bank in London directly to your issuing bank and get that message back for approval without ever going through St. Louis or some big data center in the middle of all that.

You can read the full article HERE.

Tagged with: