diff options
author | Youness Alaoui <youness.alaoui@collabora.co.uk> | 2009-11-04 13:00:36 -0500 |
---|---|---|
committer | Youness Alaoui <youness.alaoui@collabora.co.uk> | 2009-11-04 13:00:36 -0500 |
commit | 8eab0facb3285ad43b3dc411e583d35a287a06eb (patch) | |
tree | 0de4ab47185281a04532e53fead9996d62bf47e3 | |
parent | 9c56802a8b144e39bd875cc3419fe1f20758dc16 (diff) | |
download | libnice-8eab0facb3285ad43b3dc411e583d35a287a06eb.tar.gz |
Add a stun_agent_set_software API and correctly append only the first 128 utf-8 characters
-rw-r--r-- | stun/stun5389.c | 34 | ||||
-rw-r--r-- | stun/stun5389.h | 3 | ||||
-rw-r--r-- | stun/stunagent.c | 26 | ||||
-rw-r--r-- | stun/stunagent.h | 31 |
4 files changed, 82 insertions, 12 deletions
diff --git a/stun/stun5389.c b/stun/stun5389.c index fa100fd..32f1c1b 100644 --- a/stun/stun5389.c +++ b/stun/stun5389.c @@ -53,6 +53,21 @@ #include "stuncrc32.h" #include "stunmessage.h" + +static const char utf8_skip_data[256] = { + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1 +}; + +#define next_utf8_char(p) (char *)((p) + \ + utf8_skip_data[*(const unsigned char *)(p)]) + uint32_t stun_fingerprint (const uint8_t *msg, size_t len, bool wlm2009_stupid_crc32_typo) { @@ -81,10 +96,21 @@ bool stun_message_has_cookie (const StunMessage *msg) } -StunMessageReturn stun_message_append_software (StunMessage *msg) +StunMessageReturn stun_message_append_software (StunMessage *msg, + const char *software) { - static const char software[] = PACKAGE_STRING; - // assert (strlen (software) < 128); + int len = 0; + const char *ptr = NULL; + + if (software == NULL) + software = PACKAGE_STRING; + + ptr = software; + while (*ptr && len < 128) { + ptr = next_utf8_char (ptr); + len++; + } - return stun_message_append_string (msg, STUN_ATTRIBUTE_SOFTWARE, software); + return stun_message_append_bytes (msg, STUN_ATTRIBUTE_SOFTWARE, software, + ptr - software); } diff --git a/stun/stun5389.h b/stun/stun5389.h index 3387304..5f3a65e 100644 --- a/stun/stun5389.h +++ b/stun/stun5389.h @@ -60,7 +60,8 @@ uint32_t stun_fingerprint (const uint8_t *msg, size_t len, bool wlm2009_stupid_crc32_typo); -StunMessageReturn stun_message_append_software (StunMessage *msg); +StunMessageReturn stun_message_append_software (StunMessage *msg, + const char *software); #endif /* _STUN_5389_H */ diff --git a/stun/stunagent.c b/stun/stunagent.c index fb8121c..68c81c3 100644 --- a/stun/stunagent.c +++ b/stun/stunagent.c @@ -59,6 +59,7 @@ void stun_agent_init (StunAgent *agent, const uint16_t *known_attributes, agent->known_attributes = (uint16_t *) known_attributes; agent->compatibility = compatibility; agent->usage_flags = usage_flags; + agent->software_attribute = NULL; for (i = 0; i < STUN_AGENT_MAX_SAVED_IDS; i++) { agent->sent_ids[i].valid = FALSE; @@ -358,6 +359,12 @@ bool stun_agent_init_request (StunAgent *agent, StunMessage *msg, uint32_t cookie = htonl (STUN_MAGIC_COOKIE); memcpy (msg->buffer + STUN_MESSAGE_TRANS_ID_POS, &cookie, sizeof (cookie)); } + if (agent->software_attribute != NULL || + ((agent->compatibility == STUN_COMPATIBILITY_RFC5389 || + agent->compatibility == STUN_COMPATIBILITY_WLM2009) && + agent->usage_flags & STUN_AGENT_USAGE_ADD_SOFTWARE)) { + stun_message_append_software (msg, agent->software_attribute); + } } return ret; @@ -416,10 +423,11 @@ bool stun_agent_init_response (StunAgent *agent, StunMessage *msg, if (stun_message_init (msg, STUN_RESPONSE, stun_message_get_method (request), id)) { - if ((agent->compatibility == STUN_COMPATIBILITY_RFC5389 || + if (agent->software_attribute != NULL || + ((agent->compatibility == STUN_COMPATIBILITY_RFC5389 || agent->compatibility == STUN_COMPATIBILITY_WLM2009) && - agent->usage_flags & STUN_AGENT_USAGE_ADD_SOFTWARE) { - stun_message_append_software (msg); + agent->usage_flags & STUN_AGENT_USAGE_ADD_SOFTWARE)) { + stun_message_append_software (msg, agent->software_attribute); } return TRUE; } @@ -452,10 +460,11 @@ bool stun_agent_init_error (StunAgent *agent, StunMessage *msg, if (stun_message_init (msg, STUN_ERROR, stun_message_get_method (request), id)) { - if ((agent->compatibility == STUN_COMPATIBILITY_RFC5389 || + if (agent->software_attribute != NULL || + ((agent->compatibility == STUN_COMPATIBILITY_RFC5389 || agent->compatibility == STUN_COMPATIBILITY_WLM2009) && - agent->usage_flags & STUN_AGENT_USAGE_ADD_SOFTWARE) { - stun_message_append_software (msg); + agent->usage_flags & STUN_AGENT_USAGE_ADD_SOFTWARE)) { + stun_message_append_software (msg, agent->software_attribute); } if (stun_message_append_error (msg, err) == STUN_MESSAGE_RETURN_SUCCESS) { return TRUE; @@ -674,3 +683,8 @@ stun_agent_find_unknowns (StunAgent *agent, const StunMessage * msg, stun_debug ("STUN unknown: %u mandatory attribute(s)!\n", count); return count; } + +void stun_agent_set_software (StunAgent *agent, char *software) +{ + agent->software_attribute = software; +} diff --git a/stun/stunagent.h b/stun/stunagent.h index 6aed2aa..f83837a 100644 --- a/stun/stunagent.h +++ b/stun/stunagent.h @@ -138,7 +138,10 @@ typedef enum { * @STUN_AGENT_USAGE_USE_FINGERPRINT: The agent should add the FINGERPRINT * attribute to the STUN messages it creates. * @STUN_AGENT_USAGE_ADD_SOFTWARE: The agent should add the SOFTWARE attribute - * to the STUN messages it creates + * to the STUN messages it creates. Calling nice_agent_set_software() will have + * the same effect as enabling this Usage. STUN Indications do not have the + * SOFTWARE attributes added to them though. The SOFTWARE attribute is only + * added for the RFC5389 and WLM2009 compatibility modes. * @STUN_AGENT_USAGE_IGNORE_CREDENTIALS: The agent should ignore any credentials * in the STUN messages it receives (the MESSAGE-INTEGRITY attribute * will never be validated by stun_agent_validate()) @@ -184,6 +187,7 @@ struct stun_agent_t { StunAgentSavedIds sent_ids[STUN_AGENT_MAX_SAVED_IDS]; uint16_t *known_attributes; StunAgentUsageFlags usage_flags; + char *software_attribute; }; /** @@ -470,4 +474,29 @@ size_t stun_agent_finish_message (StunAgent *agent, StunMessage *msg, bool stun_agent_forget_transaction (StunAgent *agent, StunTransactionId id); +/** + * stun_agent_set_software: + * @agent: The #StunAgent + * @software: The value of the SOFTWARE attribute to add. + * + * This function will set the value of the SOFTWARE attribute to be added to + * STUN requests, responses and error responses. + * <para> + * Calling this function will automatically enable the addition of the SOFTWARE + * attribute for RFC5389 and WLM2009 compatibility modes. + * </para> + * <note> + <para> + The @software argument must be in UTF-8 encoding and only the first + 128 characters will be sent. + </para> + <para> + The value of the @software argument must stay valid throughout the life of + the StunAgent's life. Do not free its content. + </para> + </note> + * + */ +void stun_agent_set_software (StunAgent *agent, char *software); + #endif /* _STUN_AGENT_H */ |