void Session::Challenged(const Response &response)
  {
    if(Stopped()) {
      return;
    }

    if(response.Successful()) {
      QPair<bool, QVariant> auth = _auth->ProcessChallenge(response.GetData());
      if(auth.first) {
        qDebug() << "Sending challenge response";
        SendChallenge(false, auth.second);
        return;
      }

      qDebug() << "Received an invalid challenge, retrying.";
    }

    if(!_register_event.Stopped()) {
      qDebug() << "Almost started two registration attempts simultaneously!";
      return;
    }

    int delay = 5000;
    if(response.GetErrorType() == Response::Other) {
      delay = 60000;
    }
    qDebug() << "Unable to register due to" << response.GetError() <<
      "Trying again later.";

    Dissent::Utils::TimerCallback *cb =
      new Dissent::Utils::TimerMethod<Session, int>(this, &Session::Register, 0);
    _register_event = Dissent::Utils::Timer::GetInstance().QueueCallback(cb, delay);
  }
  void NtfyPacket(std::shared_ptr<GlobalGrid::VSocket> socket,unsigned char* packetData, size_t packetLength) {
    
    if(sessions.find(socket) == sessions.end()) {
      //We should have an AES key in our packet here encrypted with our public key.
      
      
      //Packet header -- thumbprint (16 bytes) (unverified data element), session key (variable length, encrypted)
      if(packetLength<=16) {
	return;
      }
      void* packet = RSA_Decrypt(privkey,packetData+16,packetLength-16);
      if(packet == 0) { //Decryption failure.
	return;
      }
      unsigned char* buffer;
      size_t sz;
      GlobalGrid::Buffer_Get(packet,&buffer,&sz);
      if(sz>=32) {
	//We have a new Session.
	Session route(socket,buffer,packetData);
	sessions.insert(route);
	//Respond with ACK, which verifies our identity
	//Send challenge to verify remote identity.
	
	char hexprint[33];
	ToHexString((unsigned char*)route.claimedThumbprint,16,hexprint);
	hexprint[32] = 0;
	
	void* remoteKey = DB_FindAuthority(hexprint);
	
	if(remoteKey) {
	  SendChallenge(remoteKey,route,socket);
	}else {
	  //We don't have a remote key. Request it.
	  unsigned char izard[16];
	  memset(izard,0,16);
	  izard[0] = 2;
	  aes_encrypt(route.key,izard);
	  socket->Send(izard,16);
	}
	GlobalGrid::GGObject_Free(packet);
      }else {
	GlobalGrid::GGObject_Free(packet);
      }
    }else {
      //Bind to existing Session.
      if(packetLength % 16 != 0) {
	//Invalid packet.
	return;
      }
      
      Session session = *sessions.find(socket);
      for(size_t i = 0;i<packetLength;i+=16) {
	aes_decrypt(session.key,packetData+i);
      }
      
      switch(*packetData) {
	case 0:
	  //Challenge request
	{
	  //Decrypt challenge
	  uint16_t len;
	  memcpy(&len,packetData+1,2);
	  void* challenge = RSA_Decrypt(privkey,packetData+1+2,len);
	  if(challenge == 0) {
	    return;
	  }
	  unsigned char* challenge_bytes;
	  size_t challenge_sz;
	  
	  GlobalGrid::Buffer_Get(challenge,&challenge_bytes,&challenge_sz);
	  if(challenge_sz != 16) {
	    GlobalGrid::GGObject_Free(challenge);
	    return;
	  }
	  
	  unsigned char response[32];
	  memset(response,0,32);
	  response[0] = 1;
	  memcpy(response+1,challenge_bytes,16);
	  aes_encrypt(session.key,response);
	  aes_encrypt(session.key,response+16);
	  socket->Send(response,32);
	  GlobalGrid::GGObject_Free(challenge);
	  
	  
	}
	  break;
	case 1:
	{
	  //Response to challenge (identity verification)
	  if(memcmp(session.challenge,packetData+1,16) == 0) {
	    session.verified = true;
	    printf("Identity verified.\n");
	  }
	}
	  break;
	case 2:
	{
	  //Request for public encryptionKey.
	  void* key = RSA_Export(privkey,false);
	  unsigned char* key_bytes;
	  size_t key_size;
	  GlobalGrid::Buffer_Get(key,&key_bytes,&key_size);
	  size_t aligned = key_size+1;
	  aligned+=16-(aligned % 16);
	  
	  unsigned char* packet = new unsigned char[aligned];
	  memcpy(packet+1,key_bytes,key_size);
	  packet[0] = 3;
	  
	  for(size_t i = 0;i<aligned;i+=16) {
	    aes_encrypt(session.key,packet+i);
	  }
	  
	  socket->Send(packet,aligned);
	  delete[] packet;
	  GlobalGrid::GGObject_Free(key);
	  
	}
	  break;
	case 3:
	{
	  //Received public encryption key
	  void* key = RSA_Key(packetData+1,packetLength-1);
	  char thumbprint[33];
	  RSA_thumbprint(key,thumbprint);
	  thumbprint[32] = 0;
	  void* obj = DB_FindAuthority(thumbprint);
	  if(obj == 0) {
	    void* keybin = RSA_Export(key,false);
	    unsigned char* cert;
	    size_t cert_len;
	    GlobalGrid::Buffer_Get(keybin,&cert,&cert_len);
	    DB_Insert_Certificate(thumbprint,cert,cert_len,false);
	    GlobalGrid::GGObject_Free(keybin);
	    if(session.verified == false) {
	      //TODO: Send verification request
	      SendChallenge(key,session,socket);
	    }
	  }else {
	    RSA_Free(obj);
	  }
	}
	  break;
	case 4:
	{
	  //Route packet
	  packetData++;
	  unsigned char ttl = *packetData;
	  packetData++;
	  
	  //Intended destination
	  GlobalGrid::Guid dest;
	  memcpy(dest.value,packetData,16);
	  packetData+=16;
	  GlobalGrid::Guid localThumbprint;
	  RSA_thumbprint(privkey,(unsigned char*)localThumbprint.value);
	  uint32_t packetSize;
	  memcpy(&packetSize,packetData,4);
	  packetData+=16;
	  if(dest == localGuid) {
	    printf("TODO: Packet destined for ourselves\n");
	    return;
	  }
	  SendPacket(packetData,packetSize,ttl,dest,session.claimedThumbprint);
	  
	}
	  break;
      }
    }
  }