Esempio n. 1
0
/** Parse SIP version.
 *
 * Parse a SIP version string. Update the
 * pointer at @a ss to first non-LWS character after the version string.
 *
 * @param ss   string to be parsed [IN/OUT]
 * @param ver  value result for version [OUT]
 *
 * @retval 0 when successful,
 * @retval -1 upon an error.
 */
int sip_version_d(char **ss, char const **ver)
{
  char *s = *ss;
  char const *result;
  size_t const version_size = sizeof(sip_version_2_0) - 1;

  if (su_casenmatch(s, sip_version_2_0, version_size) &&
      !IS_TOKEN(s[version_size])) {
    result = sip_version_2_0;
    s += version_size;
  }
  else {
    /* Version consists of two tokens, separated by / */
    size_t l1 = 0, l2 = 0, n;

    result = s;

    l1 = span_token(s);
    for (n = l1; IS_LWS(s[n]); n++)
      {}
    if (s[n] == '/') {
      for (n++; IS_LWS(s[n]); n++)
        {}
      l2 = span_token(s + n);
      n += l2;
    }

    if (l1 == 0 || l2 == 0)
      return -1;

    /* If there is extra ws between tokens, compact version */
    if (n > l1 + 1 + l2) {
      s[l1] = '/';
      memmove(s + l1 + 1, s + n - l2, l2);
      s[l1 + 1 + l2] = 0;

      /* Compare again with compacted version */
      if (su_casematch(s, sip_version_2_0))
	result = sip_version_2_0;
    }

    s += n;
  }

  while (IS_WS(*s)) *s++ = '\0';

  *ss = s;

  if (ver)
    *ver = result;

  return 0;
}
Esempio n. 2
0
static
size_t span_attribute_value(char *s)
{
  size_t n;

  n = span_token_lws(s);
  if (n > 0 && s[n] == '=') {
    n += 1 + span_lws(s + n + 1);
    if (s[n] == '"')
      n += span_quoted(s + n);
    else
      n += span_token(s + n);
    n += span_lws(s + n);
  }

  return n;
}
Esempio n. 3
0
/** Set various outbound and nat-traversal related options. */
int outbound_set_options(outbound_t *ob,
			 char const *_options,
			 unsigned interval,
			 unsigned stream_interval)
{
  struct outbound_prefs prefs[1] = {{ 0 }};
  char *s, *options = su_strdup(NULL, _options);
  int invalid;

  prefs->interval = interval;
  prefs->stream_interval = stream_interval;

#define MATCH(v) (len == sizeof(#v) - 1 && su_casenmatch(#v, s, len))

  if (options) {
    for (s = options; s[0]; s++) if (s[0] == '-') s[0] = '_';
  }

  prefs->gruuize = 1;
  prefs->outbound = 0;
  prefs->natify = 1;
  prefs->okeepalive = -1;
  prefs->validate = 1;
  prefs->use_rport = 1;

  for (s = options; s && s[0]; ) {
    size_t len = span_token(s);
    int value = 1;

    if (len > 3 && su_casenmatch(s, "no_", 3))
      value = 0, s += 3, len -= 3;
    else if (len > 4 && su_casenmatch(s, "not_", 4))
      value = 0, s += 4, len -= 4;

    if (len == 0)
      break;
    else if (MATCH(gruuize)) prefs->gruuize = value;
    else if (MATCH(outbound)) prefs->outbound = value;
    else if (MATCH(natify)) prefs->natify = value;
    else if (MATCH(validate)) prefs->validate = value;
    else if (MATCH(options_keepalive)) prefs->okeepalive = value;
    else if (MATCH(use_connect)) prefs->use_connect = value;
    else if (MATCH(use_rport)) prefs->use_rport = value;
    else if (MATCH(use_socks)) prefs->use_socks = value;
    else if (MATCH(use_upnp)) prefs->use_upnp = value;
    else if (MATCH(use_stun)) prefs->use_stun = value;
    else
      SU_DEBUG_1(("outbound(%p): unknown option \"%.*s\"\n",
		  (void *)ob->ob_owner, (int)len, s));

    s += len;
    len = strspn(s, " \t\n\r,;");
    if (len == 0)
      break;
    s += len;
  }

  invalid = s && s[0];
  if (invalid)
    SU_DEBUG_1(("outbound(%p): invalid options \"%s\"\n",
		(void *)ob->ob_owner, options));
  su_free(NULL, options);
  if (invalid)
    return -1;

  if (prefs->natify &&
      !(prefs->outbound ||
	prefs->use_connect ||
	prefs->use_rport ||
	prefs->use_socks ||
	prefs->use_upnp ||
	prefs->use_stun)) {
    SU_DEBUG_1(("outbound(%p): no nat traversal method given\n",
		(void *)ob->ob_owner));
  }

  ob->ob_prefs = *prefs;
  ob->ob_reg_id = prefs->outbound ? 1 : 0;

  return 0;
}