<commit_before>#include "sipregistration.h"

#include "serverstatusview.h"

#include "common.h"
#include "global.h"
#include "logger.h"

#include <QVariant>

const int REGISTER_SEND_PERIOD = (REGISTER_INTERVAL - 5)*1000;


SIPRegistration::SIPRegistration():
  retryTimer_(nullptr),
  attemptedAuth_(false)
{}


SIPRegistration::~SIPRegistration()
{}


void SIPRegistration::init(ServerStatusView *statusView)
{
  Logger::getLogger()->printNormal(this, "Initiating Registration");
  statusView_ = statusView;

  QObject::connect(&retryTimer_, &QTimer::timeout,
                   this, &SIPRegistration::refreshRegistration);

  retryTimer_.setInterval(REGISTER_SEND_PERIOD); // have 5 seconds extra to reach registrar
  retryTimer_.setSingleShot(false);
}


void SIPRegistration::uninit()
{
  if (status_ == REG_ACTIVE)
  {
    sendREGISTERRequest(0, DEREGISTERING);
  }

  Logger::getLogger()->printNormal(this, "Finished uniniating registration");
  return;
}


void SIPRegistration::bindToServer(NameAddr& addressRecord, QString localAddress,
                                    uint16_t port)
{
  Logger::getLogger()->printNormal(this, "Binding to server", {"Server"},
                                   {addressRecord.uri.hostport.host});

  status_ = INACTIVE;
  contactAddress_ = localAddress;
  contactPort_ = port;

  serverAddress_ = addressRecord.uri.hostport.host;
  statusView_->updateServerStatus("Request sent. Waiting response...");

  sendREGISTERRequest(REGISTER_INTERVAL, FIRST_REGISTRATION);
}


void SIPRegistration::processIncomingResponse(SIPResponse& response, QVariant& content)
{
  Q_UNUSED(content);
  // REGISTER response must not create route. In other words ignore all record-routes

  if (response.message->cSeq.method == SIP_REGISTER)
  {
    if (serverAddress_ == response.message->to.address.uri.hostport.host)
    {
      if (response.type == SIP_OK)
      {
        attemptedAuth_ = false; // reset our attempts so if the digest expires,
                                // we auth again

        if (status_ != RE_REGISTRATION &&
            response.message->vias.at(0).receivedAddress != "" &&
            response.message->vias.at(0).rportValue != 0 &&
            (contactAddress_ != response.message->vias.at(0).receivedAddress ||
             contactPort_ != response.message->vias.at(0).rportValue))
        {
          Logger::getLogger()->printNormal(this, "Detected that we are behind NAT!");

          // we want to remove the previous registration so it doesn't cause problems
          if (status_ == FIRST_REGISTRATION)
          {
            Logger::getLogger()->printNormal(this, "Resetting previous registration");
            sendREGISTERRequest(0, DEREGISTERING);
            return;
          }
          else if (status_ == DEREGISTERING)// the actual NAT registration
          {
            Logger::getLogger()->printNormal(this, "Sending the final NAT REGISTER");
            contactAddress_ = response.message->contact.first().address.uri.hostport.host;
            contactPort_ = response.message->contact.first().address.uri.hostport.port;
            // makes sure we don't end up in infinite loop if the address doesn't match

            statusView_->updateServerStatus("Behind NAT, updating address...");

             // re-REGISTER with NAT address and port
            sendREGISTERRequest(REGISTER_INTERVAL, RE_REGISTRATION);
            return;
          }
          else
          {
            Logger::getLogger()->printError(this, "The Registration response does not match internal state");
          }
        }
        else
        {
          statusView_->updateServerStatus("Registered");
        }

        status_ = REG_ACTIVE;

        if (!retryTimer_.isActive())
        {
          retryTimer_.start(REGISTER_SEND_PERIOD);
        }<commit_msg>fix(Transaction): Prevent crash if no contacts are received<commit_after>#include "sipregistration.h"

#include "serverstatusview.h"

#include "common.h"
#include "global.h"
#include "logger.h"

#include <QVariant>

const int REGISTER_SEND_PERIOD = (REGISTER_INTERVAL - 5)*1000;


SIPRegistration::SIPRegistration():
  retryTimer_(nullptr),
  attemptedAuth_(false)
{}


SIPRegistration::~SIPRegistration()
{}


void SIPRegistration::init(ServerStatusView *statusView)
{
  Logger::getLogger()->printNormal(this, "Initiating Registration");
  statusView_ = statusView;

  QObject::connect(&retryTimer_, &QTimer::timeout,
                   this, &SIPRegistration::refreshRegistration);

  retryTimer_.setInterval(REGISTER_SEND_PERIOD); // have 5 seconds extra to reach registrar
  retryTimer_.setSingleShot(false);
}


void SIPRegistration::uninit()
{
  if (status_ == REG_ACTIVE)
  {
    sendREGISTERRequest(0, DEREGISTERING);
  }

  Logger::getLogger()->printNormal(this, "Finished uniniating registration");
  return;
}


void SIPRegistration::bindToServer(NameAddr& addressRecord, QString localAddress,
                                    uint16_t port)
{
  Logger::getLogger()->printNormal(this, "Binding to server", {"Server"},
                                   {addressRecord.uri.hostport.host});

  status_ = INACTIVE;
  contactAddress_ = localAddress;
  contactPort_ = port;

  serverAddress_ = addressRecord.uri.hostport.host;
  statusView_->updateServerStatus("Request sent. Waiting response...");

  sendREGISTERRequest(REGISTER_INTERVAL, FIRST_REGISTRATION);
}


void SIPRegistration::processIncomingResponse(SIPResponse& response, QVariant& content)
{
  Q_UNUSED(content);
  // REGISTER response must not create route. In other words ignore all record-routes

  if (response.message->cSeq.method == SIP_REGISTER)
  {
    if (serverAddress_ == response.message->to.address.uri.hostport.host)
    {
      if (response.type == SIP_OK)
      {
        attemptedAuth_ = false; // reset our attempts so if the digest expires,
                                // we auth again

        if (status_ != RE_REGISTRATION &&
            response.message->vias.at(0).receivedAddress != "" &&
            response.message->vias.at(0).rportValue != 0 &&
            (contactAddress_ != response.message->vias.at(0).receivedAddress ||
             contactPort_ != response.message->vias.at(0).rportValue))
        {
          Logger::getLogger()->printNormal(this, "Detected that we are behind NAT!");

          // we want to remove the previous registration so it doesn't cause problems
          if (status_ == FIRST_REGISTRATION)
          {
            Logger::getLogger()->printNormal(this, "Resetting previous registration");
            sendREGISTERRequest(0, DEREGISTERING);
            return;
          }
          else if (status_ == DEREGISTERING)// the actual NAT registration
          {
            if (!response.message->contact.empty())
            {
              Logger::getLogger()->printNormal(this, "Sending the final NAT REGISTER");
              contactAddress_ = response.message->contact.first().address.uri.hostport.host;
              contactPort_ = response.message->contact.first().address.uri.hostport.port;
              // makes sure we don't end up in infinite loop if the address doesn't match

              statusView_->updateServerStatus("Behind NAT, updating address...");

               // re-REGISTER with NAT address and port
              sendREGISTERRequest(REGISTER_INTERVAL, RE_REGISTRATION);
            }
            else
            {
              Logger::getLogger()->printError(this, "Failed to get contacts in REGISTER response");
            }
            return;
          }
          else
          {
            Logger::getLogger()->printError(this, "The Registration response does not match internal state");
          }
        }
        else
        {
          statusView_->updateServerStatus("Registered");
        }

        status_ = REG_ACTIVE;

        if (!retryTimer_.isActive())
        {
          retryTimer_.start(REGISTER_SEND_PERIOD);
        }
{'fraction_non_alphanumeric': 0.11174027935069837, 'fraction_numerical': 0.003775009437523594, 'mean_word_length': 2.71575502571295, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2550745', 'n_tokens_mistral': 2241, 'n_tokens_neox': 2180, 'n_words': 462}