Using a Subset of Addresses in an SCTP Association

This post is about how to use SCTP with only a subset of available addresses and so I will not describe the SCTP protocol in any great detail.

I will digress only briefly to say what SCTP is and to recommend an article in which interested readers can get a basic overview of the protocol. Basically SCTP (Stream Control Transmission Protocol) is a transport layer protocol similar to TCP/UDP and only the third to be ratified by the IETF. One primary feature of SCTP is the ability to allow associations (an association is SCTP parlance for a connection) to span multiple IP addresses. For more information on SCTP I would highly recommend the following article from IBM ‘Better Networking with SCTP’.

So back to the point of this post. During initial association establishment the default behaviour of SCTP is to bind all available addresses to the association. This means that both the client and server will exchange a list of all addresses through which they can be reached, regardless of whether the address is routable by the alternate endpoint. There are a number of reasons why this is undesirable. Firstly it is simply a waste if the machine cannot be reached via that address from the other endpoint, this will result in HEARTBEAT messages to that address failing and hence the address will be flagged as down. A second and more important reason is that of security, a server using SCTP may only want to utilise a subset of its addresses for receiving SCTP associations. The other interfaces may be part of a private network or be used for other purposes and the administrators of the machine may not want to expose these interfaces.

SCTP has the capability to only use a subset of addresses during the establishment of an association, unfortunately this is done in two different ways depending on whether the machine is operating as a client or server. I will first describe the server.

The sctp_bindx function call can be used in place of the normal bind call.

Server Code Snippet
// Create the Socket
sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
struct sockaddr_in addr, *addresses;
int addrcount = 2;
int addrsize = sizeof(struct sockaddr_in);

addresses = (struct sockaddr_in*) malloc(addrsize * addrcount);
if (addresses == NULL) {
perror("malloc");
exit(1);
}

addr.sin_family = AF_INET;

addr.sin_addr.s_addr = inet_addr(FIRSTLOCALADDRESS);
memcpy(addresses+0, &addr, addrsize);
addr.sin_addr.s_addr = inet_addr(SECONDLOCALADDRESS);
memcpy(addresses+1, &addr, addrsize);

//Bind with address list
if(sctp_bindx( sockfd, (struct sockaddr *)&addresses, addrcount, SCTP_BINDX_ADD_ADDR ) == -1){
throw ("TunnelManager: bindx failed");
free(addresses);
return -1;
}
listen(sockfd);



In the server case the bind call is simply replaced by sctp_bindx which takes a list off addresses as a parameter; only these specified addresses will be exchanged during association setup. In the example above only two addresses are specified however any number of local interface addresses can be added to the server address list before calling sctp_bindx.

The slightly more tricky and non-obvious case is when using only a subset of addresses on the client side of an association. Normally it is not required to call bind before calling connect, rather connect will automatically call bind with a port number 0. This means that the system will dynamically assign a free port to the connection. In the case of using only a subset of the addresses it is critical that all these addresses use the same port and hence we must obtain the system assigned port before being able to add multiple specific addresses .

The following steps are required to achieve this:
  1. Call bind on the socket giving the initial address that you want to set as the primary for the client
  2. Retrieve the port number that the system dynamically assigned
  3. Create the list of local client addresses to be used in the association making sure to use the same port number obtained in step 2
Client Code Snippet
// Create the Socket
sockfd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);

//Create Server Address
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(SERVERADDRESS);
serv_addr.sin_port = htons(SERVERPORT);

//Bind locally to only a subset of addresses
struct sockaddr_in client_addr;
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr = inet_addr(FIRSTLOCALADDRESS);
client_addr.sin_port = 0;
bind( sockfd, (struct sockaddr *)&client_addr, sizeof(client_addr) );
int port = client_addr.sin_port;

//Add the second local address
//Note a number of addresses can be added in the same manner as shown in the server code
int addrcount = 1; //adding one additional address
int addrsize = sizeof(struct sockaddr_in);

addresses = (struct sockaddr_in*) malloc(addrsize * addrcount);
if (addresses == NULL) {
perror("malloc");
exit(1);
}

client_addr.sin_addr.s_addr = inet_addr(SECONDWIFIADDRESS);
memcpy(addresses+1, &client_addr, addrsize);

//Bindx with address list
if(sctp_bindx( sockfd, (struct sockaddr *)&addresses, addrcount, SCTP_BINDX_ADD_ADDR ) == -1){
throw ("TunnelManager: bindx failed");
free(addresses);
exit(1);
}

//Connect to server
if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
perror("connect to server failed");
exit(1);
}

Installing an SSD in a Macbook Pro

A brief Intro


I recently bit the bullet and bought an SSD for my Macbook. Having heard numerous friends raving about the performance increase I could no longer resist. However, I was not willing to pay the exorbitant amount required to replace my 500GB drive with an SSD of equivalent size.
The solution was to lose the DVD drive and replace it with an SSD thereby getting a dual system with the speed benefits of an SSD and the capacity benefits of a traditional HD.

The Hardware


I opted for a 120GB SSD and a bracket known as a data doubler which allows the SSD to be mounted where the DVD drive normally sits. Both of these items are available from Other World Computing. My reasoning was that 120GB should be more than enough for the OS and most of my home directory while my media such as photos, videos and music, would be relegated to the HD.

The Install


I will not go into the gory details, sufficed to say the install is a breeze. The data doubler and SSD are specifically designed for Macbooks and as such come with excellent step-by-step instructions for all models. If you are anyway comfortable opening your laptop then the it will be absolutely no trouble. The total install time from opening the boxes to the first boot took all of 20 minutes.

The Dilemma


The main dillemma I faced was how to configure the system, from what I can see there are three main options.
  1. Install the OS on the SSD and migrate the user folders to the HD. The logic of this is that the apps will still boot quickly as they are located on the SSD but the large media files will be in the home directory on the higher capacity HD.
  2. Locate most of the home directory on the SSD but keep large media directories on the HD and symlink them to the SSD.
  3. Locate the OS and home folder on the SSD and use the HD as a separate drive to store large media files. Then use in built functionality in Aperture, iTunes etc. to use libraries located outside of the home folder.
After much deliberation I opted for option 3. With option 1 as the SSD is 120GB and my OS and applications occupy less than 40GB I would essentially be wasting 80GB of SSD - not a chance. Also, when applications launch they use the library directory located in the home folder and I thought may slow things down a little.
Option 2 seemed a little messy and it can be a little risky, one wrong keystroke and I may be recovering the system from a backup. Also, for backups Time Machine will not follow symlinks.

For me, option 3 gave me the best compromise, the full utilisation of the SSD for maximum speed and the large storage capacity of the HD for media and backup.

Battery Life


I have seen a number of posts asking about battery life differences. For me I have actually seen an increase in performance. The reason for this is that only my large media files are on the HD and so these are not in use very regularly. Therefore it is possible to spin down the HD when not in use thereby saving power. With only the lower power consuming SSD active most of the time my battery life has actually increased. This is an improvement that cannot be achieved with locating the home directory on the HD (Option 1).

In order to set the HD to spin down when not needed, use the following command in the terminal:
sudo pmset -a disksleep 1
(1 specifies the number of minutes of inactivity before the drive is spun down)

Conclusion


By far this is the best upgrade I have seen. The system is now so much faster and responsive, and It was by no means a slouch beforehand. Installing the SSD really allowed me to appreciate how much of a bottleneck the HD in a modern computer is. The system boots in no time and apps launch as if they were already opened and sitting in RAM. If you are on the fence about the purchase bite the bullet, you will not be disappointed!

Chilly iPhone


iphone-frozen
A few weeks ago, the WiFi on my iPhone began giving some trouble. Initially it would randomly disconnect or have trouble trying to scan for and connect to APs, until it stopped working completely.

I tried all the usual tricks, reseting network settings, restoring to to a previous backup at a time when the WiFi was working correct - all of this was to no avail.
I did some searching on Google and came up with mainly the same solutions I had already, unsuccessfully, tried.

I then found a reference to sticking the iPhone in the freezer. Thinking I had nothing to lose, I turned the phone off, wrapped it in a tea-cloth and left it in the freezer for 20 minutes; unfortunately I forgot about the phone a 3 hours later I pulled a very cold iPhone from the freezer.

It booted no problem and low and behold WiFi was working! My guess is that it is related to a problem with some connector and the drop in temperature causes the connector to contract and fit snugly back to where it belongs.

Dreamhost Hosting and GoDaddy Domain

So my first blog post is about how I setup up this site. I purchased my domain a couple of months ago from GoDaddy but due to lack of time I have not had a chance to set up my site, that was until my Christmas holidays.

The first thing I did was to check out what the best hosting plan for my site would be. After some deliberation I finally decided on Dreamhost. One of the main reasons for this was the amazing deal I got! On Lifehacker, I found a promo code for Dreamhost which entitled me to a 70% discount on a 2 year hosting plan which save me just over $151.

All in all it was a very smooth experience, Dreamhost allowed me to easily provide my existing domain and easily upload my site. The only sightly confusing thing was having my domain and hosting plan with different providers. It meant having to specify the Dreamhost nameservers in GoDaddy for my domain; the reason it was slightly confusing is that the GoDaddy interface is not very intuitive or pretty. Anyway I found the solution and maybe this will help others who encounter the same issue.
The solution was:
  1. Log into your GoDaddy dashboard
  2. Select ‘Domains’ and then go to ‘Domain Management’
  3. Then click on your domain, this will provide a small tab underneath the domain which says ‘’Manage Domain’ - click in this tab
  4. Under the NameServers heading click on ‘set nameservers’
  5. Then simply change the existing nameservers to the Dreamhost nameservers (Screenshot below)

Screen shot 2010-12-30 at 16.22.21