Sfoglia il codice sorgente

rtpengine: allow usage of arbitrary/unknown flags within the protocol

Richard Fuchs 11 anni fa
parent
commit
81a1ebc76d
2 ha cambiato i file con 149 aggiunte e 161 eliminazioni
  1. 91 60
      modules/rtpengine/bencode.h
  2. 58 101
      modules/rtpengine/rtpengine.c

+ 91 - 60
modules/rtpengine/bencode.h

@@ -12,8 +12,10 @@
 # define BENCODE_MALLOC pkg_malloc
 # define BENCODE_MALLOC pkg_malloc
 # define BENCODE_FREE pkg_free
 # define BENCODE_FREE pkg_free
 # endif
 # endif
+# define INLINE static inline
 #else
 #else
-/* mediaproxy-ng */
+/* rtpengine */
+# include "compat.h"
 # include "str.h"
 # include "str.h"
 # ifndef BENCODE_MALLOC
 # ifndef BENCODE_MALLOC
 # define BENCODE_MALLOC malloc
 # define BENCODE_MALLOC malloc
@@ -63,6 +65,13 @@ struct bencode_buffer {
 
 
 
 
 
 
+/* to embed BENCODE_STRING objects into printf-like functions */
+#define BENCODE_FORMAT "%.*s"
+#define BENCODE_FMT(b) (int) (b)->iov[1].iov_len, (char *) (b)->iov[1].iov_base
+
+
+
+
 /*** INIT & DESTROY ***/
 /*** INIT & DESTROY ***/
 
 
 /* Initializes a bencode_buffer_t object. This object is used to group together all memory allocations
 /* Initializes a bencode_buffer_t object. This object is used to group together all memory allocations
@@ -72,6 +81,9 @@ struct bencode_buffer {
  * Returns 0 on success or -1 on failure (if no memory could be allocated). */
  * Returns 0 on success or -1 on failure (if no memory could be allocated). */
 int bencode_buffer_init(bencode_buffer_t *buf);
 int bencode_buffer_init(bencode_buffer_t *buf);
 
 
+/* Allocate a piece of memory from the given buffer object */
+void *bencode_buffer_alloc(bencode_buffer_t *, unsigned int);
+
 /* Destroys a previously initialized bencode_buffer_t object. All memory used by the object is freed
 /* Destroys a previously initialized bencode_buffer_t object. All memory used by the object is freed
  * and all objects created through it become invalid. */
  * and all objects created through it become invalid. */
 void bencode_buffer_free(bencode_buffer_t *buf);
 void bencode_buffer_free(bencode_buffer_t *buf);
@@ -89,7 +101,7 @@ bencode_item_t *bencode_list(bencode_buffer_t *buf);
 void bencode_buffer_destroy_add(bencode_buffer_t *buf, free_func_t, void *);
 void bencode_buffer_destroy_add(bencode_buffer_t *buf, free_func_t, void *);
 
 
 /* Returns the buffer associated with an item, or NULL if pointer given is NULL */
 /* Returns the buffer associated with an item, or NULL if pointer given is NULL */
-static inline bencode_buffer_t *bencode_item_buffer(bencode_item_t *);
+INLINE bencode_buffer_t *bencode_item_buffer(bencode_item_t *);
 
 
 
 
 
 
@@ -104,29 +116,31 @@ static inline bencode_buffer_t *bencode_item_buffer(bencode_item_t *);
  * Also, the function does not reorder keys into lexicographical order; keys will be encoded in
  * Also, the function does not reorder keys into lexicographical order; keys will be encoded in
  * the same order as they've been added. The key must a null-terminated string.
  * the same order as they've been added. The key must a null-terminated string.
  * The value to be added must not have been previously linked into any other dictionary or list. */
  * The value to be added must not have been previously linked into any other dictionary or list. */
-static inline bencode_item_t *bencode_dictionary_add(bencode_item_t *dict, const char *key, bencode_item_t *val);
+INLINE bencode_item_t *bencode_dictionary_add(bencode_item_t *dict, const char *key, bencode_item_t *val);
+INLINE bencode_item_t *bencode_dictionary_str_add(bencode_item_t *dict, const str *key, bencode_item_t *val);
 
 
 /* Identical to bencode_dictionary_add() but doesn't require the key string to be null-terminated */
 /* Identical to bencode_dictionary_add() but doesn't require the key string to be null-terminated */
 bencode_item_t *bencode_dictionary_add_len(bencode_item_t *dict, const char *key, int keylen, bencode_item_t *val);
 bencode_item_t *bencode_dictionary_add_len(bencode_item_t *dict, const char *key, int keylen, bencode_item_t *val);
 
 
 /* Convenience function to add a string value to a dictionary, possibly duplicated into the
 /* Convenience function to add a string value to a dictionary, possibly duplicated into the
  * bencode_buffer_t object. */
  * bencode_buffer_t object. */
-static inline bencode_item_t *bencode_dictionary_add_string(bencode_item_t *dict, const char *key, const char *val);
-static inline bencode_item_t *bencode_dictionary_add_string_dup(bencode_item_t *dict, const char *key, const char *val);
+INLINE bencode_item_t *bencode_dictionary_add_string(bencode_item_t *dict, const char *key, const char *val);
+INLINE bencode_item_t *bencode_dictionary_add_string_dup(bencode_item_t *dict, const char *key, const char *val);
 
 
 /* Ditto, but for a "str" object */
 /* Ditto, but for a "str" object */
-static inline bencode_item_t *bencode_dictionary_add_str(bencode_item_t *dict, const char *key, const str *val);
-static inline bencode_item_t *bencode_dictionary_add_str_dup(bencode_item_t *dict, const char *key, const str *val);
+INLINE bencode_item_t *bencode_dictionary_add_str(bencode_item_t *dict, const char *key, const str *val);
+INLINE bencode_item_t *bencode_dictionary_str_add_str(bencode_item_t *dict, const str *key, const str *val);
+INLINE bencode_item_t *bencode_dictionary_add_str_dup(bencode_item_t *dict, const char *key, const str *val);
 
 
 /* Ditto, but adds a string created through an iovec array to the dictionary. See
 /* Ditto, but adds a string created through an iovec array to the dictionary. See
  * bencode_string_iovec(). */
  * bencode_string_iovec(). */
-static inline bencode_item_t *bencode_dictionary_add_iovec(bencode_item_t *dict, const char *key,
+INLINE bencode_item_t *bencode_dictionary_add_iovec(bencode_item_t *dict, const char *key,
 	const struct iovec *iov, int iov_cnt, int str_len);
 	const struct iovec *iov, int iov_cnt, int str_len);
 
 
 /* Convenience functions to add the respective (newly created) objects to a dictionary */
 /* Convenience functions to add the respective (newly created) objects to a dictionary */
-static inline bencode_item_t *bencode_dictionary_add_integer(bencode_item_t *dict, const char *key, long long int val);
-static inline bencode_item_t *bencode_dictionary_add_dictionary(bencode_item_t *dict, const char *key);
-static inline bencode_item_t *bencode_dictionary_add_list(bencode_item_t *dict, const char *key);
+INLINE bencode_item_t *bencode_dictionary_add_integer(bencode_item_t *dict, const char *key, long long int val);
+INLINE bencode_item_t *bencode_dictionary_add_dictionary(bencode_item_t *dict, const char *key);
+INLINE bencode_item_t *bencode_dictionary_add_list(bencode_item_t *dict, const char *key);
 
 
 
 
 
 
@@ -139,9 +153,10 @@ static inline bencode_item_t *bencode_dictionary_add_list(bencode_item_t *dict,
 bencode_item_t *bencode_list_add(bencode_item_t *list, bencode_item_t *item);
 bencode_item_t *bencode_list_add(bencode_item_t *list, bencode_item_t *item);
 
 
 /* Convenience function to add the respective (newly created) objects to a list */
 /* Convenience function to add the respective (newly created) objects to a list */
-static inline bencode_item_t *bencode_list_add_string(bencode_item_t *list, const char *s);
-static inline bencode_item_t *bencode_list_add_list(bencode_item_t *list);
-static inline bencode_item_t *bencode_list_add_dictionary(bencode_item_t *list);
+INLINE bencode_item_t *bencode_list_add_string(bencode_item_t *list, const char *s);
+INLINE bencode_item_t *bencode_list_add_str(bencode_item_t *list, const str *s);
+INLINE bencode_item_t *bencode_list_add_list(bencode_item_t *list);
+INLINE bencode_item_t *bencode_list_add_dictionary(bencode_item_t *list);
 
 
 
 
 
 
@@ -158,17 +173,17 @@ bencode_item_t *bencode_string_len(bencode_buffer_t *buf, const char *s, int len
 
 
 /* Creates a new byte-string object. The given string must be null-terminated. Otherwise identical
 /* Creates a new byte-string object. The given string must be null-terminated. Otherwise identical
  * to bencode_string_len(). */
  * to bencode_string_len(). */
-static inline bencode_item_t *bencode_string(bencode_buffer_t *buf, const char *s);
+INLINE bencode_item_t *bencode_string(bencode_buffer_t *buf, const char *s);
 
 
 /* Creates a new byte-string object from a "str" object. The string does not have to be null-
 /* Creates a new byte-string object from a "str" object. The string does not have to be null-
  * terminated. */
  * terminated. */
-static inline bencode_item_t *bencode_str(bencode_buffer_t *buf, const str *s);
+INLINE bencode_item_t *bencode_str(bencode_buffer_t *buf, const str *s);
 
 
 /* Identical to the above three functions, but copies the string into the bencode_buffer_t object.
 /* Identical to the above three functions, but copies the string into the bencode_buffer_t object.
  * Thus, the given string doesn't have to remain valid and accessible afterwards. */
  * Thus, the given string doesn't have to remain valid and accessible afterwards. */
 bencode_item_t *bencode_string_len_dup(bencode_buffer_t *buf, const char *s, int len);
 bencode_item_t *bencode_string_len_dup(bencode_buffer_t *buf, const char *s, int len);
-static inline bencode_item_t *bencode_string_dup(bencode_buffer_t *buf, const char *s);
-static inline bencode_item_t *bencode_str_dup(bencode_buffer_t *buf, const str *s);
+INLINE bencode_item_t *bencode_string_dup(bencode_buffer_t *buf, const char *s);
+INLINE bencode_item_t *bencode_str_dup(bencode_buffer_t *buf, const str *s);
 
 
 /* Creates a new byte-string object from an iovec array. The created object has different internal
 /* Creates a new byte-string object from an iovec array. The created object has different internal
  * semantics (not a BENCODE_STRING, but a BENCODE_IOVEC) and must not be treated like other string
  * semantics (not a BENCODE_STRING, but a BENCODE_IOVEC) and must not be treated like other string
@@ -180,11 +195,11 @@ bencode_item_t *bencode_string_iovec(bencode_buffer_t *buf, const struct iovec *
 
 
 /* Convenience function to compare a string object to a regular C string. Returns 2 if object
 /* Convenience function to compare a string object to a regular C string. Returns 2 if object
  * isn't a string object, otherwise returns according to strcmp(). */
  * isn't a string object, otherwise returns according to strcmp(). */
-static inline int bencode_strcmp(bencode_item_t *a, const char *b);
+INLINE int bencode_strcmp(bencode_item_t *a, const char *b);
 
 
 /* Converts the string object "in" into a str object "out". Returns "out" on success, or NULL on
 /* Converts the string object "in" into a str object "out". Returns "out" on success, or NULL on
  * error ("in" was NULL or not a string object). */
  * error ("in" was NULL or not a string object). */
-static inline str *bencode_get_str(bencode_item_t *in, str *out);
+INLINE str *bencode_get_str(bencode_item_t *in, str *out);
 
 
 
 
 
 
@@ -292,10 +307,10 @@ bencode_item_t *bencode_decode(bencode_buffer_t *buf, const char *s, int len);
 
 
 /* Identical to bencode_decode(), but returns successfully only if the type of the decoded object match
 /* Identical to bencode_decode(), but returns successfully only if the type of the decoded object match
  * "expect". */
  * "expect". */
-static inline bencode_item_t *bencode_decode_expect(bencode_buffer_t *buf, const char *s, int len, bencode_type_t expect);
+INLINE bencode_item_t *bencode_decode_expect(bencode_buffer_t *buf, const char *s, int len, bencode_type_t expect);
 
 
 /* Identical to bencode_decode_expect() but takes a "str" argument. */
 /* Identical to bencode_decode_expect() but takes a "str" argument. */
-static inline bencode_item_t *bencode_decode_expect_str(bencode_buffer_t *buf, const str *s, bencode_type_t expect);
+INLINE bencode_item_t *bencode_decode_expect_str(bencode_buffer_t *buf, const str *s, bencode_type_t expect);
 
 
 
 
 
 
@@ -306,7 +321,7 @@ static inline bencode_item_t *bencode_decode_expect_str(bencode_buffer_t *buf, c
 /* Searches the given dictionary object for the given key and returns the respective value. Returns
 /* Searches the given dictionary object for the given key and returns the respective value. Returns
  * NULL if the given object isn't a dictionary or if the key doesn't exist. The key must be a
  * NULL if the given object isn't a dictionary or if the key doesn't exist. The key must be a
  * null-terminated string. */
  * null-terminated string. */
-static inline bencode_item_t *bencode_dictionary_get(bencode_item_t *dict, const char *key);
+INLINE bencode_item_t *bencode_dictionary_get(bencode_item_t *dict, const char *key);
 
 
 /* Identical to bencode_dictionary_get() but doesn't require the key to be null-terminated. */
 /* Identical to bencode_dictionary_get() but doesn't require the key to be null-terminated. */
 bencode_item_t *bencode_dictionary_get_len(bencode_item_t *dict, const char *key, int key_len);
 bencode_item_t *bencode_dictionary_get_len(bencode_item_t *dict, const char *key, int key_len);
@@ -315,31 +330,31 @@ bencode_item_t *bencode_dictionary_get_len(bencode_item_t *dict, const char *key
  * returns it as a pointer to the string itself. Returns NULL if the value is of some other type. The
  * returns it as a pointer to the string itself. Returns NULL if the value is of some other type. The
  * returned string is NOT null-terminated. Length of the string is returned in *len, which must be a
  * returned string is NOT null-terminated. Length of the string is returned in *len, which must be a
  * valid pointer. The returned string will be valid until dict's bencode_buffer_t object is destroyed. */
  * valid pointer. The returned string will be valid until dict's bencode_buffer_t object is destroyed. */
-static inline char *bencode_dictionary_get_string(bencode_item_t *dict, const char *key, int *len);
+INLINE char *bencode_dictionary_get_string(bencode_item_t *dict, const char *key, int *len);
 
 
 /* Identical to bencode_dictionary_get_string() but fills in a "str" struct. Returns str->s, which
 /* Identical to bencode_dictionary_get_string() but fills in a "str" struct. Returns str->s, which
  * may be NULL. */
  * may be NULL. */
-static inline char *bencode_dictionary_get_str(bencode_item_t *dict, const char *key, str *str);
+INLINE char *bencode_dictionary_get_str(bencode_item_t *dict, const char *key, str *str);
 
 
 /* Looks up the given key in the dictionary and compares the corresponding value to the given
 /* Looks up the given key in the dictionary and compares the corresponding value to the given
  * null-terminated string. Returns 2 if the key isn't found or if the value isn't a string, otherwise
  * null-terminated string. Returns 2 if the key isn't found or if the value isn't a string, otherwise
  * returns according to strcmp(). */
  * returns according to strcmp(). */
-static inline int bencode_dictionary_get_strcmp(bencode_item_t *dict, const char *key, const char *str);
+INLINE int bencode_dictionary_get_strcmp(bencode_item_t *dict, const char *key, const char *str);
 
 
 /* Identical to bencode_dictionary_get() but returns the string in a newly allocated buffer (using the
 /* Identical to bencode_dictionary_get() but returns the string in a newly allocated buffer (using the
  * BENCODE_MALLOC function), which remains valid even after bencode_buffer_t is destroyed. */
  * BENCODE_MALLOC function), which remains valid even after bencode_buffer_t is destroyed. */
-static inline char *bencode_dictionary_get_string_dup(bencode_item_t *dict, const char *key, int *len);
+INLINE char *bencode_dictionary_get_string_dup(bencode_item_t *dict, const char *key, int *len);
 
 
 /* Combines bencode_dictionary_get_str() and bencode_dictionary_get_string_dup(). Fills in a "str"
 /* Combines bencode_dictionary_get_str() and bencode_dictionary_get_string_dup(). Fills in a "str"
  * struct, but copies the string into a newly allocated buffer. Returns str->s. */
  * struct, but copies the string into a newly allocated buffer. Returns str->s. */
-static inline char *bencode_dictionary_get_str_dup(bencode_item_t *dict, const char *key, str *str);
+INLINE char *bencode_dictionary_get_str_dup(bencode_item_t *dict, const char *key, str *str);
 
 
 /* Identical to bencode_dictionary_get_string() but expects an integer object. The parameter "defval"
 /* Identical to bencode_dictionary_get_string() but expects an integer object. The parameter "defval"
  * specified which value should be returned if the key is not found or if the value is not an integer. */
  * specified which value should be returned if the key is not found or if the value is not an integer. */
-static inline long long int bencode_dictionary_get_integer(bencode_item_t *dict, const char *key, long long int defval);
+INLINE long long int bencode_dictionary_get_integer(bencode_item_t *dict, const char *key, long long int defval);
 
 
 /* Identical to bencode_dictionary_get(), but returns the object only if its type matches "expect". */
 /* Identical to bencode_dictionary_get(), but returns the object only if its type matches "expect". */
-static inline bencode_item_t *bencode_dictionary_get_expect(bencode_item_t *dict, const char *key, bencode_type_t expect);
+INLINE bencode_item_t *bencode_dictionary_get_expect(bencode_item_t *dict, const char *key, bencode_type_t expect);
 
 
 
 
 
 
@@ -347,89 +362,105 @@ static inline bencode_item_t *bencode_dictionary_get_expect(bencode_item_t *dict
 
 
 /**************************/
 /**************************/
 
 
-static inline bencode_buffer_t *bencode_item_buffer(bencode_item_t *i) {
+INLINE bencode_buffer_t *bencode_item_buffer(bencode_item_t *i) {
 	if (!i)
 	if (!i)
 		return NULL;
 		return NULL;
 	return i->buffer;
 	return i->buffer;
 }
 }
 
 
-static inline bencode_item_t *bencode_string(bencode_buffer_t *buf, const char *s) {
+INLINE bencode_item_t *bencode_string(bencode_buffer_t *buf, const char *s) {
 	return bencode_string_len(buf, s, strlen(s));
 	return bencode_string_len(buf, s, strlen(s));
 }
 }
 
 
-static inline bencode_item_t *bencode_string_dup(bencode_buffer_t *buf, const char *s) {
+INLINE bencode_item_t *bencode_string_dup(bencode_buffer_t *buf, const char *s) {
 	return bencode_string_len_dup(buf, s, strlen(s));
 	return bencode_string_len_dup(buf, s, strlen(s));
 }
 }
 
 
-static inline bencode_item_t *bencode_str(bencode_buffer_t *buf, const str *s) {
+INLINE bencode_item_t *bencode_str(bencode_buffer_t *buf, const str *s) {
 	return bencode_string_len(buf, s->s, s->len);
 	return bencode_string_len(buf, s->s, s->len);
 }
 }
 
 
-static inline bencode_item_t *bencode_str_dup(bencode_buffer_t *buf, const str *s) {
+INLINE bencode_item_t *bencode_str_dup(bencode_buffer_t *buf, const str *s) {
 	return bencode_string_len_dup(buf, s->s, s->len);
 	return bencode_string_len_dup(buf, s->s, s->len);
 }
 }
 
 
-static inline bencode_item_t *bencode_dictionary_add(bencode_item_t *dict, const char *key, bencode_item_t *val) {
+INLINE bencode_item_t *bencode_dictionary_add(bencode_item_t *dict, const char *key, bencode_item_t *val) {
 	if (!key)
 	if (!key)
 		return NULL;
 		return NULL;
 	return bencode_dictionary_add_len(dict, key, strlen(key), val);
 	return bencode_dictionary_add_len(dict, key, strlen(key), val);
 }
 }
 
 
-static inline bencode_item_t *bencode_dictionary_add_string(bencode_item_t *dict, const char *key, const char *val) {
+INLINE bencode_item_t *bencode_dictionary_str_add(bencode_item_t *dict, const str *key, bencode_item_t *val) {
+	if (!key)
+		return NULL;
+	return bencode_dictionary_add_len(dict, key->s, key->len, val);
+}
+
+INLINE bencode_item_t *bencode_dictionary_add_string(bencode_item_t *dict, const char *key, const char *val) {
 	if (!val)
 	if (!val)
 		return NULL;
 		return NULL;
 	return bencode_dictionary_add(dict, key, bencode_string(bencode_item_buffer(dict), val));
 	return bencode_dictionary_add(dict, key, bencode_string(bencode_item_buffer(dict), val));
 }
 }
 
 
-static inline bencode_item_t *bencode_dictionary_add_string_dup(bencode_item_t *dict, const char *key, const char *val) {
+INLINE bencode_item_t *bencode_dictionary_add_string_dup(bencode_item_t *dict, const char *key, const char *val) {
 	if (!val)
 	if (!val)
 		return NULL;
 		return NULL;
 	return bencode_dictionary_add(dict, key, bencode_string_dup(bencode_item_buffer(dict), val));
 	return bencode_dictionary_add(dict, key, bencode_string_dup(bencode_item_buffer(dict), val));
 }
 }
 
 
-static inline bencode_item_t *bencode_dictionary_add_str(bencode_item_t *dict, const char *key, const str *val) {
+INLINE bencode_item_t *bencode_dictionary_add_str(bencode_item_t *dict, const char *key, const str *val) {
 	if (!val)
 	if (!val)
 		return NULL;
 		return NULL;
 	return bencode_dictionary_add(dict, key, bencode_str(bencode_item_buffer(dict), val));
 	return bencode_dictionary_add(dict, key, bencode_str(bencode_item_buffer(dict), val));
 }
 }
 
 
-static inline bencode_item_t *bencode_dictionary_add_str_dup(bencode_item_t *dict, const char *key, const str *val) {
+INLINE bencode_item_t *bencode_dictionary_str_add_str(bencode_item_t *dict, const str *key, const str *val) {
+	if (!val)
+		return NULL;
+	return bencode_dictionary_str_add(dict, key, bencode_str(bencode_item_buffer(dict), val));
+}
+
+INLINE bencode_item_t *bencode_dictionary_add_str_dup(bencode_item_t *dict, const char *key, const str *val) {
 	if (!val)
 	if (!val)
 		return NULL;
 		return NULL;
 	return bencode_dictionary_add(dict, key, bencode_str_dup(bencode_item_buffer(dict), val));
 	return bencode_dictionary_add(dict, key, bencode_str_dup(bencode_item_buffer(dict), val));
 }
 }
 
 
-static inline bencode_item_t *bencode_dictionary_add_integer(bencode_item_t *dict, const char *key, long long int val) {
+INLINE bencode_item_t *bencode_dictionary_add_integer(bencode_item_t *dict, const char *key, long long int val) {
 	return bencode_dictionary_add(dict, key, bencode_integer(bencode_item_buffer(dict), val));
 	return bencode_dictionary_add(dict, key, bencode_integer(bencode_item_buffer(dict), val));
 }
 }
 
 
-static inline bencode_item_t *bencode_dictionary_add_dictionary(bencode_item_t *dict, const char *key) {
+INLINE bencode_item_t *bencode_dictionary_add_dictionary(bencode_item_t *dict, const char *key) {
 	return bencode_dictionary_add(dict, key, bencode_dictionary(bencode_item_buffer(dict)));
 	return bencode_dictionary_add(dict, key, bencode_dictionary(bencode_item_buffer(dict)));
 }
 }
 
 
-static inline bencode_item_t *bencode_dictionary_add_list(bencode_item_t *dict, const char *key) {
+INLINE bencode_item_t *bencode_dictionary_add_list(bencode_item_t *dict, const char *key) {
 	return bencode_dictionary_add(dict, key, bencode_list(bencode_item_buffer(dict)));
 	return bencode_dictionary_add(dict, key, bencode_list(bencode_item_buffer(dict)));
 }
 }
 
 
-static inline bencode_item_t *bencode_list_add_string(bencode_item_t *list, const char *s) {
+INLINE bencode_item_t *bencode_list_add_string(bencode_item_t *list, const char *s) {
 	return bencode_list_add(list, bencode_string(bencode_item_buffer(list), s));
 	return bencode_list_add(list, bencode_string(bencode_item_buffer(list), s));
 }
 }
 
 
-static inline bencode_item_t *bencode_list_add_list(bencode_item_t *list) {
+INLINE bencode_item_t *bencode_list_add_str(bencode_item_t *list, const str *s) {
+	return bencode_list_add(list, bencode_str(bencode_item_buffer(list), s));
+}
+
+INLINE bencode_item_t *bencode_list_add_list(bencode_item_t *list) {
 	return bencode_list_add(list, bencode_list(bencode_item_buffer(list)));
 	return bencode_list_add(list, bencode_list(bencode_item_buffer(list)));
 }
 }
 
 
-static inline bencode_item_t *bencode_list_add_dictionary(bencode_item_t *list) {
+INLINE bencode_item_t *bencode_list_add_dictionary(bencode_item_t *list) {
 	return bencode_list_add(list, bencode_dictionary(bencode_item_buffer(list)));
 	return bencode_list_add(list, bencode_dictionary(bencode_item_buffer(list)));
 }
 }
 
 
-static inline bencode_item_t *bencode_dictionary_get(bencode_item_t *dict, const char *key) {
+INLINE bencode_item_t *bencode_dictionary_get(bencode_item_t *dict, const char *key) {
 	if (!key)
 	if (!key)
 		return NULL;
 		return NULL;
 	return bencode_dictionary_get_len(dict, key, strlen(key));
 	return bencode_dictionary_get_len(dict, key, strlen(key));
 }
 }
 
 
-static inline char *bencode_dictionary_get_string(bencode_item_t *dict, const char *key, int *len) {
+INLINE char *bencode_dictionary_get_string(bencode_item_t *dict, const char *key, int *len) {
 	bencode_item_t *val;
 	bencode_item_t *val;
 	val = bencode_dictionary_get(dict, key);
 	val = bencode_dictionary_get(dict, key);
 	if (!val || val->type != BENCODE_STRING)
 	if (!val || val->type != BENCODE_STRING)
@@ -438,14 +469,14 @@ static inline char *bencode_dictionary_get_string(bencode_item_t *dict, const ch
 	return val->iov[1].iov_base;
 	return val->iov[1].iov_base;
 }
 }
 
 
-static inline char *bencode_dictionary_get_str(bencode_item_t *dict, const char *key, str *str) {
+INLINE char *bencode_dictionary_get_str(bencode_item_t *dict, const char *key, str *str) {
 	str->s = bencode_dictionary_get_string(dict, key, &str->len);
 	str->s = bencode_dictionary_get_string(dict, key, &str->len);
 	if (!str->s)
 	if (!str->s)
 		str->len = 0;
 		str->len = 0;
 	return str->s;
 	return str->s;
 }
 }
 
 
-static inline char *bencode_dictionary_get_string_dup(bencode_item_t *dict, const char *key, int *len) {
+INLINE char *bencode_dictionary_get_string_dup(bencode_item_t *dict, const char *key, int *len) {
 	const char *s;
 	const char *s;
 	char *ret;
 	char *ret;
 	s = bencode_dictionary_get_string(dict, key, len);
 	s = bencode_dictionary_get_string(dict, key, len);
@@ -458,12 +489,12 @@ static inline char *bencode_dictionary_get_string_dup(bencode_item_t *dict, cons
 	return ret;
 	return ret;
 }
 }
 
 
-static inline char *bencode_dictionary_get_str_dup(bencode_item_t *dict, const char *key, str *str) {
+INLINE char *bencode_dictionary_get_str_dup(bencode_item_t *dict, const char *key, str *str) {
 	str->s = bencode_dictionary_get_string_dup(dict, key, &str->len);
 	str->s = bencode_dictionary_get_string_dup(dict, key, &str->len);
 	return str->s;
 	return str->s;
 }
 }
 
 
-static inline long long int bencode_dictionary_get_integer(bencode_item_t *dict, const char *key, long long int defval) {
+INLINE long long int bencode_dictionary_get_integer(bencode_item_t *dict, const char *key, long long int defval) {
 	bencode_item_t *val;
 	bencode_item_t *val;
 	val = bencode_dictionary_get(dict, key);
 	val = bencode_dictionary_get(dict, key);
 	if (!val || val->type != BENCODE_INTEGER)
 	if (!val || val->type != BENCODE_INTEGER)
@@ -471,7 +502,7 @@ static inline long long int bencode_dictionary_get_integer(bencode_item_t *dict,
 	return val->value;
 	return val->value;
 }
 }
 
 
-static inline bencode_item_t *bencode_decode_expect(bencode_buffer_t *buf, const char *s, int len, bencode_type_t expect) {
+INLINE bencode_item_t *bencode_decode_expect(bencode_buffer_t *buf, const char *s, int len, bencode_type_t expect) {
 	bencode_item_t *ret;
 	bencode_item_t *ret;
 	ret = bencode_decode(buf, s, len);
 	ret = bencode_decode(buf, s, len);
 	if (!ret || ret->type != expect)
 	if (!ret || ret->type != expect)
@@ -479,22 +510,22 @@ static inline bencode_item_t *bencode_decode_expect(bencode_buffer_t *buf, const
 	return ret;
 	return ret;
 }
 }
 
 
-static inline bencode_item_t *bencode_decode_expect_str(bencode_buffer_t *buf, const str *s, bencode_type_t expect) {
+INLINE bencode_item_t *bencode_decode_expect_str(bencode_buffer_t *buf, const str *s, bencode_type_t expect) {
 	return bencode_decode_expect(buf, s->s, s->len, expect);
 	return bencode_decode_expect(buf, s->s, s->len, expect);
 }
 }
 
 
-static inline bencode_item_t *bencode_dictionary_get_expect(bencode_item_t *dict, const char *key, bencode_type_t expect) {
+INLINE bencode_item_t *bencode_dictionary_get_expect(bencode_item_t *dict, const char *key, bencode_type_t expect) {
 	bencode_item_t *ret;
 	bencode_item_t *ret;
 	ret = bencode_dictionary_get(dict, key);
 	ret = bencode_dictionary_get(dict, key);
 	if (!ret || ret->type != expect)
 	if (!ret || ret->type != expect)
 		return NULL;
 		return NULL;
 	return ret;
 	return ret;
 }
 }
-static inline str *bencode_collapse_str(bencode_item_t *root, str *out) {
+INLINE str *bencode_collapse_str(bencode_item_t *root, str *out) {
 	out->s = bencode_collapse(root, &out->len);
 	out->s = bencode_collapse(root, &out->len);
 	return out;
 	return out;
 }
 }
-static inline int bencode_strcmp(bencode_item_t *a, const char *b) {
+INLINE int bencode_strcmp(bencode_item_t *a, const char *b) {
 	int len;
 	int len;
 	if (a->type != BENCODE_STRING)
 	if (a->type != BENCODE_STRING)
 		return 2;
 		return 2;
@@ -505,7 +536,7 @@ static inline int bencode_strcmp(bencode_item_t *a, const char *b) {
 		return 1;
 		return 1;
 	return memcmp(a->iov[1].iov_base, b, len);
 	return memcmp(a->iov[1].iov_base, b, len);
 }
 }
-static inline int bencode_dictionary_get_strcmp(bencode_item_t *dict, const char *key, const char *str) {
+INLINE int bencode_dictionary_get_strcmp(bencode_item_t *dict, const char *key, const char *str) {
 	bencode_item_t *i;
 	bencode_item_t *i;
 	i = bencode_dictionary_get(dict, key);
 	i = bencode_dictionary_get(dict, key);
 	if (!i)
 	if (!i)
@@ -513,7 +544,7 @@ static inline int bencode_dictionary_get_strcmp(bencode_item_t *dict, const char
 	return bencode_strcmp(i, str);
 	return bencode_strcmp(i, str);
 }
 }
 
 
-static inline str *bencode_get_str(bencode_item_t *in, str *out) {
+INLINE str *bencode_get_str(bencode_item_t *in, str *out) {
 	if (!in || in->type != BENCODE_STRING)
 	if (!in || in->type != BENCODE_STRING)
 		return NULL;
 		return NULL;
 	out->s = in->iov[1].iov_base;
 	out->s = in->iov[1].iov_base;
@@ -521,7 +552,7 @@ static inline str *bencode_get_str(bencode_item_t *in, str *out) {
 	return out;
 	return out;
 }
 }
 
 
-static inline bencode_item_t *bencode_dictionary_add_iovec(bencode_item_t *dict, const char *key,
+INLINE bencode_item_t *bencode_dictionary_add_iovec(bencode_item_t *dict, const char *key,
 		const struct iovec *iov, int iov_cnt, int str_len)
 		const struct iovec *iov, int iov_cnt, int str_len)
 {
 {
 	return bencode_dictionary_add(dict, key, bencode_string_iovec(bencode_item_buffer(dict), iov, iov_cnt, str_len));
 	return bencode_dictionary_add(dict, key, bencode_string_iovec(bencode_item_buffer(dict), iov, iov_cnt, str_len));

+ 58 - 101
modules/rtpengine/rtpengine.c

@@ -449,6 +449,19 @@ static inline int str_eq(const str *p, const char *q) {
 		return 0;
 		return 0;
 	return 1;
 	return 1;
 }
 }
+static inline str str_prefix(const str *p, const char *q) {
+	str ret;
+	ret.s = NULL;
+	int l = strlen(q);
+	if (p->len < l)
+		return ret;
+	if (memcmp(p->s, q, l))
+		return ret;
+	ret = *p;
+	ret.s += l;
+	ret.len -= l;
+	return ret;
+}
 
 
 
 
 static int rtpengine_set_store(modparam_t type, void * val){
 static int rtpengine_set_store(modparam_t type, void * val){
@@ -1121,7 +1134,7 @@ static int parse_flags(struct ng_flags_parse *ng_flags, struct sip_msg *msg, enu
 {
 {
 	char *e;
 	char *e;
 	const char *err;
 	const char *err;
-	str key, val;
+	str key, val, s;
 
 
 	if (!flags_str)
 	if (!flags_str)
 		return 0;
 		return 0;
@@ -1151,21 +1164,23 @@ static int parse_flags(struct ng_flags_parse *ng_flags, struct sip_msg *msg, enu
 		if (!key.len)
 		if (!key.len)
 			break;
 			break;
 
 
-		/* XXX make this prettier */
-		err = "unknown flag";
+		/* check for items which have their own sub-list */
+		s = str_prefix(&key, "replace-");
+		if (s.s) {
+			bencode_list_add_str(ng_flags->replace, &s);
+			goto next;
+		}
+
+		s = str_prefix(&key, "rtcp-mux-");
+		if (s.s) {
+			bencode_list_add_str(ng_flags->rtcp_mux, &s);
+			goto next;
+		}
+
+		/* check for specially handled items */
 		switch (key.len) {
 		switch (key.len) {
 			case 3:
 			case 3:
-				if (str_eq(&key, "ICE")) {
-					err = "missing value";
-					if (!val.s)
-						goto error;
-					err = "invalid value";
-					if (str_eq(&val, "force") || str_eq(&val, "force_relay")|| str_eq(&val, "remove"))
-						bencode_dictionary_add_str(ng_flags->dict, "ICE", &val);
-					else
-						goto error;
-				}
-				else if (str_eq(&key, "RTP")) {
+				if (str_eq(&key, "RTP")) {
 					ng_flags->transport |= 0x100;
 					ng_flags->transport |= 0x100;
 					ng_flags->transport &= ~0x001;
 					ng_flags->transport &= ~0x001;
 				}
 				}
@@ -1174,7 +1189,8 @@ static int parse_flags(struct ng_flags_parse *ng_flags, struct sip_msg *msg, enu
 					ng_flags->transport &= ~0x002;
 					ng_flags->transport &= ~0x002;
 				}
 				}
 				else
 				else
-					goto error;
+					goto generic;
+				goto next;
 				break;
 				break;
 
 
 			case 4:
 			case 4:
@@ -1183,50 +1199,41 @@ static int parse_flags(struct ng_flags_parse *ng_flags, struct sip_msg *msg, enu
 				else if (str_eq(&key, "AVPF"))
 				else if (str_eq(&key, "AVPF"))
 					ng_flags->transport |= 0x102;
 					ng_flags->transport |= 0x102;
 				else
 				else
-					goto error;
-				break;
-
-			case 5:
-				if (str_eq(&key, "force"))
-					bencode_list_add_string(ng_flags->flags, "force");
-				else
-					goto error;
+					goto generic;
+				goto next;
 				break;
 				break;
 
 
 			case 6:
 			case 6:
-				if (str_eq(&key, "to-tag"))
+				if (str_eq(&key, "to-tag")) {
 					ng_flags->to = 1;
 					ng_flags->to = 1;
-				else
-					goto error;
+					goto next;
+				}
 				break;
 				break;
 
 
 			case 7:
 			case 7:
-				if (str_eq(&key, "RTP/AVP"))
+				if (str_eq(&key, "RTP/AVP")) {
 					ng_flags->transport = 0x100;
 					ng_flags->transport = 0x100;
-				else
-					goto error;
+					goto next;
+				}
 				break;
 				break;
 
 
 			case 8:
 			case 8:
-				if (str_eq(&key, "internal"))
-					bencode_list_add_string(ng_flags->direction, "internal");
-				else if (str_eq(&key, "external"))
-					bencode_list_add_string(ng_flags->direction, "external");
+				if (str_eq(&key, "internal") || str_eq(&key, "external"))
+					bencode_list_add_str(ng_flags->direction, &key);
 				else if (str_eq(&key, "RTP/AVPF"))
 				else if (str_eq(&key, "RTP/AVPF"))
 					ng_flags->transport = 0x102;
 					ng_flags->transport = 0x102;
 				else if (str_eq(&key, "RTP/SAVP"))
 				else if (str_eq(&key, "RTP/SAVP"))
 					ng_flags->transport = 0x101;
 					ng_flags->transport = 0x101;
 				else
 				else
-					goto error;
+					goto generic;
+				goto next;
 				break;
 				break;
 
 
 			case 9:
 			case 9:
-				if (str_eq(&key, "symmetric"))
-					bencode_list_add_string(ng_flags->flags, "symmetric");
-				else if (str_eq(&key, "RTP/SAVPF"))
+				if (str_eq(&key, "RTP/SAVPF")) {
 					ng_flags->transport = 0x103;
 					ng_flags->transport = 0x103;
-				else
-					goto error;
+					goto next;
+				}
 				break;
 				break;
 
 
 			case 10:
 			case 10:
@@ -1243,17 +1250,12 @@ static int parse_flags(struct ng_flags_parse *ng_flags, struct sip_msg *msg, enu
 						ng_flags->via = -1;
 						ng_flags->via = -1;
 					else
 					else
 						goto error;
 						goto error;
+					goto next;
 				}
 				}
-				else if (str_eq(&key, "asymmetric"))
-					bencode_list_add_string(ng_flags->flags, "asymmetric");
-				else
-					goto error;
 				break;
 				break;
 
 
 			case 11:
 			case 11:
-				if (str_eq(&key, "auto-bridge"))
-					bencode_list_add_string(ng_flags->flags, "auto-bridge");
-				else if (str_eq(&key, "repacketize")) {
+				if (str_eq(&key, "repacketize")) {
 					err = "missing value";
 					err = "missing value";
 					if (!val.s)
 					if (!val.s)
 						goto error;
 						goto error;
@@ -1267,9 +1269,8 @@ static int parse_flags(struct ng_flags_parse *ng_flags, struct sip_msg *msg, enu
 					if (!ng_flags->packetize)
 					if (!ng_flags->packetize)
 						goto error;
 						goto error;
 					bencode_dictionary_add_integer(ng_flags->dict, "repacketize", ng_flags->packetize);
 					bencode_dictionary_add_integer(ng_flags->dict, "repacketize", ng_flags->packetize);
+					goto next;
 				}
 				}
-				else
-					goto error;
 				break;
 				break;
 
 
 			case 12:
 			case 12:
@@ -1278,63 +1279,19 @@ static int parse_flags(struct ng_flags_parse *ng_flags, struct sip_msg *msg, enu
 					if (*op != OP_OFFER)
 					if (*op != OP_OFFER)
 						goto error;
 						goto error;
 					*op = OP_ANSWER;
 					*op = OP_ANSWER;
+					goto next;
 				}
 				}
-				else
-					goto error;
-				break;
-			case 13:
-				if (str_eq(&key, "trust-address"))
-					bencode_list_add_string(ng_flags->flags, "trust-address");
-				else if (str_eq(&key, "media-address")) {
-					err = "missing value";
-					if (!val.s)
-						goto error;
-				}
-				else
-					goto error;
 				break;
 				break;
-
-			case 14:
-				if (str_eq(&key, "replace-origin"))
-					bencode_list_add_string(ng_flags->replace, "origin");
-				else if (str_eq(&key, "address-family")) {
-					err = "missing value";
-					if (!val.s)
-						goto error;
-					err = "invalid value";
-					if (str_eq(&val, "IP4") || str_eq(&val, "IP6"))
-						bencode_dictionary_add_str(ng_flags->dict, "address family", &val);
-					else
-						goto error;
-				}
-				else if (str_eq(&key, "rtcp-mux-demux"))
-					bencode_list_add_string(ng_flags->rtcp_mux, "demux");
-				else if (str_eq(&key, "rtcp-mux-offer"))
-					bencode_list_add_string(ng_flags->rtcp_mux, "offer");
-				else
-					goto error;
-				break;
-
-			case 15:
-				if (str_eq(&key, "rtcp-mux-reject"))
-					bencode_list_add_string(ng_flags->rtcp_mux, "reject");
-				else if (str_eq(&key, "rtcp-mux-accept"))
-					bencode_list_add_string(ng_flags->rtcp_mux, "accept");
-				else
-					goto error;
-				break;
-
-			case 26:
-				if (str_eq(&key, "replace-session-connection"))
-					bencode_list_add_string(ng_flags->replace, "session-connection");
-				else
-					goto error;
-				break;
-
-			default:
-				goto error;
 		}
 		}
 
 
+generic:
+		if (!val.s)
+			bencode_list_add_str(ng_flags->flags, &key);
+		else
+			bencode_dictionary_str_add_str(ng_flags->dict, &key, &val);
+		goto next;
+
+next:
 		flags_str = e;
 		flags_str = e;
 	}
 	}