提交 4fa64dd6 authored 作者: Anthony Minessale's avatar Anthony Minessale

a stunning new change

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@1036 d0543943-73ff-0310-b7d9-9358b9ac24b2
上级 13c4c602
......@@ -63,7 +63,8 @@ src/include/switch_sqlite.h\
src/include/switch_types.h\
src/include/switch_utils.h\
src/include/switch_version.h\
src/inclide/switch_rtp.h\
src/include/switch_rtp.h\
src/include/switch_stun.h\
src/switch_rtp.c\
src/switch_buffer.c \
src/switch_caller.c \
......@@ -75,7 +76,8 @@ src/switch_loadable_module.c \
src/switch_utils.c \
src/switch_event.c \
src/switch_resample.c \
src/switch_ivr.c
src/switch_ivr.c \
src/switch_stun.c
......@@ -103,7 +105,8 @@ src/include/switch_sqlite.h\
src/include/switch_types.h\
src/include/switch_utils.h\
src/include/switch_rtp.h\
src/include/switch_version.h
src/include/switch_version.h\
src/include/switch_stun.h
BUILT_SOURCES = version depends
CLEANFILES = src/include/switch_version.h
......
......@@ -83,7 +83,7 @@ am_libfreeswitch_la_OBJECTS = libfreeswitch_la-switch_rtp.lo \
libfreeswitch_la-switch_utils.lo \
libfreeswitch_la-switch_event.lo \
libfreeswitch_la-switch_resample.lo \
libfreeswitch_la-switch_ivr.lo
libfreeswitch_la-switch_ivr.lo libfreeswitch_la-switch_stun.lo
nodist_libfreeswitch_la_OBJECTS =
libfreeswitch_la_OBJECTS = $(am_libfreeswitch_la_OBJECTS) \
$(nodist_libfreeswitch_la_OBJECTS)
......@@ -280,7 +280,8 @@ src/include/switch_sqlite.h\
src/include/switch_types.h\
src/include/switch_utils.h\
src/include/switch_version.h\
src/inclide/switch_rtp.h\
src/include/switch_rtp.h\
src/include/switch_stun.h\
src/switch_rtp.c\
src/switch_buffer.c \
src/switch_caller.c \
......@@ -292,7 +293,8 @@ src/switch_loadable_module.c \
src/switch_utils.c \
src/switch_event.c \
src/switch_resample.c \
src/switch_ivr.c
src/switch_ivr.c \
src/switch_stun.c
#bindir = $(PREFIX)/bin
......@@ -319,7 +321,8 @@ src/include/switch_sqlite.h\
src/include/switch_types.h\
src/include/switch_utils.h\
src/include/switch_rtp.h\
src/include/switch_version.h
src/include/switch_version.h\
src/include/switch_stun.h
BUILT_SOURCES = version depends
CLEANFILES = src/include/switch_version.h
......@@ -469,6 +472,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfreeswitch_la-switch_loadable_module.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfreeswitch_la-switch_resample.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfreeswitch_la-switch_rtp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfreeswitch_la-switch_stun.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfreeswitch_la-switch_utils.Plo@am__quote@
.c.o:
......@@ -576,6 +580,13 @@ libfreeswitch_la-switch_ivr.lo: src/switch_ivr.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfreeswitch_la_CFLAGS) $(CFLAGS) -c -o libfreeswitch_la-switch_ivr.lo `test -f 'src/switch_ivr.c' || echo '$(srcdir)/'`src/switch_ivr.c
libfreeswitch_la-switch_stun.lo: src/switch_stun.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfreeswitch_la_CFLAGS) $(CFLAGS) -MT libfreeswitch_la-switch_stun.lo -MD -MP -MF "$(DEPDIR)/libfreeswitch_la-switch_stun.Tpo" -c -o libfreeswitch_la-switch_stun.lo `test -f 'src/switch_stun.c' || echo '$(srcdir)/'`src/switch_stun.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libfreeswitch_la-switch_stun.Tpo" "$(DEPDIR)/libfreeswitch_la-switch_stun.Plo"; else rm -f "$(DEPDIR)/libfreeswitch_la-switch_stun.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/switch_stun.c' object='libfreeswitch_la-switch_stun.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfreeswitch_la_CFLAGS) $(CFLAGS) -c -o libfreeswitch_la-switch_stun.lo `test -f 'src/switch_stun.c' || echo '$(srcdir)/'`src/switch_stun.c
freeswitch-switch.o: src/switch.c
@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(freeswitch_CFLAGS) $(CFLAGS) -MT freeswitch-switch.o -MD -MP -MF "$(DEPDIR)/freeswitch-switch.Tpo" -c -o freeswitch-switch.o `test -f 'src/switch.c' || echo '$(srcdir)/'`src/switch.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/freeswitch-switch.Tpo" "$(DEPDIR)/freeswitch-switch.Po"; else rm -f "$(DEPDIR)/freeswitch-switch.Tpo"; exit 1; fi
......
差异被折叠。
差异被折叠。
......@@ -18,12 +18,12 @@ AM_CFLAGS += $(shell $(APU_CONFIG) --includes)
AM_LDFLAGS += $(shell $(APU_CONFIG) --link-ld --libs )
lib_LTLIBRARIES = libdingaling.la
libdingaling_la_SOURCES = src/libdingaling.c src/stun_parser.c
libdingaling_la_SOURCES = src/libdingaling.c
libdingaling_la_CFLAGS = $(AM_CFLAGS)
libdingaling_la_LDFLAGS =
library_includedir = $(prefix)/include
library_include_HEADERS = src/libdingaling.h src/stun_parser.h
library_include_HEADERS = src/libdingaling.h
......
......@@ -62,8 +62,7 @@ am__installdirs = "$(DESTDIR)$(libdir)" \
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
libdingaling_la_LIBADD =
am_libdingaling_la_OBJECTS = libdingaling_la-libdingaling.lo \
libdingaling_la-stun_parser.lo
am_libdingaling_la_OBJECTS = libdingaling_la-libdingaling.lo
libdingaling_la_OBJECTS = $(am_libdingaling_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
......@@ -212,11 +211,11 @@ AM_LDFLAGS = -liksemel -L$(PREFIX)/lib $(shell $(APR_CONFIG) --link-ld \
APR_CONFIG = $(prefix)/bin/apr-1-config
APU_CONFIG = $(prefix)/bin/apu-1-config
lib_LTLIBRARIES = libdingaling.la
libdingaling_la_SOURCES = src/libdingaling.c src/stun_parser.c
libdingaling_la_SOURCES = src/libdingaling.c
libdingaling_la_CFLAGS = $(AM_CFLAGS)
libdingaling_la_LDFLAGS =
library_includedir = $(prefix)/include
library_include_HEADERS = src/libdingaling.h src/stun_parser.h
library_include_HEADERS = src/libdingaling.h
all: all-recursive
.SUFFIXES:
......@@ -291,7 +290,6 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdingaling_la-libdingaling.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdingaling_la-stun_parser.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
......@@ -321,13 +319,6 @@ libdingaling_la-libdingaling.lo: src/libdingaling.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdingaling_la_CFLAGS) $(CFLAGS) -c -o libdingaling_la-libdingaling.lo `test -f 'src/libdingaling.c' || echo '$(srcdir)/'`src/libdingaling.c
libdingaling_la-stun_parser.lo: src/stun_parser.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdingaling_la_CFLAGS) $(CFLAGS) -MT libdingaling_la-stun_parser.lo -MD -MP -MF "$(DEPDIR)/libdingaling_la-stun_parser.Tpo" -c -o libdingaling_la-stun_parser.lo `test -f 'src/stun_parser.c' || echo '$(srcdir)/'`src/stun_parser.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdingaling_la-stun_parser.Tpo" "$(DEPDIR)/libdingaling_la-stun_parser.Plo"; else rm -f "$(DEPDIR)/libdingaling_la-stun_parser.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/stun_parser.c' object='libdingaling_la-stun_parser.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdingaling_la_CFLAGS) $(CFLAGS) -c -o libdingaling_la-stun_parser.lo `test -f 'src/stun_parser.c' || echo '$(srcdir)/'`src/stun_parser.c
mostlyclean-libtool:
-rm -f *.lo
......
/*
* libDingaLing XMPP Jingle Library
* Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is libDingaLing XMPP Jingle Library
*
* The Initial Developer of the Original Code is
* Anthony Minessale II <anthmct@yahoo.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Anthony Minessale II <anthmct@yahoo.com>
*
* stun_parser.c STUN packet manipulation
*
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#ifdef WIN32
#include <Winsock2.h>
#else
#include <stdint.h>
#include <netinet/in.h>
#endif
#include "ldl_compat.h"
#include "stun_parser.h"
struct value_mapping {
const uint32_t value;
const char *name;
};
static const struct value_mapping PACKET_TYPES[] = {
{ STUN_BINDING_REQUEST, "BINDING_REQUEST" },
{ STUN_BINDING_RESPONSE, "BINDING_RESPONSE" },
{ STUN_BINDING_ERROR_RESPONSE, "BINDING_ERROR_RESPONSE" },
{ STUN_SHARED_SECRET_REQUEST, "SHARED_SECRET_REQUEST" },
{ STUN_SHARED_SECRET_RESPONSE, "SHARED_SECRET_RESPONSE" },
{ STUN_SHARED_SECRET_ERROR_RESPONSE, "SHARED_SECRET_ERROR_RESPONSE" },
{ STUN_ALLOCATE_REQUEST, "ALLOCATE_REQUEST" },
{ STUN_ALLOCATE_RESPONSE, "ALLOCATE_RESPONSE" },
{ STUN_ALLOCATE_ERROR_RESPONSE, "ALLOCATE_ERROR_RESPONSE" },
{ STUN_SEND_REQUEST, "SEND_REQUEST" },
{ STUN_SEND_RESPONSE, "SEND_RESPONSE" },
{ STUN_SEND_ERROR_RESPONSE, "SEND_ERROR_RESPONSE" },
{ STUN_DATA_INDICATION , "DATA_INDICATION"},
{ 0, 0} };
static const struct value_mapping ATTR_TYPES[] = {
{ STUN_ATTR_MAPPED_ADDRESS, "MAPPED_ADDRESS" },
{ STUN_ATTR_RESPONSE_ADDRESS, "RESPONSE_ADDRESS" },
{ STUN_ATTR_CHANGE_REQUEST, "CHANGE_REQUEST" },
{ STUN_ATTR_SOURCE_ADDRESS, "SOURCE_ADDRESS" },
{ STUN_ATTR_CHANGED_ADDRESS, "CHANGED_ADDRESS" },
{ STUN_ATTR_USERNAME, "USERNAME" },
{ STUN_ATTR_PASSWORD, "PASSWORD" },
{ STUN_ATTR_MESSAGE_INTEGRITY, "MESSAGE_INTEGRITY" },
{ STUN_ATTR_ERROR_CODE, "ERROR_CODE" },
{ STUN_ATTR_UNKNOWN_ATTRIBUTES, "UNKNOWN_ATTRIBUTES" },
{ STUN_ATTR_REFLECTED_FROM, "REFLECTED_FROM" },
{ STUN_ATTR_TRANSPORT_PREFERENCES, "TRANSPORT_PREFERENCES" },
{ STUN_ATTR_LIFETIME, "LIFETIME" },
{ STUN_ATTR_ALTERNATE_SERVER, "ALTERNATE_SERVER" },
{ STUN_ATTR_MAGIC_COOKIE, "MAGIC_COOKIE" },
{ STUN_ATTR_BANDWIDTH, "BANDWIDTH" },
{ STUN_ATTR_DESTINATION_ADDRESS, "DESTINATION_ADDRESS" },
{ STUN_ATTR_SOURCE_ADDRESS2, "SOURCE_ADDRESS2" },
{ STUN_ATTR_DATA, "DATA" },
{ STUN_ATTR_OPTIONS, "OPTIONS" },
{ 0, 0} };
static const struct value_mapping ERROR_TYPES[] = {
{ STUN_ERROR_BAD_REQUEST, "BAD_REQUEST" },
{ STUN_ERROR_UNAUTHORIZED, "UNAUTHORIZED" },
{ STUN_ERROR_UNKNOWN_ATTRIBUTE, "UNKNOWN_ATTRIBUTE" },
{ STUN_ERROR_STALE_CREDENTIALS, "STALE_CREDENTIALS" },
{ STUN_ERROR_INTEGRITY_CHECK_FAILURE, "INTEGRITY_CHECK_FAILURE" },
{ STUN_ERROR_MISSING_USERNAME, "MISSING_USERNAME" },
{ STUN_ERROR_USE_TLS, "USE_TLS" },
{ STUN_ERROR_SERVER_ERROR, "SERVER_ERROR" },
{ STUN_ERROR_GLOBAL_FAILURE, "GLOBAL_FAILURE" },
{ 0, 0 }};
void stun_random_string(char *buf, uint16_t len, char *set)
{
char chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
int max;
uint8_t x;
if (!set) {
set = chars;
}
max = (int)strlen(set) - 1;
for(x = 0; x < len; x++) {
int j = 1+(int)(max*1.0*rand()/(RAND_MAX+1.0));
buf[x] = set[j];
}
}
stun_packet_t *stun_packet_parse(uint8_t *buf, uint32_t len)
{
stun_packet_t *packet;
stun_packet_attribute_t *attr;
if (len < STUN_PACKET_MIN_LEN) {
return NULL;
}
packet = (stun_packet_t *) buf;
packet->header.type = ntohs(packet->header.type);
packet->header.length = ntohs(packet->header.length);
attr = &packet->first_attribute;
stun_packet_first_attribute(packet, attr);
do {
attr->length = ntohs(attr->length);
attr->type = ntohs(attr->type);
if (!attr->length) {
break;
}
switch(attr->type) {
case STUN_ATTR_MAPPED_ADDRESS:
if (attr->type) {
stun_ip_t *ip;
ip = (stun_ip_t *) attr->value;
ip->port = ntohs(ip->port);
}
break;
}
} while (stun_packet_next_attribute(attr));
return packet;
}
const char *stun_value_to_name(int32_t type, int32_t value)
{
uint32_t x = 0;
const struct value_mapping *map = NULL;
switch (type) {
case STUN_TYPE_PACKET_TYPE:
map = PACKET_TYPES;
break;
case STUN_TYPE_ATTRIBUTE:
map = ATTR_TYPES;
break;
case STUN_TYPE_ERROR:
map = ERROR_TYPES;
break;
default:
map = NULL;
break;
}
if (map) {
for(x = 0; map[x].value; x++) {
if (map[x].value == value) {
return map[x].name;
}
}
}
return "INVALID";
}
uint8_t stun_packet_attribute_get_mapped_address(stun_packet_attribute_t *attribute, char *ipstr, uint16_t *port)
{
stun_ip_t *ip;
uint8_t x, *i;
char *p = ipstr;
ip = (stun_ip_t *) attribute->value;
i = (uint8_t *) &ip->address;
*ipstr = 0;
for(x =0; x < 4; x++) {
sprintf(p, "%u%s", i[x], x == 3 ? "" : ".");
p = ipstr + strlen(ipstr);
}
*port = ip->port;
return 1;
}
char *stun_packet_attribute_get_username(stun_packet_attribute_t *attribute, char *username, uint16_t len)
{
uint16_t cpylen;
cpylen = attribute->length > len ? attribute->length : len;
return memcpy(username, attribute->value, cpylen);
}
stun_packet_t *stun_packet_build_header(stun_message_t type,
char *id,
uint8_t *buf
)
{
stun_packet_header_t *header;
header = (stun_packet_header_t *) buf;
header->type = htons(type);
header->length = 0;
if (id) {
memcpy(header->id, id, 16);
} else {
stun_random_string(header->id, 16, NULL);
}
return (stun_packet_t *) buf;
}
uint8_t stun_packet_attribute_add_binded_address(stun_packet_t *packet, char *ipstr, uint16_t port)
{
stun_packet_attribute_t *attribute;
stun_ip_t *ip;
uint8_t *i, x;
char *p = ipstr;
attribute = (stun_packet_attribute_t *) ((uint8_t *) &packet->first_attribute + ntohs(packet->header.length));
attribute->type = htons(STUN_ATTR_MAPPED_ADDRESS);
attribute->length = htons(8);
ip = (stun_ip_t *) attribute->value;
ip->port = htons(port);
ip->family = 1;
i = (uint8_t *) &ip->address;
for(x = 0; x < 4 ; x++) {
i[x] = atoi(p);
if ((p = strchr(p, '.'))) {
p++;
} else {
break;
}
}
packet->header.length += htons(sizeof(stun_packet_attribute_t)) + attribute->length;
return 1;
}
uint8_t stun_packet_attribute_add_username(stun_packet_t *packet, char *username, uint16_t ulen)
{
stun_packet_attribute_t *attribute;
if (ulen % 4 != 0) {
return 0;
}
attribute = (stun_packet_attribute_t *) ((uint8_t *) &packet->first_attribute + ntohs(packet->header.length));
attribute->type = htons(STUN_ATTR_USERNAME);
attribute->length = htons(ulen);
if (username) {
memcpy(attribute->value, username, ulen);
} else {
stun_random_string(attribute->value, ulen, NULL);
}
packet->header.length += htons(sizeof(stun_packet_attribute_t)) + attribute->length;
return 1;
}
/*
* libDingaLing XMPP Jingle Library
* Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is libDingaLing XMPP Jingle Library
*
* The Initial Developer of the Original Code is
* Anthony Minessale II <anthmct@yahoo.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Anthony Minessale II <anthmct@yahoo.com>
*
* stun_parser.h STUN packet manipulation
*
*/
/*! \file stun_parser.h
\brief STUN packet manipulation
*/
/*!
\defgroup stun1 libDingaLing Stun Parser
\ingroup LIBDINGALING
\{
*/
#ifndef _STUN_PARSER_H
#define _STUN_PARSER_H
#define STUN_PACKET_MIN_LEN 20
typedef enum {
STUN_BINDING_REQUEST = 0x0001,
STUN_BINDING_RESPONSE = 0x0101,
STUN_BINDING_ERROR_RESPONSE = 0x0111,
STUN_SHARED_SECRET_REQUEST = 0x0002,
STUN_SHARED_SECRET_RESPONSE = 0x0102,
STUN_SHARED_SECRET_ERROR_RESPONSE = 0x0112,
STUN_ALLOCATE_REQUEST = 0x0003,
STUN_ALLOCATE_RESPONSE = 0x0103,
STUN_ALLOCATE_ERROR_RESPONSE = 0x0113,
STUN_SEND_REQUEST = 0x0004,
STUN_SEND_RESPONSE = 0x0104,
STUN_SEND_ERROR_RESPONSE = 0x0114,
STUN_DATA_INDICATION = 0x0115
} stun_message_t;
typedef enum {
STUN_ATTR_MAPPED_ADDRESS = 0x0001, /* Address */
STUN_ATTR_RESPONSE_ADDRESS = 0x0002, /* Address */
STUN_ATTR_CHANGE_REQUEST = 0x0003, /* UInt32 */
STUN_ATTR_SOURCE_ADDRESS = 0x0004, /* Address */
STUN_ATTR_CHANGED_ADDRESS = 0x0005, /* Address */
STUN_ATTR_USERNAME = 0x0006, /* ByteString, multiple of 4 bytes */
STUN_ATTR_PASSWORD = 0x0007, /* ByteString, multiple of 4 bytes */
STUN_ATTR_MESSAGE_INTEGRITY = 0x0008, /* ByteString, 20 bytes */
STUN_ATTR_ERROR_CODE = 0x0009, /* ErrorCode */
STUN_ATTR_UNKNOWN_ATTRIBUTES = 0x000a, /* UInt16List */
STUN_ATTR_REFLECTED_FROM = 0x000b, /* Address */
STUN_ATTR_TRANSPORT_PREFERENCES = 0x000c, /* TransportPrefs */
STUN_ATTR_LIFETIME = 0x000d, /* UInt32 */
STUN_ATTR_ALTERNATE_SERVER = 0x000e, /* Address */
STUN_ATTR_MAGIC_COOKIE = 0x000f, /* ByteString, 4 bytes */
STUN_ATTR_BANDWIDTH = 0x0010, /* UInt32 */
STUN_ATTR_DESTINATION_ADDRESS = 0x0011, /* Address */
STUN_ATTR_SOURCE_ADDRESS2 = 0x0012, /* Address */
STUN_ATTR_DATA = 0x0013, /* ByteString */
STUN_ATTR_OPTIONS = 0x8001 /* UInt32 */
} stun_attribute_t;
typedef enum {
STUN_ERROR_BAD_REQUEST = 400,
STUN_ERROR_UNAUTHORIZED = 401,
STUN_ERROR_UNKNOWN_ATTRIBUTE = 420,
STUN_ERROR_STALE_CREDENTIALS = 430,
STUN_ERROR_INTEGRITY_CHECK_FAILURE = 431,
STUN_ERROR_MISSING_USERNAME = 432,
STUN_ERROR_USE_TLS = 433,
STUN_ERROR_SERVER_ERROR = 500,
STUN_ERROR_GLOBAL_FAILURE = 600
} stun_error_t;
typedef enum {
STUN_TYPE_PACKET_TYPE,
STUN_TYPE_ATTRIBUTE,
STUN_TYPE_ERROR
} stun_type_t;
typedef struct {
int16_t type;
int16_t length;
char id[16];
} stun_packet_header_t;
typedef struct {
int16_t type;
uint16_t length;
char value[0];
} stun_packet_attribute_t;
typedef struct {
stun_packet_header_t header;
stun_packet_attribute_t first_attribute;
} stun_packet_t;
typedef struct {
int8_t wasted;
int8_t family;
int16_t port;
int32_t address;
} stun_ip_t;
/*!
\brief Writes random characters into a buffer
\param buf the buffer
\param len the length of the data
\param set the set of chars to use (NULL for auto)
*/
void stun_random_string(char *buf, uint16_t len, char *set);
/*!
\brief Prepare a raw packet for parsing
\param buf the raw data
\param len the length of the data
\return a stun packet pointer to buf to use as an access point
*/
stun_packet_t *stun_packet_parse(uint8_t *buf, uint32_t len);
/*!
\brief Obtain a printable string form of a given value
\param type the type of message
\param value the value to look up
\return a sring version of value
*/
const char *stun_value_to_name(int32_t type, int32_t value);
/*!
\brief Extract a mapped address (IP:PORT) from a packet attribute
\param attribute the attribute from which to extract
\param ipstr a buffer to write the string representation of the ip
\param port the port
\return true or false
*/
uint8_t stun_packet_attribute_get_mapped_address(stun_packet_attribute_t *attribute, char *ipstr, uint16_t *port);
/*!
\brief Extract a username from a packet attribute
\param attribute the attribute from which to extract
\param username a buffer to write the string representation of the username
\param len the maximum size of the username buffer
\return a pointer to the username or NULL
*/
char *stun_packet_attribute_get_username(stun_packet_attribute_t *attribute, char *username, uint16_t len);
/*!
\brief Prepare a new outbound packet of a certian type and id
\param id id to use (NULL for an auto generated id)
\param type the stun packet type
\param buf a pointer to data to use for the packet
\return a pointer to a ready-to-use stun packet
*/
stun_packet_t *stun_packet_build_header(stun_message_t type,
char *id,
uint8_t *buf
);
/*!
\brief Add a username packet attribute
\param packet the packet to add the attribute to
\param username the string representation of the username
\param ulen the length of the username
\return true or false
*/
uint8_t stun_packet_attribute_add_username(stun_packet_t *packet, char *username, uint16_t ulen);
/*!
\brief Add a binded address packet attribute
\param packet the packet to add the attribute to
\param ipstr the string representation of the ip
\param port the port of the mapped address
\return true or false
*/
uint8_t stun_packet_attribute_add_binded_address(stun_packet_t *packet, char *ipstr, uint16_t port);
/*!
\brief set a stun_packet_attribute_t pointer to point at the first attribute in a packet
\param packet the packet in question
\param attribute the pointer to set up
*/
#define stun_packet_first_attribute(packet, attribute) attribute = &packet->first_attribute;
/*!
\brief Increment an attribute pointer to the next attribute in it's packet
\param attribute the pointer to increment
\return true or false depending on if there are any more attributes
*/
#define stun_packet_next_attribute(attribute) (attribute = (stun_packet_attribute_t *) (attribute->value + attribute->length)) && attribute->length
/*!
\brief Obtain the correct length in bytes of a stun packet
\param packet the packet in question
\return the size in bytes (host order) of the entire packet
*/
#define stun_packet_length(packet) ntohs(packet->header.length) + sizeof(stun_packet_header_t)
///\}
#endif
......@@ -66,6 +66,7 @@ extern "C" {
#include <switch_resample.h>
#include <switch_ivr.h>
#include <switch_rtp.h>
#include <switch_stun.h>
#ifdef __cplusplus
}
#endif
......
......@@ -31,14 +31,6 @@
*/
#include <switch.h>
#include <libdingaling.h>
#include <stun_parser.h>
#ifdef _MSC_VER
#include <Winsock2.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
static const char modname[] = "mod_dingaling";
......@@ -103,7 +95,7 @@ struct private_object {
struct switch_frame read_frame;
struct switch_frame cng_frame;
struct mdl_profile *profile;
switch_sockaddr_t *stun_addr;
switch_sockaddr_t *switch_stun_addr;
unsigned char read_buf[SWITCH_RECCOMMENDED_BUFFER_SIZE];
unsigned char cng_buf[SWITCH_RECCOMMENDED_BUFFER_SIZE];
switch_core_session *session;
......@@ -177,7 +169,7 @@ static switch_status channel_write_frame(switch_core_session *session, switch_fr
static switch_status channel_kill_channel(switch_core_session *session, int sig);
static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsession, ldl_signal_t signal, char *msg);
static ldl_status handle_response(ldl_handle_t *handle, char *id);
static void stun_callback(struct switch_rtp *switch_rtp, switch_socket_t *sock, void *data, switch_size_t len, switch_sockaddr_t *from_addr);
static void switch_stun_callback(struct switch_rtp *switch_rtp, switch_socket_t *sock, void *data, switch_size_t len, switch_sockaddr_t *from_addr);
static switch_status load_config(void);
......@@ -293,7 +285,7 @@ static void *SWITCH_THREAD_FUNC negotiate_thread_run(switch_thread *thread, void
ldl_candidate_t cand[1];
char *advip = tech_pvt->profile->extip ? tech_pvt->profile->extip : tech_pvt->profile->ip;
memset(cand, 0, sizeof(cand));
stun_random_string(tech_pvt->local_user, 16, NULL);
switch_stun_random_string(tech_pvt->local_user, 16, NULL);
cand[0].name = "rtp";
cand[0].address = advip;
......@@ -703,7 +695,7 @@ static switch_status channel_write_frame(switch_core_session *session, switch_fr
if (tech_pvt->stuncount == 0) {
uint8_t buf[256] = {0};
char login[80];
stun_packet_t *packet;
switch_stun_packet_t *packet;
//struct sockaddr_in servaddr;
unsigned int elapsed;
switch_size_t bytes;
......@@ -718,12 +710,12 @@ static switch_status channel_write_frame(switch_core_session *session, switch_fr
}
snprintf(login, sizeof(login), "%s%s", tech_pvt->remote_user, tech_pvt->local_user);
packet = stun_packet_build_header(STUN_BINDING_REQUEST, NULL, buf);
stun_packet_attribute_add_username(packet, login, 32);
bytes = stun_packet_length(packet);
switch_socket_sendto(tech_pvt->rtp_sock, tech_pvt->stun_addr, 0, (void *)packet, &bytes);
packet = switch_stun_packet_build_header(SWITCH_STUN_BINDING_REQUEST, NULL, buf);
switch_stun_packet_attribute_add_username(packet, login, 32);
bytes = switch_stun_packet_length(packet);
switch_socket_sendto(tech_pvt->rtp_sock, tech_pvt->switch_stun_addr, 0, (void *)packet, &bytes);
//sendto(tech_pvt->rtp_sock, (char *)packet, stun_packet_length(packet), 0 ,(struct sockaddr *)&servaddr, sizeof(servaddr));
//sendto(tech_pvt->rtp_sock, (char *)packet, switch_stun_packet_length(packet), 0 ,(struct sockaddr *)&servaddr, sizeof(servaddr));
//xstun
//printf("XXXX SEND STUN REQ %s U=%s to %s:%d\n", packet->header.id, login, tech_pvt->remote_ip, tech_pvt->remote_port);
tech_pvt->stuncount = 25;
......@@ -957,7 +949,7 @@ static switch_status channel_outgoing_channel(switch_core_session *session, swit
switch_channel_set_flag(channel, CF_OUTBOUND);
switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
stun_random_string(sess_id, 10, "0123456789");
switch_stun_random_string(sess_id, 10, "0123456789");
ldl_session_create(&dlsession, mdl_profile->handle, sess_id, full_id, mdl_profile->login);
tech_pvt->profile = mdl_profile;
......@@ -1305,7 +1297,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
tech_pvt->remote_port = candidates[x].port;
tech_pvt->remote_user = switch_core_session_strdup(session, candidates[x].username);
if (switch_sockaddr_info_get(&tech_pvt->stun_addr,
if (switch_sockaddr_info_get(&tech_pvt->switch_stun_addr,
tech_pvt->remote_ip,
SWITCH_UNSPEC,
tech_pvt->remote_port,
......@@ -1332,7 +1324,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
}
memset(cand, 0, sizeof(cand));
stun_random_string(tech_pvt->local_user, 16, NULL);
switch_stun_random_string(tech_pvt->local_user, 16, NULL);
cand[0].name = "rtp";
cand[0].address = advip;
......@@ -1362,7 +1354,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
return LDL_STATUS_FALSE;
}
tech_pvt->rtp_sock = switch_rtp_get_rtp_socket(tech_pvt->rtp_session);
switch_rtp_set_invald_handler(tech_pvt->rtp_session, stun_callback);
switch_rtp_set_invald_handler(tech_pvt->rtp_session, switch_stun_callback);
switch_rtp_set_private(tech_pvt->rtp_session, tech_pvt);
switch_set_flag(tech_pvt, TFLAG_RTP_READY);
switch_rtp_start(tech_pvt->rtp_session);
......@@ -1402,10 +1394,10 @@ static ldl_status handle_response(ldl_handle_t *handle, char *id)
return LDL_STATUS_SUCCESS;
}
static void stun_callback(struct switch_rtp *switch_rtp, switch_socket_t *sock, void *data, switch_size_t len, switch_sockaddr_t *from_addr)
static void switch_stun_callback(struct switch_rtp *switch_rtp, switch_socket_t *sock, void *data, switch_size_t len, switch_sockaddr_t *from_addr)
{
stun_packet_t *packet;
stun_packet_attribute_t *attr;
switch_stun_packet_t *packet;
switch_stun_packet_attribute_t *attr;
char username[33] = {0};
struct private_object *tech_pvt;
unsigned char buf[512] = {0};
......@@ -1414,59 +1406,59 @@ static void stun_callback(struct switch_rtp *switch_rtp, switch_socket_t *sock,
assert(tech_pvt != NULL);
memcpy(buf, data, len);
packet = stun_packet_parse(buf, sizeof(buf));
packet = switch_stun_packet_parse(buf, sizeof(buf));
tech_pvt->last_stun = switch_time_now();
#if 0
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "read %d\ntype: [%s] (0x%04x)\nlength 0x%04x\nid %s\n",
len,
stun_value_to_name(STUN_TYPE_PACKET_TYPE, packet->header.type),
switch_stun_value_to_name(SWITCH_STUN_TYPE_PACKET_TYPE, packet->header.type),
packet->header.type,
packet->header.length,
packet->header.id);
#endif
stun_packet_first_attribute(packet, attr);
switch_stun_packet_first_attribute(packet, attr);
do {
//switch_console_printf(SWITCH_CHANNEL_CONSOLE, "ATTRIBUTE [%s] (0x%04x) [%04x bytes]\n", stun_value_to_name(STUN_TYPE_ATTRIBUTE, attr->type), attr->type, attr->length);
//switch_console_printf(SWITCH_CHANNEL_CONSOLE, "ATTRIBUTE [%s] (0x%04x) [%04x bytes]\n", switch_stun_value_to_name(SWITCH_STUN_TYPE_ATTRIBUTE, attr->type), attr->type, attr->length);
switch(attr->type) {
case STUN_ATTR_MAPPED_ADDRESS:
case SWITCH_STUN_ATTR_MAPPED_ADDRESS:
if (attr->type) {
char ip[16];
uint16_t port;
stun_packet_attribute_get_mapped_address(attr, ip, &port);
switch_stun_packet_attribute_get_mapped_address(attr, ip, &port);
//switch_console_printf(SWITCH_CHANNEL_CONSOLE, "IP/PORT: %s:%d\n", ip, port);
}
break;
case STUN_ATTR_USERNAME:
case SWITCH_STUN_ATTR_USERNAME:
if(attr->type) {
if (stun_packet_attribute_get_username(attr, username, 32)) {
if (switch_stun_packet_attribute_get_username(attr, username, 32)) {
//switch_console_printf(SWITCH_CHANNEL_CONSOLE, "USERNAME: %s\n", username);
}
}
break;
}
} while (stun_packet_next_attribute(attr));
} while (switch_stun_packet_next_attribute(attr));
if (packet->header.type == STUN_BINDING_REQUEST && strstr(username,tech_pvt->remote_user)) {
if (packet->header.type == SWITCH_STUN_BINDING_REQUEST && strstr(username,tech_pvt->remote_user)) {
uint8_t buf[512];
stun_packet_t *rpacket;
switch_stun_packet_t *rpacket;
char *remote_ip;
switch_size_t bytes;
memset(buf, 0, sizeof(buf));
rpacket = stun_packet_build_header(STUN_BINDING_RESPONSE, packet->header.id, buf);
stun_packet_attribute_add_username(rpacket, username, 32);
rpacket = switch_stun_packet_build_header(SWITCH_STUN_BINDING_RESPONSE, packet->header.id, buf);
switch_stun_packet_attribute_add_username(rpacket, username, 32);
switch_sockaddr_ip_get(&remote_ip, from_addr);
stun_packet_attribute_add_binded_address(rpacket, remote_ip, from_addr->port);
switch_stun_packet_attribute_add_binded_address(rpacket, remote_ip, from_addr->port);
//xstun
//switch_console_printf(SWITCH_CHANNEL_CONSOLE, "RESPONSE TO BIND %s:%d [%s]\n", remote_ip, port, username);
//sendto(sock, (char *)rpacket, stun_packet_length(rpacket), 0 ,(struct sockaddr *)&servaddr, sizeof(servaddr));
bytes = stun_packet_length(rpacket);
//sendto(sock, (char *)rpacket, switch_stun_packet_length(rpacket), 0 ,(struct sockaddr *)&servaddr, sizeof(servaddr));
bytes = switch_stun_packet_length(rpacket);
switch_socket_sendto(tech_pvt->rtp_sock, from_addr, 0, (void*)rpacket, &bytes);
//switch_set_flag(tech_pvt, TFLAG_IO);
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论