/**********
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)

This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
more details.

You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
**********/
// "liveMedia"
// Copyright (c) 1996-2020 Live Networks, Inc.  All rights reserved.
// A generic SIP client
// Implementation

#include "SIPClient.hh"
#include "GroupsockHelper.hh"

#if defined(__WIN32__) || defined(_WIN32) || defined(_QNX4)
#define _strncasecmp _strnicmp
#else
#define _strncasecmp strncasecmp
#endif

////////// SIPClient //////////

SIPClient* SIPClient
::createNew(UsageEnvironment& env,
	    unsigned char desiredAudioRTPPayloadFormat,
	    char const* mimeSubtype,
	    int verbosityLevel, char const* applicationName) {
  return new SIPClient(env, desiredAudioRTPPayloadFormat, mimeSubtype,
		       verbosityLevel, applicationName);
}

void SIPClient::setUserAgentString(char const* userAgentName) {
  if (userAgentName == NULL) return;

  // Change the existing user agent header string:
  char const* const formatStr = "User-Agent: %s\r\n";
  unsigned const headerSize = strlen(formatStr) + strlen(userAgentName);
  delete[] fUserAgentHeaderStr;
  fUserAgentHeaderStr = new char[headerSize];
  sprintf(fUserAgentHeaderStr, formatStr, userAgentName);
  fUserAgentHeaderStrLen = strlen(fUserAgentHeaderStr);
}

SIPClient::SIPClient(UsageEnvironment& env,
		     unsigned char desiredAudioRTPPayloadFormat,
		     char const* mimeSubtype,
		     int verbosityLevel, char const* applicationName)
  : Medium(env),
    fT1(500000 /* 500 ms */),
    fDesiredAudioRTPPayloadFormat(desiredAudioRTPPayloadFormat),
    fVerbosityLevel(verbosityLevel), fCSeq(0),
    fUserAgentHeaderStr(NULL), fUserAgentHeaderStrLen(0),
    fURL(NULL), fURLSize(0),
    fToTagStr(NULL), fToTagStrSize(0),
    fUserName(NULL), fUserNameSize(0),
    fInviteSDPDescription(NULL), fInviteSDPDescriptionReturned(NULL),
    fInviteCmd(NULL), fInviteCmdSize(0) {
  if (mimeSubtype == NULL) mimeSubtype = "";
  fMIMESubtype = strDup(mimeSubtype);
  fMIMESubtypeSize = strlen(fMIMESubtype);

  if (applicationName == NULL) applicationName = "";
  fApplicationName = strDup(applicationName);
  fApplicationNameSize = strlen(fApplicationName);

  struct in_addr ourAddress;
  ourAddress.s_addr = ourIPAddress(env); // hack
  fOurAddressStr = strDup(AddressString(ourAddress).val());
  fOurAddressStrSize = strlen(fOurAddressStr);

  fOurSocket = new Groupsock(env, ourAddress, 0, 255);
  if (fOurSocket == NULL) {
    env << "ERROR: Failed to create socket for addr "
	<< fOurAddressStr << ": "
	<< env.getResultMsg() << "\n";
  }

  // Now, find out our source port number.  Hack: Do this by first trying to
  // send a 0-length packet, so that the "getSourcePort()" call will work.
  fOurSocket->output(envir(), (unsigned char*)"", 0);
  Port srcPort(0);
  getSourcePort(env, fOurSocket->socketNum(), srcPort);
  if (srcPort.num() != 0) {
    fOurPortNum = ntohs(srcPort.num());
  } else {
    // No luck.  Try again using a default port number:
    fOurPortNum = 5060;
    delete fOurSocket;
    fOurSocket = new Groupsock(env, ourAddress, fOurPortNum, 255);
    if (fOurSocket == NULL) {
      env << "ERROR: Failed to create socket for addr "
	  << fOurAddressStr << ", port "
	  << fOurPortNum << ": "
	  << env.getResultMsg() << "\n";
    }
  }

  // Set the "User-Agent:" header to use in each request:
  char const* const libName = "LIVE555 Streaming Media v";
  char const* const libVersionStr = LIVEMEDIA_LIBRARY_VERSION_STRING;
  char const* libPrefix; char const* libSuffix;
  if (applicationName == NULL || applicationName[0] == '\0') {
    applicationName = libPrefix = libSuffix = "";
  } else {
    libPrefix = " (";
    libSuffix = ")";
  }
  unsigned userAgentNameSize
    = fApplicationNameSize + strlen(libPrefix) + strlen(libName) + strlen(libVersionStr) + strlen(libSuffix) + 1;
  char* userAgentName = new char[userAgentNameSize];
  sprintf(userAgentName, "%s%s%s%s%s",
	  applicationName, libPrefix, libName, libVersionStr, libSuffix);
  setUserAgentString(userAgentName);
  delete[] userAgentName;

  reset();
}

SIPClient::~SIPClient() {
  reset();

  delete[] fUserAgentHeaderStr;
  delete fOurSocket;
  delete[] (char*)fOurAddressStr;
  delete[] (char*)fApplicationName;
  delete[] (char*)fMIMESubtype;
}

void SIPClient::reset() {
  fWorkingAuthenticator = NULL;
  delete[] fInviteCmd; fInviteCmd = NULL; fInviteCmdSize = 0;
  delete[] fInviteSDPDescription; fInviteSDPDescription = NULL;

  delete[] (char*)fUserName; fUserName = strDup(fApplicationName);
  fUserNameSize = strlen(fUserName);

  fValidAuthenticator.reset();

  delete[] (char*)fToTagStr; fToTagStr = NULL; fToTagStrSize = 0;
  fServerPortNum = 0;
  fServerAddress.s_addr = 0;
  delete[] (char*)fURL; fURL = NULL; fURLSize = 0;
}

void SIPClient::setProxyServer(unsigned proxyServerAddress,
			       portNumBits proxyServerPortNum) {
  fServerAddress.s_addr = proxyServerAddress;
  fServerPortNum = proxyServerPortNum;
  if (fOurSocket != NULL) {
    fOurSocket->changeDestinationParameters(fServerAddress,
					    fServerPortNum, 255);
  }
}

static char* getLine(char* startOfLine) {
  // returns the start of the next line, or NULL if none
  for (char* ptr = startOfLine; *ptr != '\0'; ++ptr) {
    if (*ptr == '\r' || *ptr == '\n') {
      // We found the end of the line
      *ptr++ = '\0';
      if (*ptr == '\n') ++ptr;
      return ptr;
    }
  }

  return NULL;
}

char* SIPClient::invite(char const* url, Authenticator* authenticator) {
  // First, check whether "url" contains a username:password to be used:
  char* username; char* password;
  if (authenticator == NULL
      && parseSIPURLUsernamePassword(url, username, password)) {
    char* result = inviteWithPassword(url, username, password);
    delete[] username; delete[] password; // they were dynamically allocated
    return result;
  }

  if (!processURL(url)) return NULL;

  delete[] (char*)fURL; fURL = strDup(url);
  fURLSize = strlen(fURL);

  fCallId = our_random32();
  fFromTag = our_random32();

  return invite1(authenticator);
}

char* SIPClient::invite1(Authenticator* authenticator) {
  do {
    // Send the INVITE command:

    // First, construct an authenticator string:
    fValidAuthenticator.reset();
    fWorkingAuthenticator = authenticator;
    char* authenticatorStr
      = createAuthenticatorString(fWorkingAuthenticator, "INVITE", fURL);

    // Then, construct the SDP description to be sent in the INVITE:
    char* rtpmapLine;
    unsigned rtpmapLineSize;
    if (fMIMESubtypeSize > 0) {
      char const* const rtpmapFmt =
	"a=rtpmap:%u %s/8000\r\n";
      unsigned rtpmapFmtSize = strlen(rtpmapFmt)
	+ 3 /* max char len */ + fMIMESubtypeSize;
      rtpmapLine = new char[rtpmapFmtSize];
      sprintf(rtpmapLine, rtpmapFmt,
	      fDesiredAudioRTPPayloadFormat, fMIMESubtype);
      rtpmapLineSize = strlen(rtpmapLine);
    } else {
      // Static payload type => no "a=rtpmap:" line
      rtpmapLine = strDup("");
      rtpmapLineSize = 0;
    }
    char const* const inviteSDPFmt =
      "v=0\r\n"
      "o=- %u %u IN IP4 %s\r\n"
      "s=%s session\r\n"
      "c=IN IP4 %s\r\n"
      "t=0 0\r\n"
      "m=audio %u RTP/AVP %u\r\n"
      "%s";
    unsigned inviteSDPFmtSize = strlen(inviteSDPFmt)
      + 20 /* max int len */ + 20 + fOurAddressStrSize
      + fApplicationNameSize
      + fOurAddressStrSize
      + 5 /* max short len */ + 3 /* max char len */
      + rtpmapLineSize;
    delete[] fInviteSDPDescription;
    fInviteSDPDescription = new char[inviteSDPFmtSize];
    sprintf(fInviteSDPDescription, inviteSDPFmt,
	    fCallId, fCSeq, fOurAddressStr,
	    fApplicationName,
	    fOurAddressStr,
	    fClientStartPortNum, fDesiredAudioRTPPayloadFormat,
	    rtpmapLine);
    unsigned inviteSDPSize = strlen(fInviteSDPDescription);
    delete[] rtpmapLine;

    char const* const cmdFmt =
      "INVITE %s SIP/2.0\r\n"
      "From: %s <sip:%s@%s>;tag=%u\r\n"
      "Via: SIP/2.0/UDP %s:%u\r\n"
      "Max-Forwards: 70\r\n"
      "To: %s\r\n"
      "Contact: sip:%s@%s:%u\r\n"
      "Call-ID: %u@%s\r\n"
      "CSeq: %d INVITE\r\n"
      "Content-Type: application/sdp\r\n"
      "%s" /* Proxy-Authorization: line (if any) */
      "%s" /* User-Agent: line */
      "Content-Length: %d\r\n\r\n"
      "%s";
    unsigned inviteCmdSize = strlen(cmdFmt)
      + fURLSize
      + 2*fUserNameSize + fOurAddressStrSize + 20 /* max int len */
      + fOurAddressStrSize + 5 /* max port len */
      + fURLSize
      + fUserNameSize + fOurAddressStrSize + 5
      + 20 + fOurAddressStrSize
      + 20
      + strlen(authenticatorStr)
      + fUserAgentHeaderStrLen
      + 20
      + inviteSDPSize;
    delete[] fInviteCmd; fInviteCmd = new char[inviteCmdSize];
    sprintf(fInviteCmd, cmdFmt,
	    fURL,
	    fUserName, fUserName, fOurAddressStr, fFromTag,
	    fOurAddressStr, fOurPortNum,
	    fURL,
	    fUserName, fOurAddressStr, fOurPortNum,
	    fCallId, fOurAddressStr,
	    ++fCSeq,
	    authenticatorStr,
	    fUserAgentHeaderStr,
	    inviteSDPSize,
	    fInviteSDPDescription);
    fInviteCmdSize = strlen(fInviteCmd);
    delete[] authenticatorStr;

    // Before sending the "INVITE", arrange to handle any response packets,
    // and set up timers:
    fInviteClientState = Calling;
    fEventLoopStopFlag = 0;
    TaskScheduler& sched = envir().taskScheduler(); // abbrev.
    sched.turnOnBackgroundReadHandling(fOurSocket->socketNum(),
				       &inviteResponseHandler, this);
    fTimerALen = 1*fT1; // initially
    fTimerACount = 0; // initially
    fTimerA = sched.scheduleDelayedTask(fTimerALen, timerAHandler, this);
    fTimerB = sched.scheduleDelayedTask(64*fT1, timerBHandler, this);
    fTimerD = NULL; // for now

    if (!sendINVITE()) break;

    // Enter the event loop, to handle response packets, and timeouts:
    envir().taskScheduler().doEventLoop(&fEventLoopStopFlag);

    // We're finished with this "INVITE".
    // Turn off response handling and timers:
    sched.turnOffBackgroundReadHandling(fOurSocket->socketNum());
    sched.unscheduleDelayedTask(fTimerA);
    sched.unscheduleDelayedTask(fTimerB);
    sched.unscheduleDelayedTask(fTimerD);

    // NOTE: We return the SDP description that we used in the "INVITE",
    // not the one that we got from the server.
    // ##### Later: match the codecs in the response (offer, answer) #####
    if (fInviteSDPDescription != NULL) {
      return strDup(fInviteSDPDescription);
    }
  } while (0);

  return NULL;
}

void SIPClient::inviteResponseHandler(void* clientData, int /*mask*/) {
  SIPClient* client = (SIPClient*)clientData;
  unsigned responseCode = client->getResponseCode();
  client->doInviteStateMachine(responseCode);
}

// Special 'response codes' that represent timers expiring:
unsigned const timerAFires = 0xAAAAAAAA;
unsigned const timerBFires = 0xBBBBBBBB;
unsigned const timerDFires = 0xDDDDDDDD;

void SIPClient::timerAHandler(void* clientData) {
  SIPClient* client = (SIPClient*)clientData;
  client->fTimerA = NULL;
  if (client->fVerbosityLevel >= 1) {
    client->envir() << "RETRANSMISSION " << ++client->fTimerACount
		    << ", after " << client->fTimerALen/1000000.0
		    << " additional seconds\n";
  }
  client->doInviteStateMachine(timerAFires);
}

void SIPClient::timerBHandler(void* clientData) {
  SIPClient* client = (SIPClient*)clientData;
  client->fTimerB = NULL;
  if (client->fVerbosityLevel >= 1) {
    client->envir() << "RETRANSMISSION TIMEOUT, after "
		    << 64*client->fT1/1000000.0 << " seconds\n";
    fflush(stderr);
  }
  client->doInviteStateMachine(timerBFires);
}

void SIPClient::timerDHandler(void* clientData) {
  SIPClient* client = (SIPClient*)clientData;
  client->fTimerD = NULL;
  if (client->fVerbosityLevel >= 1) {
    client->envir() << "TIMER D EXPIRED\n";
  }
  client->doInviteStateMachine(timerDFires);
}

void SIPClient::doInviteStateMachine(unsigned responseCode) {
  // Implement the state transition diagram (RFC 3261, Figure 5)
  TaskScheduler& sched = envir().taskScheduler(); // abbrev.
  switch (fInviteClientState) {
    case Calling: {
      if (responseCode == timerAFires) {
	// Restart timer A (with double the timeout interval):
	fTimerALen *= 2;
	fTimerA
	  = sched.scheduleDelayedTask(fTimerALen, timerAHandler, this);

	fInviteClientState = Calling;
	if (!sendINVITE()) doInviteStateTerminated(0);
      } else {
	// Turn off timers A & B before moving to a new state:
	sched.unscheduleDelayedTask(fTimerA);
	sched.unscheduleDelayedTask(fTimerB);

	if (responseCode == timerBFires) {
	  envir().setResultMsg("No response from server");
	  doInviteStateTerminated(0);
	} else if (responseCode >= 100 && responseCode <= 199) {
	  fInviteClientState = Proceeding;
	} else if (responseCode >= 200 && responseCode <= 299) {
	  doInviteStateTerminated(responseCode);
	} else if (responseCode >= 400 && responseCode <= 499) {
	  doInviteStateTerminated(responseCode);
	      // this isn't what the spec says, but it seems right...
	} else if (responseCode >= 300 && responseCode <= 699) {
	  fInviteClientState = Completed;
	  fTimerD
	    = sched.scheduleDelayedTask(32000000, timerDHandler, this);
	  if (!sendACK()) doInviteStateTerminated(0);
	}
      }
      break;
    }

    case Proceeding: {
      if (responseCode >= 100 && responseCode <= 199) {
	fInviteClientState = Proceeding;
      } else if (responseCode >= 200 && responseCode <= 299) {
	doInviteStateTerminated(responseCode);
      } else if (responseCode >= 400 && responseCode <= 499) {
	doInviteStateTerminated(responseCode);
	    // this isn't what the spec says, but it seems right...
      } else if (responseCode >= 300 && responseCode <= 699) {
	fInviteClientState = Completed;
	fTimerD = sched.scheduleDelayedTask(32000000, timerDHandler, this);
	if (!sendACK()) doInviteStateTerminated(0);
      }
      break;
    }

    case Completed: {
      if (responseCode == timerDFires) {
	envir().setResultMsg("Transaction terminated");
	doInviteStateTerminated(0);
      } else if (responseCode >= 300 && responseCode <= 699) {
	fInviteClientState = Completed;
	if (!sendACK()) doInviteStateTerminated(0);
      }
      break;
    }

    case Terminated: {
	doInviteStateTerminated(responseCode);
	break;
    }
  }
}

void SIPClient::doInviteStateTerminated(unsigned responseCode) {
  fInviteClientState = Terminated; // FWIW...
  if (responseCode < 200 || responseCode > 299) {
    // We failed, so return NULL;
    delete[] fInviteSDPDescription; fInviteSDPDescription = NULL;
    delete[] fInviteSDPDescriptionReturned; fInviteSDPDescriptionReturned = NULL;
  }

  // Unblock the event loop:
  fEventLoopStopFlag = ~0;
}

Boolean SIPClient::sendINVITE() {
  if (!sendRequest(fInviteCmd, fInviteCmdSize)) {
    envir().setResultErrMsg("INVITE send() failed: ");
    return False;
  }
  return True;
}

unsigned SIPClient::getResponseCode() {
  unsigned responseCode = 0;
  do {
    // Get the response from the server:
    unsigned const readBufSize = 10000;
    char readBuffer[readBufSize+1]; char* readBuf = readBuffer;

    char* firstLine = NULL;
    char* nextLineStart = NULL;
    unsigned bytesRead = getResponse(readBuf, readBufSize);
    if (bytesRead == 0) break;
    if (fVerbosityLevel >= 1) {
      envir() << "Received INVITE response: " << readBuf << "\n";
    }

    // Inspect the first line to get the response code:
    firstLine = readBuf;
    nextLineStart = getLine(firstLine);
    if (!parseResponseCode(firstLine, responseCode)) break;

    if (responseCode != 200) {
      if (responseCode >= 400 && responseCode <= 499
	  && fWorkingAuthenticator != NULL) {
	// We have an authentication failure, so fill in
	// "*fWorkingAuthenticator" using the contents of a following
	// "Proxy-Authenticate:" or "WWW-Authenticate:" line.  (Once we compute a 'response' for
	// "fWorkingAuthenticator", it can be used in a subsequent request
	// - that will hopefully succeed.)
	char* lineStart;
	while (1) {
	  lineStart = nextLineStart;
	  if (lineStart == NULL) break;

	  nextLineStart = getLine(lineStart);
	  if (lineStart[0] == '\0') break; // this is a blank line

	  char* realm = strDupSize(lineStart);
	  char* nonce = strDupSize(lineStart);
	  // ##### Check for the format of "Proxy-Authenticate:" lines from
	  // ##### known server types.
	  // ##### This is a crock! We should make the parsing more general
          Boolean foundAuthenticateHeader = False;
	  if (
	      // Asterisk #####
	      sscanf(lineStart, "Proxy-Authenticate: Digest realm=\"%[^\"]\", nonce=\"%[^\"]\"",
		     realm, nonce) == 2 ||
	      sscanf(lineStart, "WWW-Authenticate: Digest realm=\"%[^\"]\", nonce=\"%[^\"]\"",
		     realm, nonce) == 2 ||
	      // Cisco ATA #####
	      sscanf(lineStart, "Proxy-Authenticate: Digest algorithm=MD5,domain=\"%*[^\"]\",nonce=\"%[^\"]\", realm=\"%[^\"]\"",
		     nonce, realm) == 2) {
            fWorkingAuthenticator->setRealmAndNonce(realm, nonce);
            foundAuthenticateHeader = True;
          }
          delete[] realm; delete[] nonce;
          if (foundAuthenticateHeader) break;
	}
      }
      envir().setResultMsg("cannot handle INVITE response: ", firstLine);
      break;
    }

    // Skip every subsequent header line, until we see a blank line.
    // While doing so, check for "To:" and "Content-Length:" lines.
    // The remaining data is assumed to be the SDP descriptor that we want.
    // We should really do some more checking on the headers here - e.g., to
    // check for "Content-type: application/sdp", "CSeq", etc. #####
    int contentLength = -1;
    char* lineStart;
    while (1) {
      lineStart = nextLineStart;
      if (lineStart == NULL) break;

      nextLineStart = getLine(lineStart);
      if (lineStart[0] == '\0') break; // this is a blank line

      char* toTagStr = strDupSize(lineStart);
      if (sscanf(lineStart, "To:%*[^;]; tag=%s", toTagStr) == 1) {
	delete[] (char*)fToTagStr; fToTagStr = strDup(toTagStr);
	fToTagStrSize = strlen(fToTagStr);
      }
      delete[] toTagStr;

      if (sscanf(lineStart, "Content-Length: %d", &contentLength) == 1
          || sscanf(lineStart, "Content-length: %d", &contentLength) == 1) {
        if (contentLength < 0) {
          envir().setResultMsg("Bad \"Content-Length:\" header: \"",
                               lineStart, "\"");
          break;
        }
      }
    }

    // We're now at the end of the response header lines
    if (lineStart == NULL) {
      envir().setResultMsg("no content following header lines: ", readBuf);
      break;
    }

    // Use the remaining data as the SDP descr, but first, check
    // the "Content-Length:" header (if any) that we saw.  We may need to
    // read more data, or we may have extraneous data in the buffer.
    char* bodyStart = nextLineStart;
    if (bodyStart != NULL && contentLength >= 0) {
      // We saw a "Content-Length:" header
      unsigned numBodyBytes = &readBuf[bytesRead] - bodyStart;
      if (contentLength > (int)numBodyBytes) {
        // We need to read more data.  First, make sure we have enough
        // space for it:
        unsigned numExtraBytesNeeded = contentLength - numBodyBytes;
#ifdef USING_TCP
	// THIS CODE WORKS ONLY FOR TCP: #####
        unsigned remainingBufferSize
          = readBufSize - (bytesRead + (readBuf - readBuffer));
        if (numExtraBytesNeeded > remainingBufferSize) {
          char tmpBuf[200];
          sprintf(tmpBuf, "Read buffer size (%d) is too small for \"Content-Length:\" %d (need a buffer size of >= %d bytes\n",
                  readBufSize, contentLength,
                  readBufSize + numExtraBytesNeeded - remainingBufferSize);
          envir().setResultMsg(tmpBuf);
          break;
        }

        // Keep reading more data until we have enough:
        if (fVerbosityLevel >= 1) {
          envir() << "Need to read " << numExtraBytesNeeded
		  << " extra bytes\n";
        }
        while (numExtraBytesNeeded > 0) {
          char* ptr = &readBuf[bytesRead];
	  unsigned bytesRead2;
	  struct sockaddr_in fromAddr;
	  Boolean readSuccess
	    = fOurSocket->handleRead((unsigned char*)ptr,
				     numExtraBytesNeeded,
				     bytesRead2, fromAddr);
          if (!readSuccess) break;
          ptr[bytesRead2] = '\0';
          if (fVerbosityLevel >= 1) {
            envir() << "Read " << bytesRead2
		    << " extra bytes: " << ptr << "\n";
          }

          bytesRead += bytesRead2;
          numExtraBytesNeeded -= bytesRead2;
        }
#endif
        if (numExtraBytesNeeded > 0) break; // one of the reads failed
      }

      bodyStart[contentLength] = '\0'; // trims any extra data
      delete[] fInviteSDPDescriptionReturned; fInviteSDPDescriptionReturned = strDup(bodyStart);
    }
  } while (0);

  return responseCode;
}

char* SIPClient::inviteWithPassword(char const* url, char const* username,
				    char const* password) {
  delete[] (char*)fUserName; fUserName = strDup(username);
  fUserNameSize = strlen(fUserName);

  Authenticator authenticator(username, password);
  char* inviteResult = invite(url, &authenticator);
  if (inviteResult != NULL) {
    // We are already authorized
    return inviteResult;
  }

  // The "realm" and "nonce" fields should have been filled in:
  if (authenticator.realm() == NULL || authenticator.nonce() == NULL) {
    // We haven't been given enough information to try again, so fail:
    return NULL;
  }

  // Try again (but with the same CallId):
  inviteResult = invite1(&authenticator);
  if (inviteResult != NULL) {
    // The authenticator worked, so use it in future requests:
    fValidAuthenticator = authenticator;
  }

  return inviteResult;
}

Boolean SIPClient::sendACK() {
  char* cmd = NULL;
  do {
    char const* const cmdFmt =
      "ACK %s SIP/2.0\r\n"
      "From: %s <sip:%s@%s>;tag=%u\r\n"
      "Via: SIP/2.0/UDP %s:%u\r\n"
      "Max-Forwards: 70\r\n"
      "To: %s;tag=%s\r\n"
      "Call-ID: %u@%s\r\n"
      "CSeq: %d ACK\r\n"
      "Content-Length: 0\r\n\r\n";
    unsigned cmdSize = strlen(cmdFmt)
      + fURLSize
      + 2*fUserNameSize + fOurAddressStrSize + 20 /* max int len */
      + fOurAddressStrSize + 5 /* max port len */
      + fURLSize + fToTagStrSize
      + 20 + fOurAddressStrSize
      + 20;
    cmd = new char[cmdSize];
    sprintf(cmd, cmdFmt,
	    fURL,
	    fUserName, fUserName, fOurAddressStr, fFromTag,
	    fOurAddressStr, fOurPortNum,
	    fURL, fToTagStr,
	    fCallId, fOurAddressStr,
	    fCSeq /* note: it's the same as before; not incremented */);

    if (!sendRequest(cmd, strlen(cmd))) {
      envir().setResultErrMsg("ACK send() failed: ");
      break;
    }

    delete[] cmd;
    return True;
  } while (0);

  delete[] cmd;
  return False;
}

Boolean SIPClient::sendBYE() {
  // NOTE: This should really be retransmitted, for reliability #####
  char* cmd = NULL;
  do {
    char const* const cmdFmt =
      "BYE %s SIP/2.0\r\n"
      "From: %s <sip:%s@%s>;tag=%u\r\n"
      "Via: SIP/2.0/UDP %s:%u\r\n"
      "Max-Forwards: 70\r\n"
      "To: %s;tag=%s\r\n"
      "Call-ID: %u@%s\r\n"
      "CSeq: %d BYE\r\n"
      "Content-Length: 0\r\n\r\n";
    unsigned cmdSize = strlen(cmdFmt)
      + fURLSize
      + 2*fUserNameSize + fOurAddressStrSize + 20 /* max int len */
      + fOurAddressStrSize + 5 /* max port len */
      + fURLSize + fToTagStrSize
      + 20 + fOurAddressStrSize
      + 20;
    cmd = new char[cmdSize];
    sprintf(cmd, cmdFmt,
	    fURL,
	    fUserName, fUserName, fOurAddressStr, fFromTag,
	    fOurAddressStr, fOurPortNum,
	    fURL, fToTagStr,
	    fCallId, fOurAddressStr,
	    ++fCSeq);

    if (!sendRequest(cmd, strlen(cmd))) {
      envir().setResultErrMsg("BYE send() failed: ");
      break;
    }

    delete[] cmd;
    return True;
  } while (0);

  delete[] cmd;
  return False;
}

Boolean SIPClient::processURL(char const* url) {
  do {
    // If we don't already have a server address/port, then
    // get these by parsing the URL:
    if (fServerAddress.s_addr == 0) {
      NetAddress destAddress;
      if (!parseSIPURL(envir(), url, destAddress, fServerPortNum)) break;
      fServerAddress.s_addr = *(unsigned*)(destAddress.data());

      if (fOurSocket != NULL) {
	fOurSocket->changeDestinationParameters(fServerAddress,
						fServerPortNum, 255);
      }
    }

    return True;
  } while (0);

  return False;
}

Boolean SIPClient::parseSIPURL(UsageEnvironment& env, char const* url,
			       NetAddress& address,
			       portNumBits& portNum) {
  do {
    // Parse the URL as "sip:<username>@<address>:<port>/<etc>"
    // (with ":<port>" and "/<etc>" optional)
    // Also, skip over any "<username>[:<password>]@" preceding <address>
    char const* prefix = "sip:";
    unsigned const prefixLength = 4;
    if (_strncasecmp(url, prefix, prefixLength) != 0) {
      env.setResultMsg("URL is not of the form \"", prefix, "\"");
      break;
    }

    unsigned const parseBufferSize = 100;
    char parseBuffer[parseBufferSize];
    unsigned addressStartIndex = prefixLength;
    while (url[addressStartIndex] != '\0'
	   && url[addressStartIndex++] != '@') {}
    char const* from = &url[addressStartIndex];

    // Skip over any "<username>[:<password>]@"
    char const* from1 = from;
    while (*from1 != '\0' && *from1 != '/') {
      if (*from1 == '@') {
	from = ++from1;
	break;
      }
      ++from1;
    }

    char* to = &parseBuffer[0];
    unsigned i;
    for (i = 0; i < parseBufferSize; ++i) {
      if (*from == '\0' || *from == ':' || *from == '/') {
	// We've completed parsing the address
	*to = '\0';
	break;
      }
      *to++ = *from++;
    }
    if (i == parseBufferSize) {
      env.setResultMsg("URL is too long");
      break;
    }

    NetAddressList addresses(parseBuffer);
    if (addresses.numAddresses() == 0) {
      env.setResultMsg("Failed to find network address for \"",
			   parseBuffer, "\"");
      break;
    }
    address = *(addresses.firstAddress());

    portNum = 5060; // default value
    char nextChar = *from;
    if (nextChar == ':') {
      int portNumInt;
      if (sscanf(++from, "%d", &portNumInt) != 1) {
	env.setResultMsg("No port number follows ':'");
	break;
      }
      if (portNumInt < 1 || portNumInt > 65535) {
	env.setResultMsg("Bad port number");
	break;
      }
      portNum = (portNumBits)portNumInt;
    }

    return True;
  } while (0);

  return False;
}

Boolean SIPClient::parseSIPURLUsernamePassword(char const* url,
					       char*& username,
					       char*& password) {
  username = password = NULL; // by default
  do {
    // Parse the URL as "sip:<username>[:<password>]@<whatever>"
    char const* prefix = "sip:";
    unsigned const prefixLength = 4;
    if (_strncasecmp(url, prefix, prefixLength) != 0) break;

    // Look for the ':' and '@':
    unsigned usernameIndex = prefixLength;
    unsigned colonIndex = 0, atIndex = 0;
    for (unsigned i = usernameIndex; url[i] != '\0' && url[i] != '/'; ++i) {
      if (url[i] == ':' && colonIndex == 0) {
	colonIndex = i;
      } else if (url[i] == '@') {
        atIndex = i;
        break; // we're done
      }
    }
    if (atIndex == 0) break; // no '@' found

    char* urlCopy = strDup(url);
    urlCopy[atIndex] = '\0';
    if (colonIndex > 0) {
      urlCopy[colonIndex] = '\0';
      password = strDup(&urlCopy[colonIndex+1]);
    } else {
      password = strDup("");
    }
    username = strDup(&urlCopy[usernameIndex]);
    delete[] urlCopy;

    return True;
  } while (0);

  return False;
}

char*
SIPClient::createAuthenticatorString(Authenticator const* authenticator,
				      char const* cmd, char const* url) {
  if (authenticator != NULL && authenticator->realm() != NULL
      && authenticator->nonce() != NULL && authenticator->username() != NULL
      && authenticator->password() != NULL) {
    // We've been provided a filled-in authenticator, so use it:
    char const* const authFmt
      = "Authorization: Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", response=\"%s\", uri=\"%s\"\r\n";
    char const* response = authenticator->computeDigestResponse(cmd, url);
    unsigned authBufSize = strlen(authFmt)
      + strlen(authenticator->username()) + strlen(authenticator->realm())
      + strlen(authenticator->nonce()) + strlen(url) + strlen(response);
    char* authenticatorStr = new char[authBufSize];
    sprintf(authenticatorStr, authFmt,
	    authenticator->username(), authenticator->realm(),
	    authenticator->nonce(), response, url);
    authenticator->reclaimDigestResponse(response);

    return authenticatorStr;
  }

  return strDup("");
}

Boolean SIPClient::sendRequest(char const* requestString,
			       unsigned requestLength) {
  if (fVerbosityLevel >= 1) {
    envir() << "Sending request: " << requestString << "\n";
  }
  // NOTE: We should really check that "requestLength" is not #####
  // too large for UDP (see RFC 3261, section 18.1.1) #####
  return fOurSocket->output(envir(), (unsigned char*)requestString, requestLength);
}

unsigned SIPClient::getResponse(char*& responseBuffer,
				unsigned responseBufferSize) {
  if (responseBufferSize == 0) return 0; // just in case...
  responseBuffer[0] = '\0'; // ditto

  // Keep reading data from the socket until we see "\r\n\r\n" (except
  // at the start), or until we fill up our buffer.
  // Don't read any more than this.
  char* p = responseBuffer;
  Boolean haveSeenNonCRLF = False;
  int bytesRead = 0;
  while (bytesRead < (int)responseBufferSize) {
    unsigned bytesReadNow;
    struct sockaddr_in fromAddr;
    unsigned char* toPosn = (unsigned char*)(responseBuffer+bytesRead);
    Boolean readSuccess
      = fOurSocket->handleRead(toPosn, responseBufferSize-bytesRead,
			       bytesReadNow, fromAddr);
    if (!readSuccess || bytesReadNow == 0) {
      envir().setResultMsg("SIP response was truncated");
      break;
    }
    bytesRead += bytesReadNow;

    // Check whether we have "\r\n\r\n":
    char* lastToCheck = responseBuffer+bytesRead-4;
    if (lastToCheck < responseBuffer) continue;
    for (; p <= lastToCheck; ++p) {
      if (haveSeenNonCRLF) {
        if (*p == '\r' && *(p+1) == '\n' &&
            *(p+2) == '\r' && *(p+3) == '\n') {
          responseBuffer[bytesRead] = '\0';

          // Before returning, trim any \r or \n from the start:
          while (*responseBuffer == '\r' || *responseBuffer == '\n') {
            ++responseBuffer;
            --bytesRead;
          }
          return bytesRead;
        }
      } else {
        if (*p != '\r' && *p != '\n') {
          haveSeenNonCRLF = True;
        }
      }
    }
  }

  return 0;
}

Boolean SIPClient::parseResponseCode(char const* line,
				      unsigned& responseCode) {
  if (sscanf(line, "%*s%u", &responseCode) != 1) {
    envir().setResultMsg("no response code in line: \"", line, "\"");
    return False;
  }

  return True;
}
