diff options
author | Benny Prijono <bennylp@teluu.com> | 2007-09-18 19:33:33 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2007-09-18 19:33:33 +0000 |
commit | 41234fb3ea6190fdf7bebf0d11bc41d578b66934 (patch) | |
tree | 845b6ba62a1477e77501189b0221b638cae67af9 /pjnath/src/pjnath-test | |
parent | 0b5b5d6d0b9e0c0362c15126bd74176aa1ce5161 (diff) |
Ticket #374: Update STUN specification from rfc3489bis-06 to rfc3489bis-10
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1439 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjnath/src/pjnath-test')
-rw-r--r-- | pjnath/src/pjnath-test/stun.c | 698 | ||||
-rw-r--r-- | pjnath/src/pjnath-test/test.c | 4 | ||||
-rw-r--r-- | pjnath/src/pjnath-test/test.h | 2 |
3 files changed, 679 insertions, 25 deletions
diff --git a/pjnath/src/pjnath-test/stun.c b/pjnath/src/pjnath-test/stun.c index 230e51e7..29a8eb1a 100644 --- a/pjnath/src/pjnath-test/stun.c +++ b/pjnath/src/pjnath-test/stun.c @@ -16,42 +16,392 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "test.h" -static int decode_test(void) -{ - /* Invalid message type */ - - /* Short message */ - - /* Long, random message */ +#define THIS_FILE "stun.c" - /* Message length in header is shorter */ +static pj_stun_msg* create1(pj_pool_t*); +static int verify1(pj_stun_msg*); +static int verify2(pj_stun_msg*); +static int verify5(pj_stun_msg*); - /* Message length in header is longer */ - - /* Invalid magic */ - - /* Attribute length is not valid */ +static struct test +{ + const char *title; + char *pdu; + unsigned pdu_len; + pj_stun_msg* (*create)(pj_pool_t*); + pj_status_t expected_status; + int (*verify)(pj_stun_msg*); +} tests[] = +{ + { + "Invalid message type", + "\x11\x01\x00\x00\x21\x12\xa4\x42" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 20, + NULL, + PJNATH_EINSTUNMSGTYPE, + NULL + }, + { + "Short message (1) (partial header)", + "\x00\x01", + 2, + NULL, + PJNATH_EINSTUNMSGLEN, + NULL + }, + { + "Short message (2) (partial header)", + "\x00\x01\x00\x00\x21\x12\xa4\x42" + "\x00\x00\x00\x00\x00\x00\x00\x00", + 16, + NULL, + PJNATH_EINSTUNMSGLEN, + NULL + }, + { + "Short message (3), (missing attribute)", + "\x00\x01\x00\x08\x21\x12\xa4\x42" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 20, + NULL, + PJNATH_EINSTUNMSGLEN, + NULL + }, + { + "Short message (4), (partial attribute header)", + "\x00\x01\x00\x08\x21\x12\xa4\x42" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\x28", + 22, + NULL, + PJNATH_EINSTUNMSGLEN, + NULL + }, + { + "Short message (5), (partial attribute header)", + "\x00\x01\x00\x08\x21\x12\xa4\x42" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\x28\x00", + 23, + NULL, + PJNATH_EINSTUNMSGLEN, + NULL + }, + { + "Short message (6), (partial attribute header)", + "\x00\x01\x00\x08\x21\x12\xa4\x42" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\x28\x00\x04", + 24, + NULL, + PJNATH_EINSTUNMSGLEN, + NULL + }, + { + "Short message (7), (partial attribute body)", + "\x00\x01\x00\x08\x21\x12\xa4\x42" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\x28\x00\x04\x00\x00\x00", + 27, + NULL, + PJNATH_EINSTUNMSGLEN, + NULL + }, + { + "Message length in header is too long", + "\x00\x01\xff\xff\x21\x12\xa4\x42" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\x28\x00\x04\x00\x00\x00", + 27, + NULL, + PJNATH_EINSTUNMSGLEN, + NULL + }, + { + "Message length in header is shorter", + "\x00\x01\x00\x04\x21\x12\xa4\x42" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\x28\x00\x04\x00\x00\x00\x00", + 28, + NULL, + PJNATH_EINSTUNMSGLEN, + NULL + }, + { + "Invalid magic", + "\x00\x01\x00\x08\x00\x12\xa4\x42" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\x28\x00\x04\x00\x00\x00\x00", + 28, + NULL, + PJ_SUCCESS, + NULL + }, + { + "Character beyond message", + "\x00\x01\x00\x08\x21\x12\xa4\x42" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\x28\x00\x04\x00\x00\x00\x00\x0a", + 29, + NULL, + PJNATH_EINSTUNMSGLEN, + NULL + }, + { + "Respond unknown mandatory attribute with 420 and " + "UNKNOWN-ATTRIBUTES attribute", + NULL, + 0, + &create1, + 0, + &verify1 + }, + { + "Unknown but non-mandatory should be okay", + "\x00\x01\x00\x08\x21\x12\xa4\x42" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\xff\x00\x04\x00\x00\x00\x00", + 28, + NULL, + PJ_SUCCESS, + &verify2 + }, + { + "String attr length larger than message", + "\x00\x01\x00\x08\x00\x12\xa4\x42" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x06\x00\xff\x00\x00\x00\x00", + 28, + NULL, + PJNATH_ESTUNINATTRLEN, + NULL + }, + { + "Attribute other than FINGERPRINT after MESSAGE-INTEGRITY is allowed", + "\x00\x01\x00\x20\x21\x12\xa4\x42" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x08\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" // M-I + "\x80\x24\x00\x04\x00\x00\x00\x00", // REFRESH-INTERVAL + 52, + NULL, + PJ_SUCCESS, + NULL + }, + { + "Attribute between MESSAGE-INTEGRITY and FINGERPRINT is allowed", + "\x00\x01\x00\x28\x21\x12\xa4\x42" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x08\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" // M-I + "\x80\x24\x00\x04\x00\x00\x00\x00" // REFRESH-INTERVAL + "\x80\x28\x00\x04\xc7\xde\xdd\x65", // FINGERPRINT + 60, + NULL, + PJ_SUCCESS, + &verify5 + }, + { + "Attribute past FINGERPRINT is not allowed", + "\x00\x01\x00\x10\x21\x12\xa4\x42" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\x28\x00\x04\x00\x00\x00\x00" + "\x80\x24\x00\x04\x00\x00\x00\x00", + 36, + NULL, + PJNATH_ESTUNFINGERPOS, + NULL + } +}; + +static const char *err(pj_status_t status) +{ + static char errmsg[PJ_ERR_MSG_SIZE]; + pj_strerror(status, errmsg, sizeof(errmsg)); + return errmsg; +} - /* Unknown mandatory attribute type should generate error */ +static const pj_str_t USERNAME = {"user", 4}; +static const pj_str_t PASSWORD = {"password", 8}; - /* Unknown but non-mandatory should be okay */ +static int decode_test(void) +{ + unsigned i; + pj_pool_t *pool; + int rc = 0; + + pool = pj_pool_create(mem, "decode_test", 1024, 1024, NULL); + + PJ_LOG(3,(THIS_FILE, " STUN decode test")); + + for (i=0; i<PJ_ARRAY_SIZE(tests); ++i) { + struct test *t = &tests[i]; + pj_stun_msg *msg, *msg2; + pj_uint8_t buf[1500]; + pj_str_t key; + unsigned len; + pj_status_t status; + + PJ_LOG(3,(THIS_FILE, " %s", t->title)); + + if (t->pdu) { + status = pj_stun_msg_decode(pool, (pj_uint8_t*)t->pdu, t->pdu_len, + PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET, + &msg, NULL, NULL); + + /* Check expected decode result */ + if (t->expected_status != status) { + PJ_LOG(1,(THIS_FILE, " expecting status %d, got %d", + t->expected_status, status)); + rc = -10; + goto on_return; + } + + } else { + msg = t->create(pool); + status = PJ_SUCCESS; + } + + if (status != PJ_SUCCESS) + continue; + + /* Try to encode message */ + pj_stun_create_key(pool, &key, NULL, &USERNAME, &PASSWORD); + status = pj_stun_msg_encode(msg, buf, sizeof(buf), 0, &key, &len); + if (status != PJ_SUCCESS) { + PJ_LOG(1,(THIS_FILE, " encode error: %s", err(status))); + rc = -40; + goto on_return; + } + + /* Try to decode it once more */ + status = pj_stun_msg_decode(pool, buf, len, + PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET, + &msg2, NULL, NULL); + if (status != PJ_SUCCESS) { + PJ_LOG(1,(THIS_FILE, " subsequent decoding failed: %s", err(status))); + rc = -50; + goto on_return; + } + + /* Verify */ + if (t->verify) { + rc = t->verify(msg); + if (rc != 0) { + goto on_return; + } + } + } + +on_return: + pj_pool_release(pool); + if (rc == 0) + PJ_LOG(3,(THIS_FILE, "...success!")); + return rc; +} - /* String/binary attribute length is larger than the message */ +/* Create 420 response */ +static pj_stun_msg* create1(pj_pool_t *pool) +{ + char *pdu = "\x00\x01\x00\x08\x21\x12\xa4\x42" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\xff\x00\x04\x00\x00\x00\x00"; + unsigned pdu_len = 28; + pj_stun_msg *msg, *res; + pj_status_t status; + + status = pj_stun_msg_decode(pool, (pj_uint8_t*)pdu, pdu_len, + PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET, + &msg, NULL, &res); + pj_assert(status != PJ_SUCCESS); + pj_assert(res != NULL); + + return res; +} - /* Valid message with MESSAGE-INTEGRITY */ +/* Error response MUST have ERROR-CODE attribute */ +/* 420 response MUST contain UNKNOWN-ATTRIBUTES */ +static int verify1(pj_stun_msg *msg) +{ + pj_stun_errcode_attr *aerr; + pj_stun_unknown_attr *aunk; + + if (!PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type)) { + PJ_LOG(1,(THIS_FILE, " expecting error message")); + return -100; + } + + aerr = (pj_stun_errcode_attr*) + pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ERROR_CODE, 0); + if (aerr == NULL) { + PJ_LOG(1,(THIS_FILE, " missing ERROR-CODE attribute")); + return -110; + } + + if (aerr->err_code != 420) { + PJ_LOG(1,(THIS_FILE, " expecting 420 error")); + return -120; + } + + aunk = (pj_stun_unknown_attr*) + pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_UNKNOWN_ATTRIBUTES, 0); + if (aunk == NULL) { + PJ_LOG(1,(THIS_FILE, " missing UNKNOWN-ATTRIBUTE attribute")); + return -130; + } + + if (aunk->attr_count != 1) { + PJ_LOG(1,(THIS_FILE, " expecting one unknown attribute")); + return -140; + } + + if (aunk->attrs[0] != 0xff) { + PJ_LOG(1,(THIS_FILE, " expecting 0xff as unknown attribute")); + return -150; + } - /* Valid message with FINGERPRINT */ + return 0; +} - /* Valid message with MESSAGE-INTEGRITY and FINGERPRINT */ +/* Attribute count should be zero since unknown attribute is not parsed */ +static int verify2(pj_stun_msg *msg) +{ + if (msg->attr_count != 0) { + PJ_LOG(1,(THIS_FILE, " expecting zero attribute count")); + return -200; + } + return 0; +} - /* Another attribute not FINGERPRINT exists after MESSAGE-INTEGRITY */ - /* Another attribute exists after FINGERPRINT */ +/* Attribute between MESSAGE-INTEGRITY and FINGERPRINT is allowed */ +static int verify5(pj_stun_msg *msg) +{ + if (msg->attr_count != 3) { + PJ_LOG(1,(THIS_FILE, " expecting 3 attribute count")); + return -500; + } + + if (msg->attr[0]->type != PJ_STUN_ATTR_MESSAGE_INTEGRITY) { + PJ_LOG(1,(THIS_FILE, " expecting MESSAGE-INTEGRITY")); + return -510; + } + if (msg->attr[1]->type != PJ_STUN_ATTR_REFRESH_INTERVAL) { + PJ_LOG(1,(THIS_FILE, " expecting REFRESH-INTERVAL")); + return -520; + } + if (msg->attr[2]->type != PJ_STUN_ATTR_FINGERPRINT) { + PJ_LOG(1,(THIS_FILE, " expecting FINGERPRINT")); + return -530; + } return 0; } + static int decode_verify(void) { /* Decode all attribute types */ @@ -107,12 +457,310 @@ static int auth_test(void) return 0; } +typedef struct test_vector test_vector; + +static pj_stun_msg* create_msgint1(pj_pool_t *pool, test_vector *v); +static pj_stun_msg* create_msgint2(pj_pool_t *pool, test_vector *v); + +enum +{ + USE_MESSAGE_INTEGRITY = 1, + USE_FINGERPRINT = 2 +}; + +struct test_vector +{ + unsigned msg_type; + char *tsx_id; + char *pdu; + unsigned pdu_len; + unsigned options; + char *username; + char *password; + pj_stun_msg* (*create)(pj_pool_t*, test_vector*); +} test_vectors[] = +{ + { + PJ_STUN_BINDING_REQUEST, + "\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae", + "\x00\x01\x00\x44\x21\x12\xa4\x42\xb7\xe7" + "\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" + "\x00\x24\x00\x04\x6e\x00\x01\xff\x80\x29" + "\x00\x08\x93\x2f\xf9\xb1\x51\x26\x3b\x36" + "\x00\x06\x00\x09\x65\x76\x74\x6a\x3a\x68" + "\x36\x76\x59\x20\x20\x20\x00\x08\x00\x14" + "\x62\x4e\xeb\xdc\x3c\xc9\x2d\xd8\x4b\x74" + "\xbf\x85\xd1\xc0\xf5\xde\x36\x87\xbd\x33" + "\x80\x28\x00\x04\xad\x8a\x85\xff", + 88, + USE_MESSAGE_INTEGRITY | USE_FINGERPRINT, + "evtj:h6vY", + "VOkJxbRl1RmTxUk/WvJxBt", + &create_msgint1 + }, + { + PJ_STUN_BINDING_RESPONSE, + "\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae", + "\x01\x01\x00\x3c\x21\x12\xa4\x42\xb7\xe7" + "\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" + "\x80\x22\x00\x0b\x74\x65\x73\x74\x20\x76" + "\x65\x63\x74\x6f\x72\x20\x00\x20\x00\x08" + "\x00\x01\xa1\x47\x5e\x12\xa4\x43\x00\x08" + "\x00\x14\xab\x4e\x53\x29\x61\x00\x08\x4c" + "\x89\xf2\x7c\x69\x30\x33\x5c\xa3\x58\x14" + "\xea\x90\x80\x28\x00\x04\xae\x25\x8d\xf2", + 80, + USE_MESSAGE_INTEGRITY | USE_FINGERPRINT, + "evtj:h6vY", + "VOkJxbRl1RmTxUk/WvJxBt", + &create_msgint2 + } +}; + + +static char* print_binary(const pj_uint8_t *data, unsigned data_len) +{ + static char buf[1500]; + unsigned length = sizeof(buf); + char *p = buf; + unsigned i; + + for (i=0; i<data_len;) { + unsigned j; + + pj_ansi_snprintf(p, 1500-(p-buf), + "%04d-%04d ", + i, (i+20 < data_len) ? i+20 : data_len); + p += 12; + + for (j=0; j<20 && i<data_len && p<(buf+length-10); ++j, ++i) { + pj_ansi_sprintf(p, "%02x ", (*data) & 0xFF); + p += 3; + data++; + } + + pj_ansi_sprintf(p, "\n"); + p++; + } + + return buf; +} + +static int cmp_buf(const pj_uint8_t *s1, const pj_uint8_t *s2, unsigned len) +{ + unsigned i; + for (i=0; i<len; ++i) { + if (s1[i] != s2[i]) + return i; + } + + return -1; +} + +static int fingerprint_test_vector() +{ + pj_pool_t *pool; + pj_status_t status; + unsigned i; + int rc = 0; + + PJ_LOG(3,(THIS_FILE, " STUN message test vectors")); + + pool = pj_pool_create(mem, "fingerprint", 1024, 1024, NULL); + + for (i=0; i<PJ_ARRAY_SIZE(test_vectors); ++i) { + struct test_vector *v; + pj_stun_msg *ref_msg, *msg; + unsigned parsed_len; + unsigned len, pos; + pj_uint8_t buf[1500]; + char print[1500]; + pj_str_t key; + + PJ_LOG(3,(THIS_FILE, " Running test %d/%d", i, + PJ_ARRAY_SIZE(test_vectors))); + + v = &test_vectors[i]; + + /* Print reference message */ + PJ_LOG(4,(THIS_FILE, "Reference message PDU:\n%s", + print_binary((pj_uint8_t*)v->pdu, v->pdu_len))); + + /* Try to parse the reference message first */ + status = pj_stun_msg_decode(pool, (pj_uint8_t*)v->pdu, v->pdu_len, + PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET, + &ref_msg, &parsed_len, NULL); + if (status != PJ_SUCCESS) { + PJ_LOG(1,(THIS_FILE, " Error decoding reference message")); + rc = -1010; + goto on_return; + } + + if (parsed_len != v->pdu_len) { + PJ_LOG(1,(THIS_FILE, " Parsed len error")); + rc = -1020; + goto on_return; + } + + /* Print the reference message */ + pj_stun_msg_dump(ref_msg, print, sizeof(print), NULL); + PJ_LOG(4,(THIS_FILE, "Reference message:\n%s", print)); + + /* Create our message */ + msg = v->create(pool, v); + + /* Encode message */ + if (v->options & USE_MESSAGE_INTEGRITY) { + pj_str_t s1, s2; + + pj_stun_create_key(pool, &key, NULL, pj_cstr(&s1, v->username), + pj_cstr(&s2, v->password)); + pj_stun_msg_encode(msg, buf, sizeof(buf), 0, &key, &len); + + } else { + pj_stun_msg_encode(msg, buf, sizeof(buf), 0, NULL, &len); + } + + /* Print our raw message */ + PJ_LOG(4,(THIS_FILE, "Message PDU:\n%s", + print_binary((pj_uint8_t*)buf, len))); + + /* Print our message */ + pj_stun_msg_dump(msg, print, sizeof(print), NULL); + PJ_LOG(4,(THIS_FILE, "Message is:\n%s", print)); + + /* Compare message length */ + if (len != v->pdu_len) { + PJ_LOG(1,(THIS_FILE, " Message length mismatch")); + rc = -1050; + goto on_return; + } + + pos = cmp_buf(buf, (const pj_uint8_t*)v->pdu, len); + if (pos != -1) { + PJ_LOG(1,(THIS_FILE, " Message mismatch at byte %d", pos)); + rc = -1060; + goto on_return; + } + + /* Authenticate the request/response */ + if (v->options & USE_MESSAGE_INTEGRITY) { + if (PJ_STUN_IS_REQUEST(msg->hdr.type)) { + pj_stun_auth_cred cred; + pj_status_t status; + + pj_bzero(&cred, sizeof(cred)); + cred.type = PJ_STUN_AUTH_CRED_STATIC; + cred.data.static_cred.username = pj_str(v->username); + cred.data.static_cred.data = pj_str(v->password); + + status = pj_stun_authenticate_request(buf, len, msg, + &cred, pool, NULL); + if (status != PJ_SUCCESS) { + char errmsg[PJ_ERR_MSG_SIZE]; + pj_strerror(status, errmsg, sizeof(errmsg)); + PJ_LOG(1,(THIS_FILE, + " Request authentication failed: %s", + errmsg)); + rc = -1070; + goto on_return; + } + + } else if (PJ_STUN_IS_RESPONSE(msg->hdr.type)) { + pj_status_t status; + status = pj_stun_authenticate_response(buf, len, msg, &key); + if (status != PJ_SUCCESS) { + char errmsg[PJ_ERR_MSG_SIZE]; + pj_strerror(status, errmsg, sizeof(errmsg)); + PJ_LOG(1,(THIS_FILE, + " Response authentication failed: %s", + errmsg)); + rc = -1080; + goto on_return; + } + } + } + } + + +on_return: + pj_pool_release(pool); + return rc; +} + +static pj_stun_msg* create_msgint1(pj_pool_t *pool, test_vector *v) +{ + pj_stun_msg *msg; + pj_timestamp u64; + pj_str_t s1; + + pj_stun_msg_create(pool, v->msg_type, PJ_STUN_MAGIC, + (pj_uint8_t*)v->tsx_id, &msg); + + pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_PRIORITY, 0x6e0001ff); + u64.u32.hi = 0x932ff9b1; + u64.u32.lo = 0x51263b36; + pj_stun_msg_add_uint64_attr(pool, msg, PJ_STUN_ATTR_ICE_CONTROLLED, + &u64); + + pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_USERNAME, + pj_cstr(&s1, v->username)); + + pj_stun_msg_add_msgint_attr(pool, msg); + + pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_FINGERPRINT, 0); + + return msg; +} + +static pj_stun_msg* create_msgint2(pj_pool_t *pool, test_vector *v) +{ + pj_stun_msg *msg; + pj_sockaddr_in mapped_addr; + pj_str_t s1; + + pj_stun_msg_create(pool, v->msg_type, PJ_STUN_MAGIC, + (pj_uint8_t*)v->tsx_id, &msg); + + pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_SERVER, + pj_cstr(&s1, "test vector")); + + pj_sockaddr_in_init(&mapped_addr, pj_cstr(&s1, "127.0.0.1"), 32853); + pj_stun_msg_add_sockaddr_attr(pool, msg, PJ_STUN_ATTR_XOR_MAPPED_ADDR, + PJ_TRUE, &mapped_addr, + sizeof(pj_sockaddr_in)); + + pj_stun_msg_add_msgint_attr(pool, msg); + pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_FINGERPRINT, 0); + + return msg; +} + int stun_test(void) { - decode_verify(); - decode_test(); - auth_test(); - return 0; + int pad, rc; + + pad = pj_stun_set_padding_char(32); + + rc = decode_test(); + if (rc != 0) + goto on_return; + + rc = decode_verify(); + if (rc != 0) + goto on_return; + + rc = auth_test(); + if (rc != 0) + goto on_return; + + rc = fingerprint_test_vector(); + if (rc != 0) + goto on_return; + +on_return: + pj_stun_set_padding_char(pad); + return rc; } diff --git a/pjnath/src/pjnath-test/test.c b/pjnath/src/pjnath-test/test.c index b9776539..fc1c124c 100644 --- a/pjnath/src/pjnath-test/test.c +++ b/pjnath/src/pjnath-test/test.c @@ -66,6 +66,10 @@ static int test_inner(void) pjnath_init(); +#if INCLUDE_STUN_TEST + DO_TEST(stun_test()); +#endif + #if INCLUDE_ICE_TEST DO_TEST(ice_test()); #endif diff --git a/pjnath/src/pjnath-test/test.h b/pjnath/src/pjnath-test/test.h index 5663a84e..39ad4112 100644 --- a/pjnath/src/pjnath-test/test.h +++ b/pjnath/src/pjnath-test/test.h @@ -20,8 +20,10 @@ #include <pjlib-util.h> #include <pjnath.h> +#define INCLUDE_STUN_TEST 1 #define INCLUDE_ICE_TEST 1 +extern int stun_test(void); extern int ice_test(void); extern int test_main(void); |