|
|
|
|
@ -1422,7 +1422,7 @@
|
|
|
|
|
+ http://sip-router.org/tracker.
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/modules/rtpengine/bencode.h
|
|
|
|
|
@@ -0,0 +1,530 @@
|
|
|
|
|
@@ -0,0 +1,561 @@
|
|
|
|
|
+#ifndef _BENCODE_H_
|
|
|
|
|
+#define _BENCODE_H_
|
|
|
|
|
+
|
|
|
|
|
@ -1437,8 +1437,10 @@
|
|
|
|
|
+# define BENCODE_MALLOC pkg_malloc
|
|
|
|
|
+# define BENCODE_FREE pkg_free
|
|
|
|
|
+# endif
|
|
|
|
|
+# define INLINE static inline
|
|
|
|
|
+#else
|
|
|
|
|
+/* mediaproxy-ng */
|
|
|
|
|
+/* rtpengine */
|
|
|
|
|
+# include "compat.h"
|
|
|
|
|
+# include "str.h"
|
|
|
|
|
+# ifndef BENCODE_MALLOC
|
|
|
|
|
+# define BENCODE_MALLOC malloc
|
|
|
|
|
@ -1488,6 +1490,13 @@
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+/* 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 ***/
|
|
|
|
|
+
|
|
|
|
|
+/* Initializes a bencode_buffer_t object. This object is used to group together all memory allocations
|
|
|
|
|
@ -1497,6 +1506,9 @@
|
|
|
|
|
+ * Returns 0 on success or -1 on failure (if no memory could be allocated). */
|
|
|
|
|
+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
|
|
|
|
|
+ * and all objects created through it become invalid. */
|
|
|
|
|
+void bencode_buffer_free(bencode_buffer_t *buf);
|
|
|
|
|
@ -1514,7 +1526,7 @@
|
|
|
|
|
+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 */
|
|
|
|
|
+static inline bencode_buffer_t *bencode_item_buffer(bencode_item_t *);
|
|
|
|
|
+INLINE bencode_buffer_t *bencode_item_buffer(bencode_item_t *);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
@ -1529,29 +1541,31 @@
|
|
|
|
|
+ * 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 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 */
|
|
|
|
|
+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
|
|
|
|
|
+ * 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 */
|
|
|
|
|
+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
|
|
|
|
|
+ * 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);
|
|
|
|
|
+
|
|
|
|
|
+/* 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);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
@ -1564,9 +1578,10 @@
|
|
|
|
|
+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 */
|
|
|
|
|
+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);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
@ -1583,17 +1598,17 @@
|
|
|
|
|
+
|
|
|
|
|
+/* Creates a new byte-string object. The given string must be null-terminated. Otherwise identical
|
|
|
|
|
+ * 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-
|
|
|
|
|
+ * 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.
|
|
|
|
|
+ * 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);
|
|
|
|
|
+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
|
|
|
|
|
+ * semantics (not a BENCODE_STRING, but a BENCODE_IOVEC) and must not be treated like other string
|
|
|
|
|
@ -1605,11 +1620,11 @@
|
|
|
|
|
+
|
|
|
|
|
+/* 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(). */
|
|
|
|
|
+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
|
|
|
|
|
+ * 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);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
@ -1717,10 +1732,10 @@
|
|
|
|
|
+
|
|
|
|
|
+/* Identical to bencode_decode(), but returns successfully only if the type of the decoded object match
|
|
|
|
|
+ * "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. */
|
|
|
|
|
+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);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
@ -1731,7 +1746,7 @@
|
|
|
|
|
+/* 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-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. */
|
|
|
|
|
+bencode_item_t *bencode_dictionary_get_len(bencode_item_t *dict, const char *key, int key_len);
|
|
|
|
|
@ -1740,31 +1755,31 @@
|
|
|
|
|
+ * 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
|
|
|
|
|
+ * 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
|
|
|
|
|
+ * 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
|
|
|
|
|
+ * null-terminated string. Returns 2 if the key isn't found or if the value isn't a string, otherwise
|
|
|
|
|
+ * 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
|
|
|
|
|
+ * 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"
|
|
|
|
|
+ * 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"
|
|
|
|
|
+ * 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". */
|
|
|
|
|
+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);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
@ -1772,89 +1787,105 @@
|
|
|
|
|
+
|
|
|
|
|
+/**************************/
|
|
|
|
|
+
|
|
|
|
|
+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)
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ 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));
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+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));
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+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);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+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);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+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)
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ 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)
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ 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)
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ 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)
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ 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)
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ 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));
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+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)));
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+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)));
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+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));
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+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)));
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+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)));
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+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)
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ 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;
|
|
|
|
|
+ val = bencode_dictionary_get(dict, key);
|
|
|
|
|
+ if (!val || val->type != BENCODE_STRING)
|
|
|
|
|
@ -1863,14 +1894,14 @@
|
|
|
|
|
+ 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);
|
|
|
|
|
+ if (!str->s)
|
|
|
|
|
+ str->len = 0;
|
|
|
|
|
+ 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;
|
|
|
|
|
+ char *ret;
|
|
|
|
|
+ s = bencode_dictionary_get_string(dict, key, len);
|
|
|
|
|
@ -1883,12 +1914,12 @@
|
|
|
|
|
+ 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);
|
|
|
|
|
+ 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;
|
|
|
|
|
+ val = bencode_dictionary_get(dict, key);
|
|
|
|
|
+ if (!val || val->type != BENCODE_INTEGER)
|
|
|
|
|
@ -1896,7 +1927,7 @@
|
|
|
|
|
+ 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;
|
|
|
|
|
+ ret = bencode_decode(buf, s, len);
|
|
|
|
|
+ if (!ret || ret->type != expect)
|
|
|
|
|
@ -1904,22 +1935,22 @@
|
|
|
|
|
+ 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);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+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;
|
|
|
|
|
+ ret = bencode_dictionary_get(dict, key);
|
|
|
|
|
+ if (!ret || ret->type != expect)
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ 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);
|
|
|
|
|
+ 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;
|
|
|
|
|
+ if (a->type != BENCODE_STRING)
|
|
|
|
|
+ return 2;
|
|
|
|
|
@ -1930,7 +1961,7 @@
|
|
|
|
|
+ return 1;
|
|
|
|
|
+ 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;
|
|
|
|
|
+ i = bencode_dictionary_get(dict, key);
|
|
|
|
|
+ if (!i)
|
|
|
|
|
@ -1938,7 +1969,7 @@
|
|
|
|
|
+ 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)
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ out->s = in->iov[1].iov_base;
|
|
|
|
|
@ -1946,7 +1977,7 @@
|
|
|
|
|
+ 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)
|
|
|
|
|
+{
|
|
|
|
|
+ return bencode_dictionary_add(dict, key, bencode_string_iovec(bencode_item_buffer(dict), iov, iov_cnt, str_len));
|
|
|
|
|
@ -2902,7 +2933,7 @@
|
|
|
|
|
+
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/modules/rtpengine/rtpengine.c
|
|
|
|
|
@@ -0,0 +1,2113 @@
|
|
|
|
|
@@ -0,0 +1,2070 @@
|
|
|
|
|
+/* $Id$
|
|
|
|
|
+ *
|
|
|
|
|
+ * Copyright (C) 2003-2008 Sippy Software, Inc., http://www.sippysoft.com
|
|
|
|
|
@ -3354,6 +3385,19 @@
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ 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){
|
|
|
|
|
@ -4026,7 +4070,7 @@
|
|
|
|
|
+{
|
|
|
|
|
+ char *e;
|
|
|
|
|
+ const char *err;
|
|
|
|
|
+ str key, val;
|
|
|
|
|
+ str key, val, s;
|
|
|
|
|
+
|
|
|
|
|
+ if (!flags_str)
|
|
|
|
|
+ return 0;
|
|
|
|
|
@ -4056,21 +4100,23 @@
|
|
|
|
|
+ if (!key.len)
|
|
|
|
|
+ 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) {
|
|
|
|
|
+ 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, "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 &= ~0x001;
|
|
|
|
|
+ }
|
|
|
|
|
@ -4079,7 +4125,8 @@
|
|
|
|
|
+ ng_flags->transport &= ~0x002;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ goto error;
|
|
|
|
|
+ goto generic;
|
|
|
|
|
+ goto next;
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case 4:
|
|
|
|
|
@ -4088,50 +4135,41 @@
|
|
|
|
|
+ else if (str_eq(&key, "AVPF"))
|
|
|
|
|
+ ng_flags->transport |= 0x102;
|
|
|
|
|
+ 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;
|
|
|
|
|
+
|
|
|
|
|
+ case 6:
|
|
|
|
|
+ if (str_eq(&key, "to-tag"))
|
|
|
|
|
+ if (str_eq(&key, "to-tag")) {
|
|
|
|
|
+ ng_flags->to = 1;
|
|
|
|
|
+ else
|
|
|
|
|
+ goto error;
|
|
|
|
|
+ goto next;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case 7:
|
|
|
|
|
+ if (str_eq(&key, "RTP/AVP"))
|
|
|
|
|
+ if (str_eq(&key, "RTP/AVP")) {
|
|
|
|
|
+ ng_flags->transport = 0x100;
|
|
|
|
|
+ else
|
|
|
|
|
+ goto error;
|
|
|
|
|
+ goto next;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ 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"))
|
|
|
|
|
+ ng_flags->transport = 0x102;
|
|
|
|
|
+ else if (str_eq(&key, "RTP/SAVP"))
|
|
|
|
|
+ ng_flags->transport = 0x101;
|
|
|
|
|
+ else
|
|
|
|
|
+ goto error;
|
|
|
|
|
+ goto generic;
|
|
|
|
|
+ goto next;
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ 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;
|
|
|
|
|
+ else
|
|
|
|
|
+ goto error;
|
|
|
|
|
+ goto next;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case 10:
|
|
|
|
|
@ -4148,17 +4186,12 @@
|
|
|
|
|
+ ng_flags->via = -1;
|
|
|
|
|
+ else
|
|
|
|
|
+ goto error;
|
|
|
|
|
+ goto next;
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (str_eq(&key, "asymmetric"))
|
|
|
|
|
+ bencode_list_add_string(ng_flags->flags, "asymmetric");
|
|
|
|
|
+ else
|
|
|
|
|
+ goto error;
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ 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";
|
|
|
|
|
+ if (!val.s)
|
|
|
|
|
+ goto error;
|
|
|
|
|
@ -4172,9 +4205,8 @@
|
|
|
|
|
+ if (!ng_flags->packetize)
|
|
|
|
|
+ goto error;
|
|
|
|
|
+ bencode_dictionary_add_integer(ng_flags->dict, "repacketize", ng_flags->packetize);
|
|
|
|
|
+ goto next;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ goto error;
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case 12:
|
|
|
|
|
@ -4183,63 +4215,19 @@
|
|
|
|
|
+ if (*op != OP_OFFER)
|
|
|
|
|
+ goto error;
|
|
|
|
|
+ *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;
|
|
|
|
|
+
|
|
|
|
|
+ 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;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
|