External k8gb presentation to Kubernetes SIG multicluster

Today I am a happy bunny!!!! Yury Tsarev (a very clever dude) did a presentation to one of the Kubernetes co-founders Tim Hockin. The demo was one of absa banks opensource projects called K8GB (a cloud native GSLB for K8s): https://www.k8gb.io/

Why do I like K8GB? Because it uses a single CRD that integrates to all the big DNS providers (like NS1, Infoblox and Route 53), it then uses zone delegation to allow the developers to manage their GTM in a single CRD. It also has native health checks using the liveliness and readiness kubernates probes (rather than just IMCP or http responses). Put simply it saves a whole bunch of unnecessary yak shaving!

So, if you have a few minutes you can watch the video (the demo starts after 10mins or so):

https://www.youtube.com/watch?v=jeUeRQM-ZyM

GIF so happy - animated GIF on GIFER

Windows 10: How to fix you desktop flashing icons

Just popping this here as I have had this a few times. Have you ever had your desktop icons flash and if you check explorer.exe its using high CPU. If so try:

Step 1. Delete the Icon Cache

Save the following as a batch file on your desktop and run it as admin:

cd /d %userprofile%\AppData\Local\Microsoft\Windows\Explorer 
attrib –h iconcache_*.db  
del iconcache_*.db 
start explorer
pause

Step 2. Tweak the Registry

Try setting these two reg keys to zero:

HKEY_CURRENT_USER\Control Panel\Desktop:ForegroundFlashCount
HKEY_CURRENT_USER\Control Panel\Desktop:ForegroundLockTimeout

Step 3. Switch of Indexing

Run either of these commands (as admin) to stop or suspend windows indexing

sc config cisvc start= disabled
sc config cisvc start= demand

Running Corporate Technology: Smart vs Traditional

There are two fundamental ways to run technology inside your company (and various states in-between)

The Truth

Before we get started, what lies beneath is actually a rant. It’s not even a well disguised rant and the reason for this is two fold. Firstly, I don’t expect many people to read this, so the return on the effort required to dress it up would be low. Secondly, I wrote this for my benefit to relieve frustration – nothing to do with trying to educate or for some greater good thingy. So if you continue to read this article, you are essentially paying my “frustration tax”… So thanks for that 🙂

The Models

Large corporates will tend to confuse a bad culture with poor performing staff. My experience is that a lot of execution issues center around cultural issues.

There are broadly two fundamental models of organising tech inside a corperate (and various states in-between).  To assess which world you live in, I have described the general characteristics of the two models below:

Model A:

  1. Your technology leadership/technology exco consists of auditors, CFOs, HR, risk management and generic management. They have never, will never and can never make a technology decision, as there is no understanding of technology. To solve for this, the leadership simply syndicate every single decision out to the widest possible group. Decisions take ages, as most of these groups also dont understand technology. When an eventual decision is made there can be no accountability as its unclear who made the call. By default they will always favour the status quo, they are extremely uncomfortable with all forms of change, they are fragile leaders and will focus a lof of effort on blame offloading. They still believe you cant get fired for buying IBM (no disrespect to IBM).
  2. You will spend a number of months collating voluminous documents containing all possible requirements for your products over the next n years. This is often mistaken to be a “strategy document”.
  3. You believe in developing technology away from your customer in “the center”. One day you feel you will “extract synergies” and “economies of scale” if you do this.
  4. You believe each business head should have a “single face off” into technology. This “engagement manager” (aka human inbox) attempts to use “influence” by routing escalation emails through the organisations hierarchy to try generate outcomes.
  5. Your central functions haven’t quite delivered yet, cost a small fortune, have top heavy management structure, BUT will “definitely deliver next year”. These functions manage using “gates and governance” and often send out new multi-page “Target Operating Model” documents which nobody reads/understands.
  6. You believe you can fix technology with manually captured metrics like SLAs, OLAs, KPIs etc etc. You have hundreds of these measures and you pay a small army to collate these metrics each month. These measures always come back as “Green”, but you are still unhappy with the performance of your technology teams. You feel that if you could just come up with that “killer metric” that would show how bad technology really is; you could then finally sign an outsourcing deal to “fix it”.
  7. You ask for documents from technology showing exactly what will be delivered over the next 3-5 years time horizon. You believe in these documents and feel that they are valuable. Historically they have never been close to accurate. You will likely see an item in 2025 which states “Digital Onboarding of Customers” – this is around the same time that the rest of the world will be enjoying the benefits of teleportation!
  8. You hire an army of people to track that technology are “delivering on time”, they are not delivering on time and you still don’t know why. To scale output you hire more people to track why technology is not delivering on time.
  9. You are constantly underwhelmed with what eventually gets delivered. It doesn’t do anything you really wanted it to and your customer feedback is lackluster at best.
  10. There are clear lines of distinction between technology and the business. Phrases like “I could make my budget… if I could only get some delivery from tech” are common place.
  11. The products delivered have all the charisma and charm of a road traffic accident.
  12. You believe, if you can just get the governance right and capture the requirements, then you will get the product you wanted.
  13. Your engagements with technology will take the form of “I need EVERYTHING from product X delivered by by date X. How much will it cost?”. When you get the reply a few months later, you will ALWAYS reply “that’s crazy!”. You will then cycle requirements down until you get beneath a “magic” number (that’s unknown to technology). This process and take years.
  14. Your teams spend more time in meetings or delivering static documents, than delivering business value.
  15. You layer governance meetings with various disconnected management teams, all with competing interests. This essentially turns an approval process into a multi-week/month attrition circus. The participants of this process have to explain and re-explain the exact same business case in multiple formats and leave the process with zero added insights, but minus a chunk of morale.
  16. If you ever looked at any documents signed related to technology spend, there are likely to be dozens of signatures on the documents and nobody quite recalls why they signed the document and who owns the actual decision for the spend.
  17. You direct as much technology spend as possible through a project governance process. This gives the illusion of a highly variable tech spend, focused on strategic investments. Your aggregate technology spend is nothing short of intergalactic. Funding abruptly expires at the end of each project and the resources promptly vanish. Most of your products are immature/half finished, you have a high number of (expensive) contractors, you leak IP, you love NDAs, nobody knows how to maintain or improve the products in production (as the contractors that delivered it have all left) and if you ever tried to reduced the SI spend, the “world will end”. 
  18. You can’t quite understand why everything in technology costs 10x what it would if you gave it to a start up.
  19. Technology is a grudge purchase, and internal technology spend is an absolute last resort. Most of the people in your technology teams have never written a line of code. You urge your CIO to sign outsourcing documents with a “low cost location”. You believe this will give you a 20px reduction in costs over 5 yrs. All the previous attempts to do this have failed. Next time will be different as this time you will capture the correct SLAs to fix technology. You use expressions like “we are a bank, not a technology company”. 
  20. You believe all the value stream is created in the selling of the digital artefact; not the creation of the artefact itself. Your solution to poorly designed artefacts that are hard to sell is to hire more sales staff.
  21. You fear open source and prefer to use multimillion dollar vendors for basics like middleware (please see Spring), business process management and databases. You build everything in your own data centre as you believe the “it’s a regulatory requirement”. It takes you several months to deliver hardware, or a engage with your vendors.
  22. You actively promote Monoculture. You believe that “do it once, everywhere, for everything, forever” is a meaningful sentence. You install single instances of monolithical services that everyone is force to use. These services are not automated and so generate hugely painful backlogs, both for maintenance and adding new services. You can never upgrade these monoliths without asking everyone to “stop what your doing and retest everything”. Teams spend a chunk of their time trying to engineer ways of “hacking” these monoliths in order to be able to deliver value to customers.
  23. You believe that most things in software are “utilities” and therefore belong in the center. You never look to prove that you get any benefits from this centralisation like lower costs, better quality or faster delivery times. The consumer of this service and the service provider will now both hire managers to work the functional boundary.
  24. In response to chronic stability issues you create various heavily populated central functions to solve things like “Capacity Management”, “Service Management”, “Change Management”, “Stability Management”. You can prepend the words: “We are really bad at ” to any of the above. Every time there is an outage the various management functions lead a charge into the application teams to report on what went wrong. The application teams spend more time speaking to the various functions than solving the actual issue. Getting a route cause is lengthy, as none of the various teams cannot agree on one version of the truth and there is infighting as each of the various areas looks to abstract themselves of any responsibility. You have effectively created a “functionally gridlock”.
  25. The business tend to export poor unilateral technology decisions to technology, and technology exports poor unilateral business decisions back. Technology will add arbitrarily points of friction/governance layers, change freezes, make material spend decisions and freeze hiring on critical products. Business will in turn sign low grade technology deals and hand them over the fence to technology to “make good” the decision.
  26. Your technology leaders will slavishly stick to their multiyear strategies; irrespective of how painful these choices may prove to be. If any innovation or alternatives are discovered during the sluggish execution of these strategies, they will resist any attempts to alter direction and try something new. 
  27. Bonus is assigned in a single amorphous blob at the top of the function. Both performing and non performing technology teams are equally “punished” with a low grade aggregate pot. Business, customer feedback and product quality have close to zero influence on either the pot size or its distribution. There are obvious advantages to hiring lower performing candidates and just a few rockstars/key men (as you would not be able to cover fair compensation for teams of high performers). It is highly likely that your organisation institutes some kind of bell curve on PD grades which further enforces that you can only have a rationed percentage of “A players”. This serves to foster the “key man” culture, ignoring the benefit of creating highly performing teams and creates a built in mechanism for “bonus casualties”.
  28. In an attempt to create efficiencies within an inefficient structure, you will tend to triplicate (find superficially similar products and artificially force them together at great expense, reduced output and increased cost/complexity). See The Triplication Paradigm
  29. Alignment costs cripple your organisation. You often find yourself aligning, re-aligning and then aligning again. Minutes are tacitly approved, then disputed, memories of what was agreed between the various functional areas are diverse. You periodically get back in a room with the same people, to discuss the same subjects and cover the same ground. Eventually you will tend to yield – resigning yourself to doing nothing (or find a “work around”).
  30. Your organisation believe rules will protect quality and consistency (the scaled efficiency model). Your process-focused culture will drive out the high-performing employees. When the market shifts quickly due to new technology, competitors, or business models, you can’t keep up and lose customers to competitors who adapt. You are slow-moving, rule-oriented and over time will grind “painfully into irrelevance”.

Model B:

  1. You hire technologists to make technology decisions. They are both collaborative and inclusive, but are happy to weigh up the facts and make decisions. These leaders constantly learn and love to share and tech.
  2. Business and technology is a pure partnership, with product development often starting with a sentence similar to, “I have x USD – work with me to get an MVP out in 3 months.”
  3. You realise the centre is not the place for client centric delivery. Technology is seen as an intimate collaborative process. 
  4. You believe in self organising and self navigation. No layering, no aggregation, no grand standing.
  5. Your central functions are thin, cheap and deliver scaled learning to the business facing teams. Other teams want to talk to them to share success, they are non political, encourage collaboration and do not sell gates and governance. The functions serve using the “zero wait” principle (i.e. they run with you to help, or let you run ahead). They NEVER block. 
  6. You have no manual metrics like SLAs, OLAs, KPIs etc. You just talk to the customer and fix what’s broken. All your products have comprehensive dashboards showing machine generated metrics, that would help track issues.
  7. You have no idea what you will be doing in 3 – 5 years.
  8. You have zero people tracking/reporting delivery. If you need to look in the rear view mirror, get it yourself from Jira.
  9. You are constantly flawed with the innovative solutions your teams have come up with. You could actually sell your products to other companies!
  10. There are no clear lines of distinction between technology and the business.
  11. The products delivered are designed iteratively with the customer at the centre, they have an “inspired” experience.
  12. You don’t believe in any governance, except macro finance.
  13. You neither read nor write requirements documents. Product documentation is developed after the fact and where possible is automated (eg Swagger).
  14. You teams reject most meetings, have a 15 min daily standup, use instance messaging groups, phone calls etc etc.
  15. Approval always sits at the lowest federated level, ideally with a single person or product owner.
  16. If you ever looked at any documents signed relating to technology spend, there would be single signatory. This person would be the actual decision maker, not an arbitrary person high up in the organisational hierarchy.
  17. You have zero projects. You work with finance at a macro level, not micro. Everything is a product and your variable tech spend is low. You have a high number of permanent staff and encourage internal mobility. Changing existing products is easy. You can’t remember when you last signed an NDA.
  18. You are able to both compete with and partner with start-ups. Your teams review start-up investments and find often find them “lacking”.
  19. Big outsourcing deals are never considered. You either buy and build (e.g. frameworks, cloud platforms) or build (with focus on open source). You actively recruit world class developers. You encourage a policy of “eat what you kill” to decommission expensive vendor solutions that are choking investment in the rest of the estate.
  20. You believe value is created equally in both selling and creation of digital artefacts; and you reward symmetrically.
  21. All new products are developed in the cloud, with an open source first approach. Your teams even share back to the wider open source community, e.g. https://twitter.com/donovancmuller. Your developers are proactively trained in security, you anonymising data, carry out automatic penetration testing as a part of your CI and hardware is just a debate about the efficient consumption of compute (e.g. serverless compute https://aws.amazon.com/lambda/details/).
  22. You actively encourage scaled learning, width of thought and interop – not points of singularity.
  23. You have have no system issues and therefore no central functions to track, the teams are empowered to solve the customer experience end to end. 
  24. All decisions (technology or business) are co-authored and validated as a single product team.
  25. Pay is dealt holistically, can often include revenue share and you are incentivised to hire the best and create the best products. There are no bell curves, good feedback is not rationed.
  26. Your technology leaders will not publish strategy documents, but instead focus on scaled learning, constant iteration, experimentation and prototypes. They will tend to evolve their strategies as they go and will actively look to absorb new ideas and constantly course correct.
  27. You pay zero for alignment; you have self organising teams that own their customers and stacks end to end.
  28. You believe in accountability, empowerment and Learning at Scale. You have principles, but no rules or heavy processes to “protect” quality/output.

I appreciate this article might be provocative, and that’s by design. The main point from the above is that the incumbent tech status quo in most corporates is not really challenged. Instead the tendency is to continuously draw and then redraw functional boundaries – in the process traumatising staff, relearning the exact same lessons and creating an internal talent vacuum. It’s interesting that the removal of these boundaries altogether is rarely questioned. In fact, in response to failed tech strategies most corporates will actually choose to scale these failed strategies – rather than question the validity of the approach. This is my view is a material mistake – technology is all about intimacy, and to get it right you need to embed it into your companies DNA.

To summarise, if you build an institution with “padded walls” you would expect a certain type of individual to be comfortable living there. Similarly, if you build a corporate that does not reflect it’s customer, if the roles of the leaders of this organisation are so generic it’s not clear what sits where and who does what, if layering your successful teams is culturally acceptable – then the staff working in this organisation will typically be staff that don’t care about details like the customer and being successful. This, I would argue, is not a long term game plan.

Example IAM Policy to Enforce EBS encryption

Here is a useful IAM conditional policy which will force EBS volumes to be encrypted when created by an EC2 instances.

{
   "Version": "2012-10-17",
   "Statement": [
     {
       "Sid": "Stmt2222222222222",
       "Effect": "Allow",
       "Action": [
         "ec2:CreateVolume"
       ],
       "Condition": {
         "Bool": {
           "ec2:Encrypted": "true"
         }
       },
       "Resource": [
         "*"
       ]
     },
     {
       "Sid": "Stmt1111111111111",
       "Effect": "Allow",
       "Action": [
         "ec2:DescribeVolumes",
         "ec2:DescribeAvailabilityZones",
         "ec2:CreateTags",
         "kms:ListAliases"
       ],
       "Resource": [
         "*"
       ]
     },
     {
       "Sid": "allowKmsKey",
       "Effect": "Allow",
       "Action": [
         "kms:Encrypt"
       ],
       "Resource": [
         "arn:aws:kms:us-east-1:999999999999:alias/aws/ebs"
       ]
     }
   ]
 }

The DAO Ethereum Recursion Bug: El Gordo!

If you found my article, I would consider it a reasonable assumption that you already understand the importance of this

Brief Introduction

The splitDAO function was created in order for some members of the DAO to separate themselves and their tokens from the main DAO, creating a new ‘child DAO’, for example in case they found themselves in disagreement with the majority.

The child DAO goes through the same 27 day creation period as the original DAO. Pre-requisite steps in order to call a splitDAO function are the creation of a new proposal on the original DAO and designation of a curator for the child DAO.

The child DAO created by the attacker has been referred as ‘darkDAO’ on reddit and the name seems to have stuck. The proposal and split process necessary for the attack was initiated at least 7 days prior to the incident.

The exploit one alone would have been economically unviable (attacker would have needed to put up 1/20th of the stolen amount upfront in the original DAO) and the second one alone would have been time intensive because normally only one splitDAO call could be done per transaction.

One way to see this is that the attacker performed a fraud, or a theft. Another way, more interesting for its implications, is that the attacker took the contract literally and followed the rule of code.

In their (allegedly) own words:

@stevecalifornia on Hacker News – https://news.ycombinator.com/item?id=11926150

“DAO, I closely read your contract and agreed to execute the clause where I can withdraw eth repeatedly and only be charged for my initial withdraw.

Thank you for the $70 million. Let me know if you draw up any other contracts I can participate in.

Regards, 0x304a554a310c7e546dfe434669c62820b7d83490″

The HACK

An “attacker” managed to combine two “exploits” in the DAO.

1) The attacker called the splitDAO function recursively (up to 20 times).

2) To make the attack more efficient, the attacker also managed to replicate the incident from the same two addresses (using the same tokens over and over again (approx 250 times).

Quote from “Luigi Renna”: To put this instance in a natural language perspective the Attacker requested the DAO “I want to withdraw all my tokens, and before that I want to withdraw all my tokens, and before that I want to… etc.” And be charged only once.

The Code That was Hacked

Below is the now infamous SplitDAO function in all its glory:

function splitDAO(
uint _proposalID,
address _newCurator
) noEther onlyTokenholders returns (bool _success) {
...
// Get the ether to be moved. Notice that this is done first!
uint fundsToBeMoved =
(balances[msg.sender] * p.splitData[0].splitBalance) /
p.splitData[0].totalSupply;
if (p.splitData[0].newDAO.createTokenProxy.value(fundsToBeMoved)(msg.sender) == false) // << This is
the line the attacker wants to run more than once
throw;
...
// Burn DAO Tokens
Transfer(msg.sender, 0, balances[msg.sender]);
withdrawRewardFor(msg.sender); // be nice, and get his rewards
// XXXXX Notice the preceding line is critically before the next few
•http://hackingdistributed.com/2016/06/18/analysis-of-the-dao-exploit/ Question: So what about Blockchain/DLs?
totalSupply -= balances[msg.sender]; // THIS IS DONE LAST
balances[msg.sender] = 0; // THIS IS DONE LAST TOO
paidOut[msg.sender] = 0;
return true;
}

The basic idea behind the hack was:

1) Propose a split.
2) Execute the split.
3) When the DAO goes to withdraw your reward, call the function to execute a split before that withdrawal
finishes (ie recursion).
4) The function will start running again without updating your balance!!!
5) The line we marked above as “This is the line the attacker wants to run more than once“ will run more
than once!

Thoughts on the Hack

The code is easy to fix, you can just simply zero the balances immediately after calculating the fundsToBeMoved. But this bug is not the real issue for me – the main problem can be split into two areas:

  1. Ethereum is a Turing complete language with a stack/heap, exceptions and recursion. This means that even with the best intentions, we will create a vast number of routes through the code base to allow similar recursion and other bugs to be exposed. The only barrier really is how much ether it will cost to expose the bugs.
  2. There is no Escape Hatch for “bad” contracts. Emin Gun Sirer wrote a great article on this here: Escape hatches for smart contracts

Whilst a lot of focus is going in 2) – I believe that more focus needs to be put into making the language “safer”. For me, this would involve basic changes like:

  1. Blocking recursion. Blocking recursion at compile and runtime would be a big step forward. I struggle to see a downside to this, as in general recursion doesn’t scale, is slow and can always be replaced with iteration. Replace Recursion with Iteration
  2. Sandbox parameterisation. Currently there are no sandbox parameters to sit the contracts in. This means contracts the economic impact of these contracts are more empirical than deterministic. If you could abstract core parameters of the contract like the amount, wallet addresses etc etc and place these key values in an immutable wrapper than unwanted outcomes would be harder to achieve.
  3. Transactionality. Currently there in no obvious mechanism to peform economic functions wraped in an ATOMIC transaction. This ability would mean that economic values could be copied from the heap to the stack and moved as desired; but critically recursive calls could no revist the heap to essentially “duplicate” the value. It would also mean that if a benign fault occured the execution of the contract would be idempotent. Obviously blocking recursive calls goes some way towards this; but adding transactionality would be a material improvement.

I have other ideas including segregation of duties using API layers between core and contract code – but am still getting my head around Ethereum’s architecture.

How to Ping a computer using .NET Sockets

///
/// The main entry point for the application.
///
[STAThread]

static void Main(string[] args)
{

    int timeToReplyMs = Ping("andrewbaker.ninja", 10000);
    Console.WriteLine("Time Taken(ms): " + timeToReplyMs);
}




#region Ping Method
///
/// Pings a host and returns the time taken for the host to respond (given the host name or IP address of the host to ping).
///



/// The host (machine name or IP address) to ping.
/// The ping timeout in ms (zero represents infinite).
/// Returns the time in milliseconds to receive a response from the host.

public static int Ping(string host, int timeout)

{

    //IPHostEntry ipHost = Dns.GetHostByName(host);
    IPHostEntry ipHost = Dns.GetHostEntry(host);

    // Ping the server
    return Ping(ipHost, timeout);

}




///
/// Pings a host and returns the time taken for the host to respond.
///




/// The host to ping.
/// The ping timeout in ms (zero represents infinite).
/// Returns the time in milliseconds to receive a response from the host.

public static int Ping(IPHostEntry host, int timeout)

{

    // Declare some Constant Variables
    const int SOCKET_ERROR = -1;
    const int ICMP_ECHO = 8;
    int timeTaken;



    // Declare the IPHostEntry
    if (host == null)
    {
        throw new ArgumentNullException("host", "The host to ping must be specified.");
    }

    Socket socket = null;

    try

    {
        // Initilize a Socket of the Type ICMP
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);


        // Convert to the first Ip address from the host to an endpoint
        IPEndPoint ipepServer = new IPEndPoint(_GetValidAddress(host.AddressList), 0);
        EndPoint epServer = (ipepServer);

        // Set the receiving endpoint to the client machine
        IPHostEntry localHost;

        localHost = Dns.GetHostEntry(Dns.GetHostName());
        IPEndPoint ipEndPointFrom = new IPEndPoint(_GetValidAddress(localHost.AddressList), 0);
        EndPoint EndPointFrom = (ipEndPointFrom);


        int packetSize;

        IcmpPacket packet = new IcmpPacket();

        // Construct the echo packet
        packet.Type = ICMP_ECHO; //8
        packet.SubCode = 0;
        packet.CheckSum = UInt16.Parse("0");
        packet.Identifier = UInt16.Parse("45");
        packet.SequenceNumber = UInt16.Parse("0");

        int pingDataSize = 32; // sizeof(IcmpPacket) - 8;

        packet.Data = new Byte[pingDataSize];

        // Initilize the Packet.Data
        for (int i = 0; i < pingDataSize; i++)
        {
            packet.Data[i] = (byte)'#';
        }

        // Variable to hold the total Packet size
        packetSize = pingDataSize + 8;
        Byte[] icmpPacketBuffer = new Byte[packetSize];
        int totalPacketSize;


        // Call Serialize, which counts the total number of Bytes in the Packet
        totalPacketSize = _SerializePacket(packet, icmpPacketBuffer, packetSize, pingDataSize);


        // Error in Packet Size
        if (totalPacketSize == -1)
        {
            // Throw serialization exception
            throw new ApplicationException("Error serializing packet buffer");
        }

        // Get the packet into a UInt16 array
        // Get the Half size of the Packet
        Double packetSizeDouble = Convert.ToDouble(totalPacketSize);
        Double halfPacketSizeDouble = Math.Ceiling(packetSizeDouble / 2);
        int checkSumBufferLength = Convert.ToInt32(halfPacketSizeDouble);

        // Create a Byte Array
        UInt16[] checkSumBuffer = new UInt16[checkSumBufferLength];

        // Code to initilize the Uint16 array
        int icmpHeaderBufferIndex = 0;

        for (int i = 0; i < checkSumBufferLength; i++)
        {
            checkSumBuffer[i] = BitConverter.ToUInt16(icmpPacketBuffer, icmpHeaderBufferIndex);
            icmpHeaderBufferIndex += 2;

        }

        // Call a method which will return a checksum
        UInt16 unsignedCheckSum = _CalcChecksum(checkSumBuffer, checkSumBufferLength);

        // Save the checksum to the Packet
        packet.CheckSum = unsignedCheckSum;

        // Have the checksum, serialize the packet again
        Byte[] sendbuf = new Byte[packetSize];

        // Check the packet size
        totalPacketSize = _SerializePacket(packet, sendbuf, packetSize, pingDataSize);


        if (totalPacketSize == -1)
        {
            // Throw serialization exception
            throw new ApplicationException("Error serializing packet buffer");

        }


        // Start timing
        int dwStart = Environment.TickCount;

        // Send the Packet
        if (socket.SendTo(sendbuf, packetSize, 0, epServer) == SOCKET_ERROR)
        {
            throw new ApplicationException("Failed to send packet to " + host.HostName + ".");

        }


        // Initialize the buffers. The receive buffer is the size of the
        // ICMP header plus the IP header (20 bytes)
        Byte[] arrayBytesReceived = new Byte[256];


        // Loop for checking the time of the server responding
        while (true)

        {

            int nBytes = socket.ReceiveFrom(arrayBytesReceived, 256, 0, ref EndPointFrom);
            timeTaken = Environment.TickCount - dwStart;



            if (nBytes == SOCKET_ERROR)
            {

                throw new ApplicationException("Failed to receive response to echo packet from " + host.HostName + ".");

            }

            else if (nBytes > 0)

            {
                // Received message
                // int dwStop = Environment.TickCount - dwStart;
                // Console.WriteLine("Reply from " + epServer.ToString() + " in " + dwStop + "MS :Bytes Received" + nBytes);
                break;
            }




            // Default to a one second timeout
            if (timeTaken > timeout && timeout > 0)
            {
                throw new ApplicationException("Ping to " + host.HostName + " timed out after " + timeout + " milliseconds.");
            }
        }

    }
    finally
    {
        if (socket != null)
        {
            // close the socket
            socket.Shutdown(SocketShutdown.Both);
            socket.Close();
        }

    }




    return timeTaken;

}

//
// Find a valid IP address
private static IPAddress _GetValidAddress(IPAddress[] addressList)
{
    for (int i = 0; i < addressList.Length; i++)
    {
        try
        {
            var address = addressList[i].Address;
        }
        catch (Exception)
        {
            // Invalid address
            continue;
        }
        // The address is valid
        return addressList[i];
    }
    return null;
}



#region Private Methods

///
/// This method get the Packet and calculates the total size
/// of the Pack by converting it to byte array
///
private static int _SerializePacket(IcmpPacket packet, Byte[] Buffer, int PacketSize, int PingData)

{

    int cbReturn;

    // serialize the struct into the array
    int Index = 0;


    Byte[] b_type = new Byte[1];
    b_type[0] = (packet.Type);

    Byte[] b_code = new Byte[1];
    b_code[0] = (packet.SubCode);

    Byte[] b_cksum = BitConverter.GetBytes(packet.CheckSum);
    Byte[] b_id = BitConverter.GetBytes(packet.Identifier);
    Byte[] b_seq = BitConverter.GetBytes(packet.SequenceNumber);


    // Console.WriteLine("Serialize type ");
    Array.Copy(b_type, 0, Buffer, Index, b_type.Length);
    Index += b_type.Length;

    // Console.WriteLine("Serialize code ");
    Array.Copy(b_code, 0, Buffer, Index, b_code.Length);
    Index += b_code.Length;

    // Console.WriteLine("Serialize cksum ");
    Array.Copy(b_cksum, 0, Buffer, Index, b_cksum.Length);
    Index += b_cksum.Length;

    // Console.WriteLine("Serialize id ");
    Array.Copy(b_id, 0, Buffer, Index, b_id.Length);
    Index += b_id.Length;

    Array.Copy(b_seq, 0, Buffer, Index, b_seq.Length);
    Index += b_seq.Length;

    // copy the data
    Array.Copy(packet.Data, 0, Buffer, Index, PingData);

    Index += PingData;

    if (Index != PacketSize/* sizeof(IcmpPacket) */)
    {
        cbReturn = -1;
        return cbReturn;
    }

    cbReturn = Index;
    return cbReturn;
}

///
/// This Method has the algorithm to make a checksum
///
private static UInt16 _CalcChecksum(UInt16[] buffer, int size)

{
    int cksum = 0;
    int counter;

    counter = 0;

    while (size > 0)
    {
        UInt16 val = buffer[counter];
        cksum += Convert.ToInt32(val);
        counter += 1;
        size -= 1;
    }

    cksum = (cksum >> 16) + (cksum & 0xffff);
    cksum += (cksum >> 16);

    return (UInt16)(~cksum);

}

#endregion Private Methods




#region IcmpPacket Class (Private)

///
/// Class that holds the Pack information.
///
private class IcmpPacket
{

    ///
    /// Type of message
    ///
    public Byte Type;

    ///
    /// Type of sub code
    ///
    public Byte SubCode;

    ///
    /// Complement checksum of struct
    ///
    public UInt16 CheckSum;

    ///
    /// Identifier
    ///
    public UInt16 Identifier;

    ///
    /// Sequence number
    ///
    public UInt16 SequenceNumber;

    ///
    /// The data
    ///
    public Byte[] Data;

}

#endregion IcmpPacket Class (Private)

}

endregion

High Performance Timer

Below is a sample class containing a high performance timer. Example usuage:

PerformanceTimer pf = new PerformanceTimer(true);

float timeMs = pf.GetTimeMs();

using System;
using System.Runtime.InteropServices;

///
/// This class can be used to gather accurate performance timings.
///
public class PerformanceTimer
{


[DllImport("kernel32.dll")]
internal static extern bool QueryPerformanceCounter(ref long lpPerformanceCount);



[DllImport("kernel32.dll")]
internal static extern bool QueryPerformanceFrequency(ref long lpFrequency);



#region Private Variables

private bool _isRunning = false;
private long _startTime = 0;
private long _frequency = 0;
private float _elapsed = 0;

#endregion Private Variables



#region Constructors



///
/// Default constructor - does not start timer immediately.
///
public PerformanceTimer()
{

}



///
/// Constructor with option to start timer at same time.
///
///Whether to start timer immediately.

public PerformanceTimer(bool startTimer)

{

    if (startTimer)
    {

        Start();

    }

}

#endregion Constructors


#region Public Properties

///
/// Returns True if the timer is currently running.
///
/// To change the running state use the Start and Stop methods provided.

public bool IsRunning
{
    get { return _isRunning; }
}



#endregion Public Properties



#region Public Methods



///
/// Starts the performance timer running.
///

public void Start()

{
    QueryPerformanceFrequency(ref _frequency);
    QueryPerformanceCounter(ref _startTime);
    _elapsed = 0;
    _isRunning = true;

}



///
/// Stops the performance timer running.
///

public void Stop()

{

    // Call procedure that will set internal elapsed variable, then turn running flag off.

    GetTime();

    _isRunning = false;

}



///

/// Returns the time elapsed since "Start" was called (in seconds). If the timer

/// is not running the time elapsed between the last start and stop time is returned.

///

/// A float representing the time ellapsed (in seconds)

public float GetTime()

{

    if (_isRunning)
    {
        long endTime = 0;
        QueryPerformanceCounter(ref endTime);
        _elapsed = (float)(endTime - _startTime) / _frequency;
        return _elapsed;
    }
    else
    {
        return _elapsed;
    }
}



///
/// Returns the time elapsed since "Start" was called (in milliseconds). If the timer
/// is not running the time elapsed between the last start and stop time is returned.
///
/// A float representing the time ellapsed (in milliseconds)

public float GetTimeMs()

{
    if (_isRunning)
    {
        return GetTime() * 1000;
    }
    else
    {
        return _elapsed * 1000;

    }

}



///
/// Override ToString to display time nicely formatted.
///
/// Returns the time formatted as a string.

public override string ToString()

{
    return String.Format("{0:0000.000}s ", GetTime());
}
#endregion Public Methods

}

Importing Data From an Excel Workbook into a VB array

The following code can be used to import the contents of an excel workbook into an array from within a Visual Basic application.

Option Explicit

'Purpose     :  Reads an excel workbook's worksheet into a 2d array
'Inputs      :  sWorkbookPath           The path of the workbook to return the data from.
'               [sSheetName]            The name of the worksheet to return the data from.
'Outputs     :  Returns True if successful
'Author      :  Andrew Baker
'Date        :  31/12/2000 13:51
'Notes       :
'Revisions   :

Function ImportWorksheetFromExcel(sWorkbookPath As String, Optional sSheetName As String = "") As Variant
    Dim oExcel As Object
    Dim oWorkbook As Object
    Dim oWkSheet As Object
    Dim avValues As Variant
    
    On Error Resume Next
    'Check if file exists
    If Len(Dir$(sWorkbookPath)) > 0 Then
        Set oExcel = CreateObject("Excel.Application")
        If (oExcel Is Nothing) = False Then
            On Error GoTo ErrFailed
            'Successfully created an Excel Application
            'Open workbook
            Set oWorkbook = oExcel.Workbooks.Open(sWorkbookPath, False, True)
            'Add sheet to store results
            If Len(sSheetName) > 0 Then
                Set oWkSheet = oWorkbook.Sheets(sSheetName)
            Else
                'Just use first sheet
                Set oWkSheet = oWorkbook.Sheets(1)
            End If
            
            'Get used range
            Call RangeToArray(oWkSheet.UsedRange, avValues)
            
            'Close Excel
            oWorkbook.Close False
            oExcel.Quit
            Set oExcel = Nothing
        End If
    End If
    
    ImportWorksheetFromExcel = avValues
    Exit Function

ErrFailed:
    Debug.Assert False
    Debug.Print Err.Description
    On Error GoTo 0
End Function

'Purpose     :  Reads the values of a range into an array (much quicker than looping through a range)
'Inputs      :  rngInput                The range to extract the values from.
'               avValues                See outputs.
'Outputs     :  Returns the True on success.
'               avValues                An 2d array containing the values in the range.
'Author      :  Andrew Baker
'Date        :  31/12/2000 13:51
'Notes       :
'Revisions   :
'Example     :  Call RangeToArray(Worksheets(1).Range("A1:K1000"), avValues)

Function RangeToArray(rngInput As Object, avValues As Variant) As Boolean
    On Error GoTo ErrFailed
    avValues = Empty
    avValues = rngInput.Value
    RangeToArray = True
    
    Exit Function

ErrFailed:
    'Failed
    Debug.Print "Error in RangeToArray: " & Err.Description
    Debug.Assert False
    RangeToArray = False
    On Error GoTo 0
End Function

'Demonstration routine.
Sub Test()
    Dim avData As Variant, vCell As Variant

    avData = ImportWorksheetFromExcel("C:\Book1.xls")
    For Each vCell In avData
        Debug.Print "Cell: " + vCell
    Next
End Sub

Simple function to Add a number of weekdays to a date

Below is a simple function to add or subtract a number of weekdays to a specified date.

/// <summary>
/// Takes a reference date and add or subtracts a specified number of weekdays.
/// </summary>
/// <param name="date">The reference date.</param>
/// <param name="offset">The number of days to offset by.</param>
/// <returns>The reference date plus or minus the specified number of weekdays.</returns>
private DateTime AddWeekDays( DateTime date, int offset)
{
	int daysAdded = 0;
	int addDay = 1;
	if (offset < 0)
	{
		addDay = -1;
	}
	DateTime result = date;
	do
	{
		if (daysAdded == offset)
		{
			break;
		}
		if (result.DayOfWeek != DayOfWeek.Saturday && result.DayOfWeek != DayOfWeek.Sunday)
		{
			daysAdded = daysAdded + addDay;
		}
		result = result.AddDays(addDay);
	} while (true);
	return result;
}