diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..0f20387 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,29 @@ +name: Lint + +on: + push: + branches: [ $default-branch ] + pull_request: + types: [ opened, reopened, synchronize ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + libevent-dev \ + libssl-dev \ + libpq-dev libmariadb-dev libsqlite3-dev \ + libhiredis-dev \ + libmongoc-dev \ + libmicrohttpd-dev \ + clang-format + - uses: actions/checkout@v3 + - name: configure + run: ./configure + - name: lint + run: clang-format --version && make lint diff --git a/Makefile.in b/Makefile.in index b869d0e..88570e4 100755 --- a/Makefile.in +++ b/Makefile.in @@ -45,6 +45,12 @@ test: check check: bin/turnutils_rfc5769check bin/turnutils_rfc5769check +format: + find . -iname "*.c" -o -iname "*.h" | xargs clang-format -i + +lint: + find . -iname "*.c" -o -iname "*.h" | xargs clang-format --dry-run -Werror + include/turn/ns_turn_defs.h: src/ns_turn_defs.h ${RMCMD} include ${MKBUILDDIR} include/turn/client diff --git a/fuzzing/FuzzStun.c b/fuzzing/FuzzStun.c index 37247e2..28ef0f2 100644 --- a/fuzzing/FuzzStun.c +++ b/fuzzing/FuzzStun.c @@ -1,9 +1,9 @@ -#include #include +#include #include -#include "ns_turn_utils.h" #include "apputils.h" +#include "ns_turn_utils.h" #include "stun_buffer.h" static SHATYPE shatype = SHATYPE_SHA1; @@ -11,18 +11,20 @@ static SHATYPE shatype = SHATYPE_SHA1; #define kMinInputLength 10 #define kMaxInputLength 5120 -extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {//rfc5769check +extern int LLVMFuzzerTestOneInput(const uint8_t *Data, + size_t Size) { // rfc5769check - if (Size < kMinInputLength || Size > kMaxInputLength){ - return 1; - } + if (Size < kMinInputLength || Size > kMaxInputLength) { + return 1; + } - stun_is_command_message_full_check_str((uint8_t *)Data, Size, 1, NULL); + stun_is_command_message_full_check_str((uint8_t *)Data, Size, 1, NULL); - uint8_t uname[33]; - uint8_t realm[33]; - uint8_t upwd[33]; - strcpy((char*) upwd, "VOkJxbRl1RmTxUk/WvJxBt"); - stun_check_message_integrity_str(TURN_CREDENTIALS_SHORT_TERM,(uint8_t *)Data, Size, uname, realm, upwd, shatype); - return 0; + uint8_t uname[33]; + uint8_t realm[33]; + uint8_t upwd[33]; + strcpy((char *)upwd, "VOkJxbRl1RmTxUk/WvJxBt"); + stun_check_message_integrity_str(TURN_CREDENTIALS_SHORT_TERM, (uint8_t *)Data, + Size, uname, realm, upwd, shatype); + return 0; } diff --git a/fuzzing/FuzzStunClient.c b/fuzzing/FuzzStunClient.c index 88fefba..6d36530 100644 --- a/fuzzing/FuzzStunClient.c +++ b/fuzzing/FuzzStunClient.c @@ -1,34 +1,35 @@ -#include #include +#include #include -#include "ns_turn_utils.h" #include "apputils.h" +#include "ns_turn_utils.h" #include "stun_buffer.h" #define kMinInputLength 10 #define kMaxInputLength 5120 -extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {//stunclient.c - - if (Size < kMinInputLength || Size > kMaxInputLength){ - return 1; - } - - stun_buffer buf; - - buf.len = Size; - memcpy(buf.buf,Data,buf.len); - - if(stun_is_command_message(&buf)){ - if(stun_is_response(&buf)){ - if(stun_is_success_response(&buf)){ - if(stun_is_binding_response(&buf)){ - return 0; - } - } - } - } +extern int LLVMFuzzerTestOneInput(const uint8_t *Data, + size_t Size) { // stunclient.c + if (Size < kMinInputLength || Size > kMaxInputLength) { return 1; + } + + stun_buffer buf; + + buf.len = Size; + memcpy(buf.buf, Data, buf.len); + + if (stun_is_command_message(&buf)) { + if (stun_is_response(&buf)) { + if (stun_is_success_response(&buf)) { + if (stun_is_binding_response(&buf)) { + return 0; + } + } + } + } + + return 1; } diff --git a/src/.clang-format b/src/.clang-format new file mode 100644 index 0000000..b0e04cc --- /dev/null +++ b/src/.clang-format @@ -0,0 +1,137 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: false +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 120 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + - Regex: '.*' + Priority: 1 + SortPriority: 0 +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentWidth: 2 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +Standard: Latest +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseCRLF: false +UseTab: Never +... + diff --git a/src/apps/common/apputils.c b/src/apps/common/apputils.c index 1a2ee43..f013286 100644 --- a/src/apps/common/apputils.c +++ b/src/apps/common/apputils.c @@ -28,46 +28,45 @@ * SUCH DAMAGE. */ -#include "ns_turn_utils.h" #include "ns_turn_msg.h" +#include "ns_turn_utils.h" #include "apputils.h" #include #if defined(__unix__) || defined(unix) || defined(__APPLE__) - #include - #include - #include +#include +#include +#include #endif #if defined(__unix__) || defined(unix) - #include - #include - #include - #include +#include +#include +#include +#include #endif #if defined(WINDOWS) - #include +#include #endif #if defined(_MSC_VER) - #include +#include #else - #include +#include #endif -#include #include +#include #include #include +#include #include #include -#include #include - #if !defined(TURN_NO_SCTP) && defined(TURN_SCTP_INCLUDE) #include TURN_SCTP_INCLUDE #endif @@ -78,481 +77,469 @@ int IS_TURN_SERVER = 0; /*********************** Sockets *********************************/ -int socket_set_nonblocking(evutil_socket_t fd) -{ +int socket_set_nonblocking(evutil_socket_t fd) { #if defined(WINDOWS) - unsigned long nonblocking = 1; - ioctlsocket(fd, FIONBIO, (unsigned long*) &nonblocking); + unsigned long nonblocking = 1; + ioctlsocket(fd, FIONBIO, (unsigned long *)&nonblocking); #else - if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { - perror("O_NONBLOCK"); - return -1; + if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { + perror("O_NONBLOCK"); + return -1; + } +#endif + return 0; +} + +void read_spare_buffer(evutil_socket_t fd) { + if (fd >= 0) { + static char buffer[65536]; +#if defined(WINDOWS) + // TODO: add set no-block? by Kang Lin + recv(fd, buffer, sizeof(buffer), 0); +#else + recv(fd, buffer, sizeof(buffer), MSG_DONTWAIT); +#endif + } +} + +int set_sock_buf_size(evutil_socket_t fd, int sz0) { + int sz; + + sz = sz0; + while (sz > 0) { + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const void *)(&sz), (socklen_t)sizeof(sz)) < 0) { + sz = sz / 2; + } else { + break; } -#endif - return 0; + } + + if (sz < 1) { + perror("Cannot set socket rcv size"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Cannot set rcv sock size %d on fd %d\n", sz0, fd); + } + + sz = sz0; + while (sz > 0) { + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *)(&sz), (socklen_t)sizeof(sz)) < 0) { + sz = sz / 2; + } else { + break; + } + } + + if (sz < 1) { + perror("Cannot set socket snd size"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Cannot set snd sock size %d on fd %d\n", sz0, fd); + } + + return 0; } -void read_spare_buffer(evutil_socket_t fd) -{ - if(fd >= 0) { - static char buffer[65536]; +int socket_init(void) { #if defined(WINDOWS) - //TODO: add set no-block? by Kang Lin - recv(fd, buffer, sizeof(buffer), 0); -#else - recv(fd, buffer, sizeof(buffer), MSG_DONTWAIT); + { + WORD wVersionRequested; + WSADATA wsaData; + int e; + + /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ + wVersionRequested = MAKEWORD(2, 2); + + e = WSAStartup(wVersionRequested, &wsaData); + if (e != 0) { + /* Tell the user that we could not find a usable */ + /* Winsock DLL. */ + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "WSAStartup failed with error: %d\n", e); + return 1; + } + } #endif - } + return 0; } -int set_sock_buf_size(evutil_socket_t fd, int sz0) -{ - int sz; - - sz = sz0; - while (sz > 0) { - if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const void*) (&sz), (socklen_t) sizeof(sz)) < 0) { - sz = sz / 2; - } else { - break; - } - } - - if (sz < 1) { - perror("Cannot set socket rcv size"); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Cannot set rcv sock size %d on fd %d\n", sz0, fd); - } - - sz = sz0; - while (sz > 0) { - if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void*) (&sz), (socklen_t) sizeof(sz)) < 0) { - sz = sz / 2; - } else { - break; - } - } - - if (sz < 1) { - perror("Cannot set socket snd size"); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Cannot set snd sock size %d on fd %d\n", sz0, fd); - } - - return 0; -} - -int socket_init(void) -{ -#if defined(WINDOWS) - { - WORD wVersionRequested; - WSADATA wsaData; - int e; - - /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ - wVersionRequested = MAKEWORD(2, 2); - - e = WSAStartup(wVersionRequested, &wsaData); - if (e != 0) { - /* Tell the user that we could not find a usable */ - /* Winsock DLL. */ - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "WSAStartup failed with error: %d\n", e); - return 1; - } - } -#endif - return 0; -} - -int socket_tcp_set_keepalive(evutil_socket_t fd,SOCKET_TYPE st) -{ - UNUSED_ARG(st); +int socket_tcp_set_keepalive(evutil_socket_t fd, SOCKET_TYPE st) { + UNUSED_ARG(st); #ifdef SO_KEEPALIVE - /* Set the keepalive option active */ - { - int on = 1; - setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (const void*)&on, (socklen_t) sizeof(on)); - } + /* Set the keepalive option active */ + { + int on = 1; + setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (const void *)&on, (socklen_t)sizeof(on)); + } #else - UNUSED_ARG(fd); + UNUSED_ARG(fd); #endif #ifdef SO_NOSIGPIPE - { - int on = 1; - setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (const void*)&on, (socklen_t) sizeof(on)); - } + { + int on = 1; + setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (const void *)&on, (socklen_t)sizeof(on)); + } #endif - return 0; + return 0; } -int socket_set_reusable(evutil_socket_t fd, int flag, SOCKET_TYPE st) -{ - UNUSED_ARG(st); +int socket_set_reusable(evutil_socket_t fd, int flag, SOCKET_TYPE st) { + UNUSED_ARG(st); - if (fd < 0) - return -1; - else { + if (fd < 0) + return -1; + else { #if defined(WINDOWS) - int use_reuseaddr = IS_TURN_SERVER; + int use_reuseaddr = IS_TURN_SERVER; #else - int use_reuseaddr = 1; + int use_reuseaddr = 1; #endif #if defined(SO_REUSEADDR) - if (use_reuseaddr) { - int on = flag; - int ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void*) &on, (socklen_t) sizeof(on)); - if (ret < 0) - perror("SO_REUSEADDR"); - } + if (use_reuseaddr) { + int on = flag; + int ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, (socklen_t)sizeof(on)); + if (ret < 0) + perror("SO_REUSEADDR"); + } #endif #if !defined(TURN_NO_SCTP) #if defined(SCTP_REUSE_PORT) - if (use_reuseaddr) { - if(is_sctp_socket(st)) { - int on = flag; - int ret = setsockopt(fd, IPPROTO_SCTP, SCTP_REUSE_PORT, (const void*) &on, (socklen_t) sizeof(on)); - if (ret < 0) - perror("SCTP_REUSE_PORT"); - } - } + if (use_reuseaddr) { + if (is_sctp_socket(st)) { + int on = flag; + int ret = setsockopt(fd, IPPROTO_SCTP, SCTP_REUSE_PORT, (const void *)&on, (socklen_t)sizeof(on)); + if (ret < 0) + perror("SCTP_REUSE_PORT"); + } + } #endif #endif #if defined(SO_REUSEPORT) - if (use_reuseaddr) { - int on = flag; - setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (const void*) &on, (socklen_t) sizeof(on)); - } + if (use_reuseaddr) { + int on = flag; + setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (const void *)&on, (socklen_t)sizeof(on)); + } #endif - return 0; - } + return 0; + } } -int sock_bind_to_device(evutil_socket_t fd, const unsigned char* ifname) { +int sock_bind_to_device(evutil_socket_t fd, const unsigned char *ifname) { - if (fd >= 0 && ifname && ifname[0]) { + if (fd >= 0 && ifname && ifname[0]) { #if defined(SO_BINDTODEVICE) - struct ifreq ifr; - memset(&ifr, 0, sizeof(ifr)); + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, (const char*) ifname, sizeof(ifr.ifr_name)); + strncpy(ifr.ifr_name, (const char *)ifname, sizeof(ifr.ifr_name)); - if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (void *) &ifr, sizeof(ifr)) < 0) { - if (errno == EPERM) - perror("You must obtain superuser privileges to bind a socket to device"); - else - perror("Cannot bind socket to device"); + if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0) { + if (errno == EPERM) + perror("You must obtain superuser privileges to bind a socket to device"); + else + perror("Cannot bind socket to device"); - return -1; - } + return -1; + } - return 0; + return 0; #endif + } - } - - return 0; + return 0; } -int addr_connect(evutil_socket_t fd, const ioa_addr* addr, int *out_errno) -{ - if (!addr || fd < 0) - return -1; - else { - int err = 0; - do { - if (addr->ss.sa_family == AF_INET) { - err = connect(fd, (const struct sockaddr *) addr, sizeof(struct sockaddr_in)); - } else if (addr->ss.sa_family == AF_INET6) { - err = connect(fd, (const struct sockaddr *) addr, sizeof(struct sockaddr_in6)); - } else { - return -1; - } - } while (err < 0 && errno == EINTR); +int addr_connect(evutil_socket_t fd, const ioa_addr *addr, int *out_errno) { + if (!addr || fd < 0) + return -1; + else { + int err = 0; + do { + if (addr->ss.sa_family == AF_INET) { + err = connect(fd, (const struct sockaddr *)addr, sizeof(struct sockaddr_in)); + } else if (addr->ss.sa_family == AF_INET6) { + err = connect(fd, (const struct sockaddr *)addr, sizeof(struct sockaddr_in6)); + } else { + return -1; + } + } while (err < 0 && errno == EINTR); - if(out_errno) - *out_errno = errno; + if (out_errno) + *out_errno = errno; - if (err < 0 && errno != EINPROGRESS) - perror("Connect"); + if (err < 0 && errno != EINPROGRESS) + perror("Connect"); - return err; - } + return err; + } } -int addr_bind(evutil_socket_t fd, const ioa_addr* addr, int reusable, int debug, SOCKET_TYPE st) -{ - if (!addr || fd < 0) { +int addr_bind(evutil_socket_t fd, const ioa_addr *addr, int reusable, int debug, SOCKET_TYPE st) { + if (!addr || fd < 0) { - return -1; + return -1; - } else { + } else { - int ret = -1; + int ret = -1; - socket_set_reusable(fd, reusable, st); + socket_set_reusable(fd, reusable, st); - if (addr->ss.sa_family == AF_INET) { - do { - ret = bind(fd, (const struct sockaddr *) addr, sizeof(struct sockaddr_in)); - } while (ret < 0 && errno == EINTR); - } else if (addr->ss.sa_family == AF_INET6) { - const int off = 0; - setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const char *) &off, sizeof(off)); - do { - ret = bind(fd, (const struct sockaddr *) addr, sizeof(struct sockaddr_in6)); - } while (ret < 0 && errno == EINTR); - } else { - return -1; - } - if(ret<0) { - if(debug) { - int err = errno; - perror("bind"); - char str[129]; - addr_to_string(addr,(uint8_t*)str); - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Trying to bind fd %d to <%s>: errno=%d\n", fd, str, err); - } - } - return ret; - } + if (addr->ss.sa_family == AF_INET) { + do { + ret = bind(fd, (const struct sockaddr *)addr, sizeof(struct sockaddr_in)); + } while (ret < 0 && errno == EINTR); + } else if (addr->ss.sa_family == AF_INET6) { + const int off = 0; + setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&off, sizeof(off)); + do { + ret = bind(fd, (const struct sockaddr *)addr, sizeof(struct sockaddr_in6)); + } while (ret < 0 && errno == EINTR); + } else { + return -1; + } + if (ret < 0) { + if (debug) { + int err = errno; + perror("bind"); + char str[129]; + addr_to_string(addr, (uint8_t *)str); + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Trying to bind fd %d to <%s>: errno=%d\n", fd, str, err); + } + } + return ret; + } } -int addr_get_from_sock(evutil_socket_t fd, ioa_addr *addr) -{ +int addr_get_from_sock(evutil_socket_t fd, ioa_addr *addr) { - if (fd < 0 || !addr) - return -1; - else { + if (fd < 0 || !addr) + return -1; + else { - ioa_addr a; - a.ss.sa_family = AF_INET6; - socklen_t socklen = get_ioa_addr_len(&a); - if (getsockname(fd, (struct sockaddr*) &a, &socklen) < 0) { - a.ss.sa_family = AF_INET; - socklen = get_ioa_addr_len(&a); - if (getsockname(fd, (struct sockaddr*) &a, &socklen) < 0) { - return -1; - } - } + ioa_addr a; + a.ss.sa_family = AF_INET6; + socklen_t socklen = get_ioa_addr_len(&a); + if (getsockname(fd, (struct sockaddr *)&a, &socklen) < 0) { + a.ss.sa_family = AF_INET; + socklen = get_ioa_addr_len(&a); + if (getsockname(fd, (struct sockaddr *)&a, &socklen) < 0) { + return -1; + } + } - addr_cpy(addr, &a); + addr_cpy(addr, &a); - return 0; - } + return 0; + } } -int get_raw_socket_ttl(evutil_socket_t fd, int family) -{ - int ttl = 0; +int get_raw_socket_ttl(evutil_socket_t fd, int family) { + int ttl = 0; - if(family == AF_INET6) { + if (family == AF_INET6) { #if !defined(IPV6_UNICAST_HOPS) - UNUSED_ARG(fd); - do { return TTL_IGNORE; } while(0); + UNUSED_ARG(fd); + do { + return TTL_IGNORE; + } while (0); #else - socklen_t slen = (socklen_t)sizeof(ttl); - if(getsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl,&slen)<0) { - perror("get HOPLIMIT on socket"); - return TTL_IGNORE; - } + socklen_t slen = (socklen_t)sizeof(ttl); + if (getsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, &slen) < 0) { + perror("get HOPLIMIT on socket"); + return TTL_IGNORE; + } #endif - } else { + } else { #if !defined(IP_TTL) - UNUSED_ARG(fd); - do { return TTL_IGNORE; } while(0); + UNUSED_ARG(fd); + do { + return TTL_IGNORE; + } while (0); #else - socklen_t slen = (socklen_t)sizeof(ttl); - if(getsockopt(fd, IPPROTO_IP, IP_TTL, &ttl,&slen)<0) { - perror("get TTL on socket"); - return TTL_IGNORE; - } + socklen_t slen = (socklen_t)sizeof(ttl); + if (getsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, &slen) < 0) { + perror("get TTL on socket"); + return TTL_IGNORE; + } #endif - } + } - CORRECT_RAW_TTL(ttl); + CORRECT_RAW_TTL(ttl); - return ttl; + return ttl; } -int get_raw_socket_tos(evutil_socket_t fd, int family) -{ - int tos = 0; +int get_raw_socket_tos(evutil_socket_t fd, int family) { + int tos = 0; - if(family == AF_INET6) { + if (family == AF_INET6) { #if !defined(IPV6_TCLASS) - UNUSED_ARG(fd); - do { return TOS_IGNORE; } while(0); + UNUSED_ARG(fd); + do { + return TOS_IGNORE; + } while (0); #else - socklen_t slen = (socklen_t)sizeof(tos); - if(getsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &tos,&slen)<0) { - perror("get TCLASS on socket"); - return -1; - } + socklen_t slen = (socklen_t)sizeof(tos); + if (getsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &tos, &slen) < 0) { + perror("get TCLASS on socket"); + return -1; + } #endif - } else { + } else { #if !defined(IP_TOS) - UNUSED_ARG(fd); - do { return TOS_IGNORE; } while(0); + UNUSED_ARG(fd); + do { + return TOS_IGNORE; + } while (0); #else - socklen_t slen = (socklen_t)sizeof(tos); - if(getsockopt(fd, IPPROTO_IP, IP_TOS, &tos,&slen)<0) { - perror("get TOS on socket"); - return -1; - } + socklen_t slen = (socklen_t)sizeof(tos); + if (getsockopt(fd, IPPROTO_IP, IP_TOS, &tos, &slen) < 0) { + perror("get TOS on socket"); + return -1; + } #endif - } + } - CORRECT_RAW_TOS(tos); + CORRECT_RAW_TOS(tos); - return tos; + return tos; } -int set_raw_socket_ttl(evutil_socket_t fd, int family, int ttl) -{ +int set_raw_socket_ttl(evutil_socket_t fd, int family, int ttl) { - if(family == AF_INET6) { + if (family == AF_INET6) { #if !defined(IPV6_UNICAST_HOPS) - UNUSED_ARG(fd); - UNUSED_ARG(ttl); + UNUSED_ARG(fd); + UNUSED_ARG(ttl); #else - CORRECT_RAW_TTL(ttl); - if(setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl,sizeof(ttl))<0) { - perror("set HOPLIMIT on socket"); - return -1; - } + CORRECT_RAW_TTL(ttl); + if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)) < 0) { + perror("set HOPLIMIT on socket"); + return -1; + } #endif - } else { + } else { #if !defined(IP_TTL) - UNUSED_ARG(fd); - UNUSED_ARG(ttl); + UNUSED_ARG(fd); + UNUSED_ARG(ttl); #else - CORRECT_RAW_TTL(ttl); - if(setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl,sizeof(ttl))<0) { - perror("set TTL on socket"); - return -1; - } + CORRECT_RAW_TTL(ttl); + if (setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) < 0) { + perror("set TTL on socket"); + return -1; + } #endif - } + } - return 0; + return 0; } -int set_raw_socket_tos(evutil_socket_t fd, int family, int tos) -{ +int set_raw_socket_tos(evutil_socket_t fd, int family, int tos) { - if(family == AF_INET6) { + if (family == AF_INET6) { #if !defined(IPV6_TCLASS) - UNUSED_ARG(fd); - UNUSED_ARG(tos); + UNUSED_ARG(fd); + UNUSED_ARG(tos); #else - CORRECT_RAW_TOS(tos); - if(setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &tos,sizeof(tos))<0) { - perror("set TCLASS on socket"); - return -1; - } + CORRECT_RAW_TOS(tos); + if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)) < 0) { + perror("set TCLASS on socket"); + return -1; + } #endif - } else { + } else { #if !defined(IP_TOS) - UNUSED_ARG(fd); - UNUSED_ARG(tos); + UNUSED_ARG(fd); + UNUSED_ARG(tos); #else - if(setsockopt(fd, IPPROTO_IP, IP_TOS, &tos,sizeof(tos))<0) { - perror("set TOS on socket"); - return -1; - } + if (setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) { + perror("set TOS on socket"); + return -1; + } #endif - } + } - return 0; + return 0; } int is_stream_socket(int st) { - switch(st) { - case TCP_SOCKET: - case TCP_SOCKET_PROXY: - case TLS_SOCKET: - case TENTATIVE_TCP_SOCKET: - case SCTP_SOCKET: - case TLS_SCTP_SOCKET: - case TENTATIVE_SCTP_SOCKET: - return 1; - default: - ; - } - return 0; + switch (st) { + case TCP_SOCKET: + case TCP_SOCKET_PROXY: + case TLS_SOCKET: + case TENTATIVE_TCP_SOCKET: + case SCTP_SOCKET: + case TLS_SCTP_SOCKET: + case TENTATIVE_SCTP_SOCKET: + return 1; + default:; + } + return 0; } int is_tcp_socket(int st) { - switch(st) { - case TCP_SOCKET: - case TLS_SOCKET: - case TENTATIVE_TCP_SOCKET: - return 1; - default: - ; - } - return 0; + switch (st) { + case TCP_SOCKET: + case TLS_SOCKET: + case TENTATIVE_TCP_SOCKET: + return 1; + default:; + } + return 0; } int is_sctp_socket(int st) { - switch(st) { - case SCTP_SOCKET: - case TLS_SCTP_SOCKET: - case TENTATIVE_SCTP_SOCKET: - return 1; - default: - ; - } - return 0; + switch (st) { + case SCTP_SOCKET: + case TLS_SCTP_SOCKET: + case TENTATIVE_SCTP_SOCKET: + return 1; + default:; + } + return 0; } -const char* socket_type_name(SOCKET_TYPE st) -{ - switch(st) { - case TCP_SOCKET: - return "TCP"; - case SCTP_SOCKET: - return "SCTP"; - case UDP_SOCKET: - return "UDP"; - case TLS_SOCKET: - return "TLS/TCP"; - case TLS_SCTP_SOCKET: - return "TLS/SCTP"; - case DTLS_SOCKET: - return "DTLS"; - case TENTATIVE_TCP_SOCKET: - return "TLS/TCP ?"; - case TENTATIVE_SCTP_SOCKET: - return "TLS/SCTP ?"; - default: - ; - }; - return "UNKNOWN"; +const char *socket_type_name(SOCKET_TYPE st) { + switch (st) { + case TCP_SOCKET: + return "TCP"; + case SCTP_SOCKET: + return "SCTP"; + case UDP_SOCKET: + return "UDP"; + case TLS_SOCKET: + return "TLS/TCP"; + case TLS_SCTP_SOCKET: + return "TLS/SCTP"; + case DTLS_SOCKET: + return "DTLS"; + case TENTATIVE_TCP_SOCKET: + return "TLS/TCP ?"; + case TENTATIVE_SCTP_SOCKET: + return "TLS/SCTP ?"; + default:; + }; + return "UNKNOWN"; } /////////////////// MTU ///////////////////////////////////////// -int set_socket_df(evutil_socket_t fd, int family, int value) -{ +int set_socket_df(evutil_socket_t fd, int family, int value) { - int ret=0; + int ret = 0; -#if defined(IP_DONTFRAG) && defined(IPPROTO_IP) //BSD +#if defined(IP_DONTFRAG) && defined(IPPROTO_IP) // BSD { - const int val=value; + const int val = value; /* kernel sets DF bit on outgoing IP packets */ - if(family==AF_INET) { + if (family == AF_INET) { ret = setsockopt(fd, IPPROTO_IP, IP_DONTFRAG, &val, sizeof(val)); } else { #if defined(IPV6_DONTFRAG) && defined(IPPROTO_IPV6) @@ -561,35 +548,38 @@ int set_socket_df(evutil_socket_t fd, int family, int value) #error CANNOT SET IPV6 SOCKET DF FLAG (1) #endif } - if(ret<0) { - int err=errno; + if (ret < 0) { + int err = errno; perror("set socket df:"); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s: set sockopt failed: fd=%d, err=%d, family=%d\n",__FUNCTION__,fd,err,family); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: set sockopt failed: fd=%d, err=%d, family=%d\n", __FUNCTION__, fd, err, + family); } } -#elif defined(IPPROTO_IP) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) && defined(IP_PMTUDISC_DONT) //LINUX +#elif defined(IPPROTO_IP) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) && defined(IP_PMTUDISC_DONT) // LINUX { /* kernel sets DF bit on outgoing IP packets */ - if(family==AF_INET) { - int val=IP_PMTUDISC_DO; - if(!value) val=IP_PMTUDISC_DONT; + if (family == AF_INET) { + int val = IP_PMTUDISC_DO; + if (!value) + val = IP_PMTUDISC_DONT; ret = setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)); } else { #if defined(IPPROTO_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) && defined(IPV6_PMTUDISC_DONT) - int val=IPV6_PMTUDISC_DO; - if(!value) val=IPV6_PMTUDISC_DONT; + int val = IPV6_PMTUDISC_DO; + if (!value) + val = IPV6_PMTUDISC_DONT; ret = setsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &val, sizeof(val)); #else #error CANNOT SET IPV6 SOCKET DF FLAG (2) #endif } - if(ret<0) { + if (ret < 0) { perror("set DF"); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s: set sockopt failed\n",__FUNCTION__); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: set sockopt failed\n", __FUNCTION__); } } #else -//CANNOT SET SOCKET DF FLAG (3) : UNKNOWN PLATFORM + // CANNOT SET SOCKET DF FLAG (3) : UNKNOWN PLATFORM UNUSED_ARG(fd); UNUSED_ARG(family); UNUSED_ARG(value); @@ -598,20 +588,19 @@ int set_socket_df(evutil_socket_t fd, int family, int value) return ret; } -static int get_mtu_from_ssl(SSL* ssl) -{ +static int get_mtu_from_ssl(SSL *ssl) { int ret = SOSO_MTU; #if DTLS_SUPPORTED - if(ssl) - ret = BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); + if (ssl) + ret = BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); #else UNUSED_ARG(ssl); #endif return ret; } -static void set_query_mtu(SSL* ssl) { - if(ssl) { +static void set_query_mtu(SSL *ssl) { + if (ssl) { #if defined(SSL_OP_NO_QUERY_MTU) SSL_set_options(ssl, SSL_OP_NO_QUERY_MTU); #else @@ -620,95 +609,99 @@ static void set_query_mtu(SSL* ssl) { } } -int decrease_mtu(SSL* ssl, int mtu, int verbose) -{ +int decrease_mtu(SSL *ssl, int mtu, int verbose) { - if (!ssl) - return mtu; + if (!ssl) + return mtu; - int new_mtu = get_mtu_from_ssl(ssl); + int new_mtu = get_mtu_from_ssl(ssl); - if (new_mtu < 1) - new_mtu = mtu; + if (new_mtu < 1) + new_mtu = mtu; - if (new_mtu > MAX_MTU) - mtu = MAX_MTU; - if (new_mtu > 0 && new_mtu < MIN_MTU) - mtu = MIN_MTU; - else if (new_mtu < mtu) - mtu = new_mtu; - else - mtu -= MTU_STEP; + if (new_mtu > MAX_MTU) + mtu = MAX_MTU; + if (new_mtu > 0 && new_mtu < MIN_MTU) + mtu = MIN_MTU; + else if (new_mtu < mtu) + mtu = new_mtu; + else + mtu -= MTU_STEP; - if (mtu < MIN_MTU) - mtu = MIN_MTU; - - set_query_mtu(ssl); - if (verbose) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "1. mtu to use: %d\n", mtu); - -#if DTLS_SUPPORTED - SSL_set_mtu(ssl,mtu); - BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SET_MTU, mtu, NULL); -#endif - - return mtu; -} - -int set_mtu_df(SSL* ssl, evutil_socket_t fd, int family, int mtu, int df_value, int verbose) { - - if(!ssl || fd<0) return 0; - - int ret=set_socket_df(fd, family, df_value); - - if(!mtu) mtu=SOSO_MTU; - else if(mtuMAX_MTU) mtu=MAX_MTU; + if (mtu < MIN_MTU) + mtu = MIN_MTU; set_query_mtu(ssl); - if(verbose) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"3. mtu to use: %d\n",mtu); + if (verbose) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "1. mtu to use: %d\n", mtu); + +#if DTLS_SUPPORTED + SSL_set_mtu(ssl, mtu); + BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SET_MTU, mtu, NULL); +#endif + + return mtu; +} + +int set_mtu_df(SSL *ssl, evutil_socket_t fd, int family, int mtu, int df_value, int verbose) { + + if (!ssl || fd < 0) + return 0; + + int ret = set_socket_df(fd, family, df_value); + + if (!mtu) + mtu = SOSO_MTU; + else if (mtu < MIN_MTU) + mtu = MIN_MTU; + else if (mtu > MAX_MTU) + mtu = MAX_MTU; + + set_query_mtu(ssl); + if (verbose) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "3. mtu to use: %d\n", mtu); #if DTLS_SUPPORTED - SSL_set_mtu(ssl,mtu); + SSL_set_mtu(ssl, mtu); BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SET_MTU, mtu, NULL); #endif - if(verbose) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"4. new mtu: %d\n",get_mtu_from_ssl(ssl)); + if (verbose) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "4. new mtu: %d\n", get_mtu_from_ssl(ssl)); return ret; } -int get_socket_mtu(evutil_socket_t fd, int family, int verbose) -{ +int get_socket_mtu(evutil_socket_t fd, int family, int verbose) { - int ret = 0; + int ret = 0; - UNUSED_ARG(fd); - UNUSED_ARG(family); - UNUSED_ARG(verbose); + UNUSED_ARG(fd); + UNUSED_ARG(family); + UNUSED_ARG(verbose); #if defined(IP_MTU) - int val = 0; - socklen_t slen=sizeof(val); - if(family==AF_INET) { - ret = getsockopt(fd, IPPROTO_IP, IP_MTU, &val, &slen); - } else { + int val = 0; + socklen_t slen = sizeof(val); + if (family == AF_INET) { + ret = getsockopt(fd, IPPROTO_IP, IP_MTU, &val, &slen); + } else { #if defined(IPPROTO_IPV6) && defined(IPV6_MTU) - ret = getsockopt(fd, IPPROTO_IPV6, IPV6_MTU, &val, &slen); + ret = getsockopt(fd, IPPROTO_IPV6, IPV6_MTU, &val, &slen); #endif - ; - } + ; + } - ret = val; + ret = val; #endif - if (verbose) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: final=%d\n", __FUNCTION__, ret); + if (verbose) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: final=%d\n", __FUNCTION__, ret); - return ret; + return ret; } //////////////////// socket error handle //////////////////// @@ -755,7 +748,7 @@ int handle_socket_error(void) { /* Out of memory. * Must close connection. */ - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Out of memory!\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Out of memory!\n"); return 0; case EACCES: /* Permission denied. @@ -766,270 +759,244 @@ int handle_socket_error(void) { return 1; default: /* Something unexpected happened */ - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Unexpected error! (errno = %d)\n", errno); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Unexpected error! (errno = %d)\n", errno); return 0; } } //////////////////// Misc utils ////////////////////////////// -char *skip_blanks(char* s) -{ - while(*s==' ' || *s=='\t' || *s=='\n') - ++s; +char *skip_blanks(char *s) { + while (*s == ' ' || *s == '\t' || *s == '\n') + ++s; - return s; + return s; } #if defined(_MSC_VER) -LARGE_INTEGER getFILETIMEoffset() -{ - SYSTEMTIME s; - FILETIME f; - LARGE_INTEGER t; +LARGE_INTEGER getFILETIMEoffset() { + SYSTEMTIME s; + FILETIME f; + LARGE_INTEGER t; - s.wYear = 1970; - s.wMonth = 1; - s.wDay = 1; - s.wHour = 0; - s.wMinute = 0; - s.wSecond = 0; - s.wMilliseconds = 0; - SystemTimeToFileTime(&s, &f); - t.QuadPart = f.dwHighDateTime; - t.QuadPart <<= 32; - t.QuadPart |= f.dwLowDateTime; - return (t); + s.wYear = 1970; + s.wMonth = 1; + s.wDay = 1; + s.wHour = 0; + s.wMinute = 0; + s.wSecond = 0; + s.wMilliseconds = 0; + SystemTimeToFileTime(&s, &f); + t.QuadPart = f.dwHighDateTime; + t.QuadPart <<= 32; + t.QuadPart |= f.dwLowDateTime; + return (t); } -int clock_gettime(int X, struct timeval* tv) -{ - LARGE_INTEGER t; - FILETIME f; - double microseconds; - static LARGE_INTEGER offset; - static double frequencyToMicroseconds; - static int initialized = 0; - static BOOL usePerformanceCounter = FALSE; +int clock_gettime(int X, struct timeval *tv) { + LARGE_INTEGER t; + FILETIME f; + double microseconds; + static LARGE_INTEGER offset; + static double frequencyToMicroseconds; + static int initialized = 0; + static BOOL usePerformanceCounter = FALSE; - if (!initialized) { - LARGE_INTEGER performanceFrequency; - initialized = 1; - usePerformanceCounter = QueryPerformanceFrequency(&performanceFrequency); - if (usePerformanceCounter) { - QueryPerformanceCounter(&offset); - frequencyToMicroseconds = (double)performanceFrequency.QuadPart / 1000000.; - } - else { - offset = getFILETIMEoffset(); - frequencyToMicroseconds = 10.; - } - } - if (usePerformanceCounter) QueryPerformanceCounter(&t); - else { - GetSystemTimeAsFileTime(&f); - t.QuadPart = f.dwHighDateTime; - t.QuadPart <<= 32; - t.QuadPart |= f.dwLowDateTime; - } + if (!initialized) { + LARGE_INTEGER performanceFrequency; + initialized = 1; + usePerformanceCounter = QueryPerformanceFrequency(&performanceFrequency); + if (usePerformanceCounter) { + QueryPerformanceCounter(&offset); + frequencyToMicroseconds = (double)performanceFrequency.QuadPart / 1000000.; + } else { + offset = getFILETIMEoffset(); + frequencyToMicroseconds = 10.; + } + } + if (usePerformanceCounter) + QueryPerformanceCounter(&t); + else { + GetSystemTimeAsFileTime(&f); + t.QuadPart = f.dwHighDateTime; + t.QuadPart <<= 32; + t.QuadPart |= f.dwLowDateTime; + } - t.QuadPart -= offset.QuadPart; - microseconds = (double)t.QuadPart / frequencyToMicroseconds; - t.QuadPart = microseconds; - tv->tv_sec = t.QuadPart / 1000000; - tv->tv_usec = t.QuadPart % 1000000; - return 0; + t.QuadPart -= offset.QuadPart; + microseconds = (double)t.QuadPart / frequencyToMicroseconds; + t.QuadPart = microseconds; + tv->tv_sec = t.QuadPart / 1000000; + tv->tv_usec = t.QuadPart % 1000000; + return 0; } -int gettimeofday(struct timeval* tp, void* tzp) -{ - time_t clock; - struct tm tm; - SYSTEMTIME wtm; +int gettimeofday(struct timeval *tp, void *tzp) { + time_t clock; + struct tm tm; + SYSTEMTIME wtm; - GetLocalTime(&wtm); - tm.tm_year = wtm.wYear - 1900; - tm.tm_mon = wtm.wMonth - 1; - tm.tm_mday = wtm.wDay; - tm.tm_hour = wtm.wHour; - tm.tm_min = wtm.wMinute; - tm.tm_sec = wtm.wSecond; - tm.tm_isdst = -1; - clock = mktime(&tm); - tp->tv_sec = clock; - tp->tv_usec = wtm.wMilliseconds * 1000; + GetLocalTime(&wtm); + tm.tm_year = wtm.wYear - 1900; + tm.tm_mon = wtm.wMonth - 1; + tm.tm_mday = wtm.wDay; + tm.tm_hour = wtm.wHour; + tm.tm_min = wtm.wMinute; + tm.tm_sec = wtm.wSecond; + tm.tm_isdst = -1; + clock = mktime(&tm); + tp->tv_sec = clock; + tp->tv_usec = wtm.wMilliseconds * 1000; - return (0); + return (0); } -char* dirname(char* path) -{ - char drive[_MAX_DRIVE]; - char dir[_MAX_DIR]; +char *dirname(char *path) { + char drive[_MAX_DRIVE]; + char dir[_MAX_DIR]; - errno_t err = _splitpath_s(path, - drive, _MAX_DRIVE, - dir, _MAX_DIR, - NULL, 0, - NULL, 0); - if (err) - { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "split path fail: %d", err); - return NULL; - } + errno_t err = _splitpath_s(path, drive, _MAX_DRIVE, dir, _MAX_DIR, NULL, 0, NULL, 0); + if (err) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "split path fail: %d", err); + return NULL; + } - int n = strlen(drive) + strlen(dir); - if (n > 0) - path[n] = 0; - else - return NULL; - return path; + int n = strlen(drive) + strlen(dir); + if (n > 0) + path[n] = 0; + else + return NULL; + return path; } #endif #if defined(WINDOWS) -int getdomainname(char* name, size_t len) -{ - DSROLE_PRIMARY_DOMAIN_INFO_BASIC* info; - DWORD dw; +int getdomainname(char *name, size_t len) { + DSROLE_PRIMARY_DOMAIN_INFO_BASIC *info; + DWORD dw; - dw = DsRoleGetPrimaryDomainInformation(NULL, - DsRolePrimaryDomainInfoBasic, - (PBYTE*)&info); - if (dw != ERROR_SUCCESS) - { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "DsRoleGetPrimaryDomainInformation: %u\n", dw); - return -1; - } + dw = DsRoleGetPrimaryDomainInformation(NULL, DsRolePrimaryDomainInfoBasic, (PBYTE *)&info); + if (dw != ERROR_SUCCESS) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "DsRoleGetPrimaryDomainInformation: %u\n", dw); + return -1; + } - do { - if (info->DomainForestName) - { - char* pszOut = NULL; - int nOutSize = 0; - if (_WTA(info->DomainForestName, wcslen(info->DomainForestName), &pszOut, &nOutSize)) - { - int n = nOutSize - 1; - if (nOutSize > len - 1) - { - n = len - 1; - } - strncpy(name, pszOut, n); - name[n] = 0; - TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainForestName: %s\n", pszOut); - } - else - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "wchar convert to char fail"); + do { + if (info->DomainForestName) { + char *pszOut = NULL; + int nOutSize = 0; + if (_WTA(info->DomainForestName, wcslen(info->DomainForestName), &pszOut, &nOutSize)) { + int n = nOutSize - 1; + if (nOutSize > len - 1) { + n = len - 1; + } + strncpy(name, pszOut, n); + name[n] = 0; + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainForestName: %s\n", pszOut); + } else + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "wchar convert to char fail"); - free(pszOut); - break; - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainForestName is NULL\n"); - } + free(pszOut); + break; + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainForestName is NULL\n"); + } - if (info->DomainNameDns) - { - char* pszOut = NULL; - int nOutSize = 0; - if (_WTA(info->DomainNameDns, wcslen(info->DomainNameDns), &pszOut, &nOutSize)) - { - int n = nOutSize - 1; - if (nOutSize > len - 1) - { - n = len - 1; - } - strncpy(name, pszOut, n); - name[n] = 0; - TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainNameDns: %s\n", pszOut); - } - else - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "wchar convert to char fail"); + if (info->DomainNameDns) { + char *pszOut = NULL; + int nOutSize = 0; + if (_WTA(info->DomainNameDns, wcslen(info->DomainNameDns), &pszOut, &nOutSize)) { + int n = nOutSize - 1; + if (nOutSize > len - 1) { + n = len - 1; + } + strncpy(name, pszOut, n); + name[n] = 0; + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainNameDns: %s\n", pszOut); + } else + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "wchar convert to char fail"); - free(pszOut); - break; - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainNameDns is NULL\n"); - } + free(pszOut); + break; + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainNameDns is NULL\n"); + } - if (info->DomainNameFlat) - { - char* pszOut = NULL; - int nOutSize = 0; - if (_WTA(info->DomainNameFlat, wcslen(info->DomainNameFlat), &pszOut, &nOutSize)) - { - int n = nOutSize - 1; - if (nOutSize > len - 1) - { - n = len - 1; - } - strncpy(name, pszOut, n); - name[n] = 0; - TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainNameFlat: %s\n", pszOut); - } - else - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "wchar convert to char fail"); + if (info->DomainNameFlat) { + char *pszOut = NULL; + int nOutSize = 0; + if (_WTA(info->DomainNameFlat, wcslen(info->DomainNameFlat), &pszOut, &nOutSize)) { + int n = nOutSize - 1; + if (nOutSize > len - 1) { + n = len - 1; + } + strncpy(name, pszOut, n); + name[n] = 0; + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainNameFlat: %s\n", pszOut); + } else + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "wchar convert to char fail"); - free(pszOut); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainNameFlat is NULL\n"); - return -2; - } - } while (0); + free(pszOut); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainNameFlat is NULL\n"); + return -2; + } + } while (0); - DsRoleFreeMemory(info); - return 0; + DsRoleFreeMemory(info); + return 0; } /*! * \brief convert char to wchar - * - * \param pszInBuf: input buffer of wchar string + * + * \param pszInBuf: input buffer of wchar string * \param nInSize: size of wchar string * \param pszOutBuf: output buffer of char string * \param pnOutSize: size of char string - * \return + * \return */ -wchar_t* _ATW(__in char* pszInBuf, __in int nInSize, __out wchar_t** pszOutBuf, __out int* pnOutSize) -{ - if (!pszInBuf || !pszOutBuf || !pnOutSize || nInSize <= 0) return NULL; - // Get buffer size - *pnOutSize = MultiByteToWideChar(NULL, NULL, pszInBuf, nInSize, *pszOutBuf, 0); - if (*pnOutSize == 0) return NULL; - (*pnOutSize)++; - *pszOutBuf = malloc((*pnOutSize) * sizeof(wchar_t)); - memset((void*)*pszOutBuf, 0, sizeof(wchar_t) * (*pnOutSize)); - if (MultiByteToWideChar(NULL, NULL, pszInBuf, nInSize, *pszOutBuf, *pnOutSize) == 0) - { - free(*pszOutBuf); - return NULL; - } - else return *pszOutBuf; +wchar_t *_ATW(__in char *pszInBuf, __in int nInSize, __out wchar_t **pszOutBuf, __out int *pnOutSize) { + if (!pszInBuf || !pszOutBuf || !pnOutSize || nInSize <= 0) + return NULL; + // Get buffer size + *pnOutSize = MultiByteToWideChar(NULL, NULL, pszInBuf, nInSize, *pszOutBuf, 0); + if (*pnOutSize == 0) + return NULL; + (*pnOutSize)++; + *pszOutBuf = malloc((*pnOutSize) * sizeof(wchar_t)); + memset((void *)*pszOutBuf, 0, sizeof(wchar_t) * (*pnOutSize)); + if (MultiByteToWideChar(NULL, NULL, pszInBuf, nInSize, *pszOutBuf, *pnOutSize) == 0) { + free(*pszOutBuf); + return NULL; + } else + return *pszOutBuf; } /*! * \brief convert wchar to char - * - * \param pszInBuf: input buffer of char string + * + * \param pszInBuf: input buffer of char string * \param nInSize: size of char string * \param pszOutBuf: output buffer of wchar string * \param pnOutSize: size of wchar string - * \return + * \return */ -char* _WTA(__in wchar_t* pszInBuf, __in int nInSize, __out char** pszOutBuf, __out int* pnOutSize) -{ - if (!pszInBuf || !pszOutBuf || !pnOutSize || nInSize <= 0) return NULL; - *pnOutSize = WideCharToMultiByte(NULL, NULL, pszInBuf, nInSize, *pszOutBuf, 0, NULL, NULL); - if (*pnOutSize == 0) return NULL; - (*pnOutSize)++; - *pszOutBuf = malloc(*pnOutSize * sizeof(char)); - memset((void*)*pszOutBuf, 0, sizeof(char) * (*pnOutSize)); - if (WideCharToMultiByte(NULL, NULL, pszInBuf, nInSize, *pszOutBuf, *pnOutSize, NULL, NULL) == 0) - { - free(*pszOutBuf); - return NULL; - } - else return *pszOutBuf; +char *_WTA(__in wchar_t *pszInBuf, __in int nInSize, __out char **pszOutBuf, __out int *pnOutSize) { + if (!pszInBuf || !pszOutBuf || !pnOutSize || nInSize <= 0) + return NULL; + *pnOutSize = WideCharToMultiByte(NULL, NULL, pszInBuf, nInSize, *pszOutBuf, 0, NULL, NULL); + if (*pnOutSize == 0) + return NULL; + (*pnOutSize)++; + *pszOutBuf = malloc(*pnOutSize * sizeof(char)); + memset((void *)*pszOutBuf, 0, sizeof(char) * (*pnOutSize)); + if (WideCharToMultiByte(NULL, NULL, pszInBuf, nInSize, *pszOutBuf, *pnOutSize, NULL, NULL) == 0) { + free(*pszOutBuf); + return NULL; + } else + return *pszOutBuf; } #endif @@ -1039,171 +1006,183 @@ char* _WTA(__in wchar_t* pszInBuf, __in int nInSize, __out char** pszOutBuf, __o #define Q(x) #x #define QUOTE(x) Q(x) -#define ETCDIR INSTALL_PREFIX/etc/ +#define ETCDIR INSTALL_PREFIX / etc / #define QETCDIR QUOTE(ETCDIR) -#define ETCDIR1 INSTALL_PREFIX/etc/turnserver/ +#define ETCDIR1 INSTALL_PREFIX / etc / turnserver / #define QETCDIR1 QUOTE(ETCDIR1) -#define ETCDIR2 INSTALL_PREFIX/etc/coturn/ +#define ETCDIR2 INSTALL_PREFIX / etc / coturn / #define QETCDIR2 QUOTE(ETCDIR2) -static const char *config_file_search_dirs[] = {"./", "./turnserver/", "./coturn/", "./etc/", "./etc/turnserver/", "./etc/coturn/", "../etc/", "../etc/turnserver/", "../etc/coturn/", "/etc/", "/etc/turnserver/", "/etc/coturn/", "/usr/local/etc/", "/usr/local/etc/turnserver/", "/usr/local/etc/coturn/", QETCDIR, QETCDIR1, QETCDIR2, NULL }; -static char *c_execdir=NULL; +static const char *config_file_search_dirs[] = {"./", + "./turnserver/", + "./coturn/", + "./etc/", + "./etc/turnserver/", + "./etc/coturn/", + "../etc/", + "../etc/turnserver/", + "../etc/coturn/", + "/etc/", + "/etc/turnserver/", + "/etc/coturn/", + "/usr/local/etc/", + "/usr/local/etc/turnserver/", + "/usr/local/etc/coturn/", + QETCDIR, + QETCDIR1, + QETCDIR2, + NULL}; +static char *c_execdir = NULL; -void set_execdir(void) -{ +void set_execdir(void) { /* On some systems, this may give us the execution path */ - char *_var = NULL; + char *_var = NULL; #if defined(_MSC_VER) - char szPath[MAX_PATH]; - if (!GetModuleFileNameA(NULL, szPath, MAX_PATH)) - { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "GetModuleFileName failed(%d)\n", GetLastError()); - return; - } - _var = szPath; + char szPath[MAX_PATH]; + if (!GetModuleFileNameA(NULL, szPath, MAX_PATH)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "GetModuleFileName failed(%d)\n", GetLastError()); + return; + } + _var = szPath; #elif defined(__unix__) - _var = getenv("_"); + _var = getenv("_"); #endif - if (_var && *_var) { + if (_var && *_var) { _var = strdup(_var); - char *edir = _var; - if (edir[0] != '.') - edir = strstr(edir, "/"); - if (edir && *edir) - edir = dirname(edir); + char *edir = _var; + if (edir[0] != '.') + edir = strstr(edir, "/"); + if (edir && *edir) + edir = dirname(edir); else - edir = dirname(_var); - if (c_execdir) - free(c_execdir); + edir = dirname(_var); + if (c_execdir) + free(c_execdir); c_execdir = strdup(edir); free(_var); } } -void print_abs_file_name(const char *msg1, const char *msg2, const char *fn) -{ +void print_abs_file_name(const char *msg1, const char *msg2, const char *fn) { char absfn[1025]; - absfn[0]=0; + absfn[0] = 0; - if(fn) { - while(fn[0] && fn[0]==' ') ++fn; - if(fn[0]) { - if(fn[0]=='/') { - STRCPY(absfn,fn); + if (fn) { + while (fn[0] && fn[0] == ' ') + ++fn; + if (fn[0]) { + if (fn[0] == '/') { + STRCPY(absfn, fn); } else { - if(fn[0]=='.' && fn[1] && fn[1]=='/') - fn+=2; - if(!getcwd(absfn,sizeof(absfn)-1)) - absfn[0]=0; - size_t blen=strlen(absfn); - if(blen + int num = 0; + // TODO: get max socket? by KangLin - num = _getmaxstdio(); - return num; + num = _getmaxstdio(); + return num; #elif defined(__linux__) || defined(__APPLE__) - - struct rlimit rlim; - if(getrlimit(RLIMIT_NOFILE, &rlim)<0) { - perror("Cannot get system limit"); - } else { - rlim.rlim_cur = rlim.rlim_max; - while((setrlimit(RLIMIT_NOFILE, &rlim)<0) && (rlim.rlim_cur>0)) { - rlim.rlim_cur = rlim.rlim_cur>>1; - } - return (unsigned long)rlim.rlim_cur; - } - -#endif - } - return 0; + struct rlimit rlim; + if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) { + perror("Cannot get system limit"); + } else { + rlim.rlim_cur = rlim.rlim_max; + while ((setrlimit(RLIMIT_NOFILE, &rlim) < 0) && (rlim.rlim_cur > 0)) { + rlim.rlim_cur = rlim.rlim_cur >> 1; + } + return (unsigned long)rlim.rlim_cur; + } + +#endif + } + + return 0; } -unsigned long get_system_number_of_cpus(void) -{ +unsigned long get_system_number_of_cpus(void) { #if defined(WINDOWS) - SYSTEM_INFO sysInfo; - GetSystemInfo(&sysInfo); - TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "System cpu num is %d\n", sysInfo.dwNumberOfProcessors); - TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "System enable num is 0x%X\n", sysInfo.dwActiveProcessorMask); - return sysInfo.dwNumberOfProcessors; + SYSTEM_INFO sysInfo; + GetSystemInfo(&sysInfo); + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "System cpu num is %d\n", sysInfo.dwNumberOfProcessors); + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "System enable num is 0x%X\n", sysInfo.dwActiveProcessorMask); + return sysInfo.dwNumberOfProcessors; #else - #if defined(_SC_NPROCESSORS_ONLN) - TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "System cpu num is %ld \n", sysconf(_SC_NPROCESSORS_CONF)); - TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "System enable num is %ld\n", sysconf(_SC_NPROCESSORS_ONLN)); - return sysconf(_SC_NPROCESSORS_CONF); - #else - //GNU way - TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "System cpu num is %d\n", get_nprocs_conf()); - TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "System enable num is %d\n", get_nprocs()); - return get_nprocs_conf(); - #endif +#if defined(_SC_NPROCESSORS_ONLN) + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "System cpu num is %ld \n", sysconf(_SC_NPROCESSORS_CONF)); + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "System enable num is %ld\n", sysconf(_SC_NPROCESSORS_ONLN)); + return sysconf(_SC_NPROCESSORS_CONF); +#else + // GNU way + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "System cpu num is %d\n", get_nprocs_conf()); + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "System enable num is %d\n", get_nprocs()); + return get_nprocs_conf(); +#endif #endif } ////////////////////// Base 64 //////////////////////////// -static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '+', '/'}; +static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; static char *decoding_table = NULL; static size_t mod_table[] = {0, 2, 1}; -char *base64_encode(const unsigned char *data, - size_t input_length, - size_t *output_length) { +char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length) { - *output_length = 4 * ((input_length + 2) / 3); + *output_length = 4 * ((input_length + 2) / 3); - char *encoded_data = (char*)malloc(*output_length+1); - if (encoded_data == NULL) return NULL; + char *encoded_data = (char *)malloc(*output_length + 1); + if (encoded_data == NULL) + return NULL; - size_t i,j; - for (i = 0, j = 0; i < input_length;) { + size_t i, j; + for (i = 0, j = 0; i < input_length;) { - uint32_t octet_a = i < input_length ? data[i++] : 0; - uint32_t octet_b = i < input_length ? data[i++] : 0; - uint32_t octet_c = i < input_length ? data[i++] : 0; + uint32_t octet_a = i < input_length ? data[i++] : 0; + uint32_t octet_b = i < input_length ? data[i++] : 0; + uint32_t octet_c = i < input_length ? data[i++] : 0; - uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c; + uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c; - encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F]; - encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F]; - encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F]; - encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F]; - } + encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F]; + encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F]; + encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F]; + encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F]; + } - for (i = 0; i < mod_table[input_length % 3]; i++) - encoded_data[*output_length - 1 - i] = '='; + for (i = 0; i < mod_table[input_length % 3]; i++) + encoded_data[*output_length - 1 - i] = '='; - encoded_data[*output_length]=0; + encoded_data[*output_length] = 0; - return encoded_data; + return encoded_data; } void build_base64_decoding_table(void) { - decoding_table = (char*)malloc(256); - memset(decoding_table, 0, 256); + decoding_table = (char *)malloc(256); + memset(decoding_table, 0, 256); - int i; - for (i = 0; i < 64; i++) - decoding_table[(unsigned char) encoding_table[i]] = (char)i; + int i; + for (i = 0; i < 64; i++) + decoding_table[(unsigned char)encoding_table[i]] = (char)i; } -unsigned char *base64_decode(const char *data, - size_t input_length, - size_t *output_length) { +unsigned char *base64_decode(const char *data, size_t input_length, size_t *output_length) { - if (decoding_table == NULL) build_base64_decoding_table(); + if (decoding_table == NULL) + build_base64_decoding_table(); - if (input_length % 4 != 0) return NULL; + if (input_length % 4 != 0) + return NULL; - *output_length = input_length / 4 * 3; - if (data[input_length - 1] == '=') (*output_length)--; - if (data[input_length - 2] == '=') (*output_length)--; + *output_length = input_length / 4 * 3; + if (data[input_length - 1] == '=') + (*output_length)--; + if (data[input_length - 2] == '=') + (*output_length)--; - unsigned char *decoded_data = (unsigned char*)malloc(*output_length); - if (decoded_data == NULL) return NULL; + unsigned char *decoded_data = (unsigned char *)malloc(*output_length); + if (decoded_data == NULL) + return NULL; - int i; - size_t j; - for (i = 0, j = 0; i < (int)input_length;) { + int i; + size_t j; + for (i = 0, j = 0; i < (int)input_length;) { - uint32_t sextet_a = - data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; - uint32_t sextet_b = - data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; - uint32_t sextet_c = - data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; - uint32_t sextet_d = - data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; + uint32_t sextet_a = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; + uint32_t sextet_b = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; + uint32_t sextet_c = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; + uint32_t sextet_d = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; - uint32_t triple = (sextet_a << 3 * 6) + (sextet_b << 2 * 6) - + (sextet_c << 1 * 6) + (sextet_d << 0 * 6); + uint32_t triple = (sextet_a << 3 * 6) + (sextet_b << 2 * 6) + (sextet_c << 1 * 6) + (sextet_d << 0 * 6); - if (j < *output_length) - decoded_data[j++] = (triple >> 2 * 8) & 0xFF; - if (j < *output_length) - decoded_data[j++] = (triple >> 1 * 8) & 0xFF; - if (j < *output_length) - decoded_data[j++] = (triple >> 0 * 8) & 0xFF; + if (j < *output_length) + decoded_data[j++] = (triple >> 2 * 8) & 0xFF; + if (j < *output_length) + decoded_data[j++] = (triple >> 1 * 8) & 0xFF; + if (j < *output_length) + decoded_data[j++] = (triple >> 0 * 8) & 0xFF; + } - } - - return decoded_data; + return decoded_data; } ////////////////// SSL ///////////////////// -const char* turn_get_ssl_method(SSL *ssl, const char* mdefault) -{ - const char* ret = "unknown"; - if(!ssl) { - ret = mdefault; - } else { - ret = SSL_get_version(ssl); - } +const char *turn_get_ssl_method(SSL *ssl, const char *mdefault) { + const char *ret = "unknown"; + if (!ssl) { + ret = mdefault; + } else { + ret = SSL_get_version(ssl); + } - return ret; + return ret; } //////////// EVENT BASE /////////////// -struct event_base *turn_event_base_new(void) -{ - struct event_config *cfg = event_config_new(); +struct event_base *turn_event_base_new(void) { + struct event_config *cfg = event_config_new(); - event_config_set_flag(cfg,EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST); + event_config_set_flag(cfg, EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST); - return event_base_new_with_config(cfg); + return event_base_new_with_config(cfg); } /////////// OAUTH ///////////////// -void convert_oauth_key_data_raw(const oauth_key_data_raw *raw, oauth_key_data *oakd) -{ - if(raw && oakd) { +void convert_oauth_key_data_raw(const oauth_key_data_raw *raw, oauth_key_data *oakd) { + if (raw && oakd) { - memset(oakd,0,sizeof(oauth_key_data)); + memset(oakd, 0, sizeof(oauth_key_data)); - oakd->timestamp = (turn_time_t)raw->timestamp; - oakd->lifetime = raw->lifetime; + oakd->timestamp = (turn_time_t)raw->timestamp; + oakd->lifetime = raw->lifetime; - memcpy(oakd->as_rs_alg,raw->as_rs_alg,sizeof(oakd->as_rs_alg)); - memcpy(oakd->kid,raw->kid,sizeof(oakd->kid)); + memcpy(oakd->as_rs_alg, raw->as_rs_alg, sizeof(oakd->as_rs_alg)); + memcpy(oakd->kid, raw->kid, sizeof(oakd->kid)); - if(raw->ikm_key[0]) { - size_t ikm_key_size = 0; - char *ikm_key = (char*)base64_decode(raw->ikm_key,strlen(raw->ikm_key),&ikm_key_size); - if(ikm_key) { - memcpy(oakd->ikm_key,ikm_key,ikm_key_size); - oakd->ikm_key_size = ikm_key_size; - free(ikm_key); - } - } - } + if (raw->ikm_key[0]) { + size_t ikm_key_size = 0; + char *ikm_key = (char *)base64_decode(raw->ikm_key, strlen(raw->ikm_key), &ikm_key_size); + if (ikm_key) { + memcpy(oakd->ikm_key, ikm_key, ikm_key_size); + oakd->ikm_key_size = ikm_key_size; + free(ikm_key); + } + } + } } ////////////////////////////////////////////////////////////// diff --git a/src/apps/common/apputils.h b/src/apps/common/apputils.h index 76a3ba7..e1a2e46 100644 --- a/src/apps/common/apputils.h +++ b/src/apps/common/apputils.h @@ -36,8 +36,8 @@ #include "ns_turn_openssl.h" #include "ns_turn_ioaddr.h" -#include "ns_turn_msg_defs.h" #include "ns_turn_ioalib.h" +#include "ns_turn_msg_defs.h" #ifdef __cplusplus extern "C" { @@ -68,48 +68,48 @@ extern int IS_TURN_SERVER; #if defined(TURN_NO_TLS) - #define TLS_SUPPORTED 0 - #define TLSv1_1_SUPPORTED 0 - #define TLSv1_2_SUPPORTED 0 +#define TLS_SUPPORTED 0 +#define TLSv1_1_SUPPORTED 0 +#define TLSv1_2_SUPPORTED 0 #else - #define TLS_SUPPORTED 1 +#define TLS_SUPPORTED 1 - #if defined(SSL_OP_NO_TLSv1_1) - #define TLSv1_1_SUPPORTED 1 - #else - #define TLSv1_1_SUPPORTED 0 - #endif +#if defined(SSL_OP_NO_TLSv1_1) +#define TLSv1_1_SUPPORTED 1 +#else +#define TLSv1_1_SUPPORTED 0 +#endif - #if defined(SSL_OP_NO_TLSv1_2) - #define TLSv1_2_SUPPORTED 1 - #else - #define TLSv1_2_SUPPORTED 0 - #endif - - #if defined(SSL_OP_NO_TLSv1_3) - #define TLSv1_3_SUPPORTED 1 - #else - #define TLSv1_3_SUPPORTED 0 - #endif +#if defined(SSL_OP_NO_TLSv1_2) +#define TLSv1_2_SUPPORTED 1 +#else +#define TLSv1_2_SUPPORTED 0 +#endif + +#if defined(SSL_OP_NO_TLSv1_3) +#define TLSv1_3_SUPPORTED 1 +#else +#define TLSv1_3_SUPPORTED 0 +#endif #endif #if defined(TURN_NO_DTLS) || (!defined(DTLS_CTRL_LISTEN) && (OPENSSL_VERSION_NUMBER < 0x10100000L)) - #define DTLS_SUPPORTED 0 - #define DTLSv1_2_SUPPORTED 0 +#define DTLS_SUPPORTED 0 +#define DTLSv1_2_SUPPORTED 0 #else - #define DTLS_SUPPORTED 1 +#define DTLS_SUPPORTED 1 #if defined(SSL_OP_NO_DTLSv1_2) - #define DTLSv1_2_SUPPORTED 1 - #else - #define DTLSv1_2_SUPPORTED 0 - #endif +#define DTLSv1_2_SUPPORTED 1 +#else +#define DTLSv1_2_SUPPORTED 0 +#endif #endif @@ -122,16 +122,16 @@ extern int IS_TURN_SERVER; /////////// SSL ////////////////////////// enum _TURN_TLS_TYPE { - TURN_TLS_NO=0, - TURN_TLS_SSL23, - TURN_TLS_v1_0, + TURN_TLS_NO = 0, + TURN_TLS_SSL23, + TURN_TLS_v1_0, #if TLSv1_1_SUPPORTED - TURN_TLS_v1_1, + TURN_TLS_v1_1, #if TLSv1_2_SUPPORTED - TURN_TLS_v1_2, + TURN_TLS_v1_2, #endif #endif - TURN_TLS_TOTAL + TURN_TLS_TOTAL }; typedef enum _TURN_TLS_TYPE TURN_TLS_TYPE; @@ -139,19 +139,24 @@ typedef enum _TURN_TLS_TYPE TURN_TLS_TYPE; //////////////////////////////////////////// struct _oauth_key_data_raw { - char kid[OAUTH_KID_SIZE+1]; - char ikm_key[OAUTH_KEY_SIZE+1]; - uint64_t timestamp; - uint32_t lifetime; - char as_rs_alg[OAUTH_ALG_SIZE+1]; - char realm[STUN_MAX_REALM_SIZE+1]; + char kid[OAUTH_KID_SIZE + 1]; + char ikm_key[OAUTH_KEY_SIZE + 1]; + uint64_t timestamp; + uint32_t lifetime; + char as_rs_alg[OAUTH_ALG_SIZE + 1]; + char realm[STUN_MAX_REALM_SIZE + 1]; }; typedef struct _oauth_key_data_raw oauth_key_data_raw; ////////////////////////////////////////// -#define EVENT_DEL(ev) if(ev) { event_del(ev); event_free(ev); ev=NULL; } +#define EVENT_DEL(ev) \ + if (ev) { \ + event_del(ev); \ + event_free(ev); \ + ev = NULL; \ + } ////////////////////////////////////////// @@ -175,20 +180,28 @@ int set_sock_buf_size(evutil_socket_t fd, int sz); int socket_init(void); int socket_set_reusable(evutil_socket_t fd, int reusable, SOCKET_TYPE st); -int sock_bind_to_device(evutil_socket_t fd, const unsigned char* ifname); +int sock_bind_to_device(evutil_socket_t fd, const unsigned char *ifname); int socket_set_nonblocking(evutil_socket_t fd); int socket_tcp_set_keepalive(evutil_socket_t fd, SOCKET_TYPE st); -int addr_connect(evutil_socket_t fd, const ioa_addr* addr, int *out_errno); +int addr_connect(evutil_socket_t fd, const ioa_addr *addr, int *out_errno); -int addr_bind(evutil_socket_t fd, const ioa_addr* addr, int reusable, int debug, SOCKET_TYPE st); +int addr_bind(evutil_socket_t fd, const ioa_addr *addr, int reusable, int debug, SOCKET_TYPE st); int addr_get_from_sock(evutil_socket_t fd, ioa_addr *addr); int handle_socket_error(void); -#define CORRECT_RAW_TTL(ttl) do { if(ttl<0 || ttl>255) ttl=TTL_DEFAULT; } while(0) -#define CORRECT_RAW_TOS(tos) do { if(tos<0 || tos>255) tos=TOS_DEFAULT; } while(0) +#define CORRECT_RAW_TTL(ttl) \ + do { \ + if (ttl < 0 || ttl > 255) \ + ttl = TTL_DEFAULT; \ + } while (0) +#define CORRECT_RAW_TOS(tos) \ + do { \ + if (tos < 0 || tos > 255) \ + tos = TOS_DEFAULT; \ + } while (0) int set_raw_socket_tos(evutil_socket_t fd, int family, int tos); int set_raw_socket_ttl(evutil_socket_t fd, int family, int ttl); @@ -210,51 +223,47 @@ unsigned long get_system_number_of_cpus(void); #define MTU_STEP (68) int set_socket_df(evutil_socket_t fd, int family, int value); -int set_mtu_df(SSL* ssl, evutil_socket_t fd, int family, int mtu, int df_value, int verbose); -int decrease_mtu(SSL* ssl, int mtu, int verbose); +int set_mtu_df(SSL *ssl, evutil_socket_t fd, int family, int mtu, int df_value, int verbose); +int decrease_mtu(SSL *ssl, int mtu, int verbose); int get_socket_mtu(evutil_socket_t fd, int family, int verbose); ////////////////// Misc utils ///////////////////////// -char *skip_blanks(char* s); +char *skip_blanks(char *s); #if defined(_MSC_VER) - #define CLOCK_REALTIME 0 - int clock_gettime(int X, struct timeval* tv); - int gettimeofday(struct timeval* tp, void* tzp); +#define CLOCK_REALTIME 0 +int clock_gettime(int X, struct timeval *tv); +int gettimeofday(struct timeval *tp, void *tzp); - char* dirname(char* path); +char *dirname(char *path); #endif #if defined(WINDOWS) - int getdomainname(char* name, size_t len); - // wchar convert to char - char* _WTA(__in wchar_t* pszInBufBuf, __in int nInSize, __out char** pszOutBuf, __out int* pnOutSize); - // char convert to wchar - wchar_t* _ATW(__in char* pszInBuf, __in int nInSize, __out wchar_t** pszOutBuf, __out int* pnOutSize); +int getdomainname(char *name, size_t len); +// wchar convert to char +char *_WTA(__in wchar_t *pszInBufBuf, __in int nInSize, __out char **pszOutBuf, __out int *pnOutSize); +// char convert to wchar +wchar_t *_ATW(__in char *pszInBuf, __in int nInSize, __out wchar_t **pszOutBuf, __out int *pnOutSize); #endif ////////////////// File search //////////////////////// -char* find_config_file(const char *config_file, int print_file_name); +char *find_config_file(const char *config_file, int print_file_name); void set_execdir(void); void print_abs_file_name(const char *msg1, const char *msg2, const char *fn); ////////////////// Base64 ///////////////////////////// -char *base64_encode(const unsigned char *data, - size_t input_length, - size_t *output_length); +char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length); void build_base64_decoding_table(void); -unsigned char *base64_decode(const char *data, - size_t input_length, - size_t *output_length); +unsigned char *base64_decode(const char *data, size_t input_length, size_t *output_length); ///////////// SSL //////////////// -const char* turn_get_ssl_method(SSL *ssl, const char* mdefault); +const char *turn_get_ssl_method(SSL *ssl, const char *mdefault); ////////////// OAUTH UTILS //////////////// diff --git a/src/apps/common/hiredis_libevent2.c b/src/apps/common/hiredis_libevent2.c index 19bf147..6a58b4b 100644 --- a/src/apps/common/hiredis_libevent2.c +++ b/src/apps/common/hiredis_libevent2.c @@ -33,34 +33,32 @@ #include "hiredis_libevent2.h" #include "ns_turn_utils.h" -#include #include +#include -#include #include +#include //////////////// Libevent context /////////////////////// -struct redisLibeventEvents -{ - redisAsyncContext *context; - int invalid; - int allocated; - struct event_base *base; - struct event *rev, *wev; - int rev_set, wev_set; - char *ip; - int port; - char *pwd; - int db; +struct redisLibeventEvents { + redisAsyncContext *context; + int invalid; + int allocated; + struct event_base *base; + struct event *rev, *wev; + int rev_set, wev_set; + char *ip; + int port; + char *pwd; + int db; }; ///////////// Messages //////////////////////////// -struct redis_message -{ - char format[513]; - char arg[513]; +struct redis_message { + char format[513]; + char arg[513]; }; /////////////////// forward declarations /////////////// @@ -69,180 +67,175 @@ static void redis_reconnect(struct redisLibeventEvents *e); ////////////////////////////////////////////////////////// -static int redis_le_valid(struct redisLibeventEvents *e) -{ - return (e && !(e->invalid) && (e->context)); -} +static int redis_le_valid(struct redisLibeventEvents *e) { return (e && !(e->invalid) && (e->context)); } /////////////////// Callbacks //////////////////////////// static void redisLibeventReadEvent(int fd, short event, void *arg) { - ((void)fd); ((void)event); - struct redisLibeventEvents *e = (struct redisLibeventEvents*)arg; - if(redis_le_valid(e)) { - { - char buf[8]; - int len = 0; - do { - len = recv(fd,buf,sizeof(buf),MSG_PEEK); - } while((len<0)&&(errno == EINTR)); - if(len<1) { - e->invalid = 1; - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Redis connection broken: e=0x%lx\n", __FUNCTION__, ((unsigned long)e)); - } - } - if(redis_le_valid(e)) { - redisAsyncHandleRead(e->context); - } + ((void)fd); + ((void)event); + struct redisLibeventEvents *e = (struct redisLibeventEvents *)arg; + if (redis_le_valid(e)) { + { + char buf[8]; + int len = 0; + do { + len = recv(fd, buf, sizeof(buf), MSG_PEEK); + } while ((len < 0) && (errno == EINTR)); + if (len < 1) { + e->invalid = 1; + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Redis connection broken: e=0x%lx\n", __FUNCTION__, ((unsigned long)e)); + } + } + if (redis_le_valid(e)) { + redisAsyncHandleRead(e->context); + } } else { - redis_reconnect(e); + redis_reconnect(e); } } static void redisLibeventWriteEvent(int fd, short event, void *arg) { - ((void)fd); ((void)event); - struct redisLibeventEvents *e = (struct redisLibeventEvents*)arg; - if(redis_le_valid(e)) { + ((void)fd); + ((void)event); + struct redisLibeventEvents *e = (struct redisLibeventEvents *)arg; + if (redis_le_valid(e)) { redisAsyncHandleWrite(e->context); } } static void redisLibeventAddRead(void *privdata) { - struct redisLibeventEvents *e = (struct redisLibeventEvents*)privdata; - if(e && (e->rev) && !(e->rev_set)) { - event_add(e->rev,NULL); + struct redisLibeventEvents *e = (struct redisLibeventEvents *)privdata; + if (e && (e->rev) && !(e->rev_set)) { + event_add(e->rev, NULL); e->rev_set = 1; } } static void redisLibeventDelRead(void *privdata) { - struct redisLibeventEvents *e = (struct redisLibeventEvents*)privdata; - if(e && e->rev && e->rev_set) { - event_del(e->rev); - e->rev_set = 0; - } + struct redisLibeventEvents *e = (struct redisLibeventEvents *)privdata; + if (e && e->rev && e->rev_set) { + event_del(e->rev); + e->rev_set = 0; + } } static void redisLibeventAddWrite(void *privdata) { - struct redisLibeventEvents *e = (struct redisLibeventEvents*)privdata; - if(e && (e->wev) && !(e->wev_set)) { - event_add(e->wev,NULL); - e->wev_set = 1; - } + struct redisLibeventEvents *e = (struct redisLibeventEvents *)privdata; + if (e && (e->wev) && !(e->wev_set)) { + event_add(e->wev, NULL); + e->wev_set = 1; + } } static void redisLibeventDelWrite(void *privdata) { - struct redisLibeventEvents *e = (struct redisLibeventEvents*)privdata; - if(e && e->wev && e->wev_set) { + struct redisLibeventEvents *e = (struct redisLibeventEvents *)privdata; + if (e && e->wev && e->wev_set) { event_del(e->wev); e->wev_set = 0; } } -static void redisLibeventCleanup(void *privdata) -{ +static void redisLibeventCleanup(void *privdata) { - if (privdata) { + if (privdata) { - struct redisLibeventEvents *e = (struct redisLibeventEvents *) privdata; - if (e->allocated) { - if (e->rev) { - if(e->rev_set) - event_del(e->rev); - event_free(e->rev); - e->rev = NULL; - } - e->rev_set = 0; - if (e->wev) { - if(e->wev_set) - event_del(e->wev); - event_free(e->wev); - e->wev = NULL; - } - e->wev_set = 0; - e->context = NULL; - } - } + struct redisLibeventEvents *e = (struct redisLibeventEvents *)privdata; + if (e->allocated) { + if (e->rev) { + if (e->rev_set) + event_del(e->rev); + event_free(e->rev); + e->rev = NULL; + } + e->rev_set = 0; + if (e->wev) { + if (e->wev_set) + event_del(e->wev); + event_free(e->wev); + e->wev = NULL; + } + e->wev_set = 0; + e->context = NULL; + } + } } ///////////////////////// Send-receive /////////////////////////// -int is_redis_asyncconn_good(redis_context_handle rch) -{ - if(rch) { - struct redisLibeventEvents *e = (struct redisLibeventEvents*)rch; - if(redis_le_valid(e)) - return 1; - } - return 0; +int is_redis_asyncconn_good(redis_context_handle rch) { + if (rch) { + struct redisLibeventEvents *e = (struct redisLibeventEvents *)rch; + if (redis_le_valid(e)) + return 1; + } + return 0; } -void send_message_to_redis(redis_context_handle rch, const char *command, const char *key, const char *format,...) -{ - if(!rch) { - return; - } else { +void send_message_to_redis(redis_context_handle rch, const char *command, const char *key, const char *format, ...) { + if (!rch) { + return; + } else { - struct redisLibeventEvents *e = (struct redisLibeventEvents*)rch; + struct redisLibeventEvents *e = (struct redisLibeventEvents *)rch; - if(!redis_le_valid(e)) { - redis_reconnect(e); - } + if (!redis_le_valid(e)) { + redis_reconnect(e); + } - if(!redis_le_valid(e)) { - ; - } else { + if (!redis_le_valid(e)) { + ; + } else { - redisAsyncContext *ac=e->context; + redisAsyncContext *ac = e->context; - struct redis_message rm; + struct redis_message rm; - snprintf(rm.format,sizeof(rm.format)-3,"%s %s ", command, key); - strcpy(rm.format+strlen(rm.format),"%s"); + snprintf(rm.format, sizeof(rm.format) - 3, "%s %s ", command, key); + strcpy(rm.format + strlen(rm.format), "%s"); - va_list args; - va_start (args, format); - vsnprintf(rm.arg, sizeof(rm.arg)-1, format, args); - va_end (args); + va_list args; + va_start(args, format); + vsnprintf(rm.arg, sizeof(rm.arg) - 1, format, args); + va_end(args); - if((redisAsyncCommand(ac, NULL, e, rm.format, rm.arg)!=REDIS_OK)) { - e->invalid = 1; - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Redis connection broken: ac=0x%lx, e=0x%lx\n", __FUNCTION__,(unsigned long)ac,(unsigned long)e); - } - } - } + if ((redisAsyncCommand(ac, NULL, e, rm.format, rm.arg) != REDIS_OK)) { + e->invalid = 1; + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Redis connection broken: ac=0x%lx, e=0x%lx\n", __FUNCTION__, + (unsigned long)ac, (unsigned long)e); + } + } + } } ///////////////////////// Attach ///////////////////////////////// -redis_context_handle redisLibeventAttach(struct event_base *base, char *ip0, int port0, char *pwd, int db) -{ +redis_context_handle redisLibeventAttach(struct event_base *base, char *ip0, int port0, char *pwd, int db) { struct redisLibeventEvents *e = NULL; redisAsyncContext *ac = NULL; char ip[256]; - if(ip0 && ip0[0]) - STRCPY(ip,ip0); + if (ip0 && ip0[0]) + STRCPY(ip, ip0); else - strncpy(ip,"127.0.0.1",sizeof(ip)); + strncpy(ip, "127.0.0.1", sizeof(ip)); int port = DEFAULT_REDIS_PORT; - if(port0>0) - port=port0; + if (port0 > 0) + port = port0; ac = redisAsyncConnect(ip, port); if (!ac) { - fprintf(stderr,"Error: redisAsyncConnect returned NULL\n"); - return NULL; - } - else if (ac->err) { - fprintf(stderr,"Error: %s:%s\n", ac->errstr, ac->c.errstr); - return NULL; + fprintf(stderr, "Error: redisAsyncConnect returned NULL\n"); + return NULL; + } else if (ac->err) { + fprintf(stderr, "Error: %s:%s\n", ac->errstr, ac->c.errstr); + return NULL; } /* Create container for context and r/w events */ - e = (struct redisLibeventEvents*)malloc(sizeof(struct redisLibeventEvents)); + e = (struct redisLibeventEvents *)malloc(sizeof(struct redisLibeventEvents)); memset(e, 0, sizeof(struct redisLibeventEvents)); e->allocated = 1; @@ -250,8 +243,8 @@ redis_context_handle redisLibeventAttach(struct event_base *base, char *ip0, int e->base = base; e->ip = strdup(ip); e->port = port; - if(pwd) - e->pwd = strdup(pwd); + if (pwd) + e->pwd = strdup(pwd); e->db = db; /* Register functions to start/stop listening for events */ @@ -264,74 +257,69 @@ redis_context_handle redisLibeventAttach(struct event_base *base, char *ip0, int ac->ev.data = e; /* Initialize and install read/write events */ - e->rev = event_new(e->base,e->context->c.fd, - EV_READ|EV_PERSIST,redisLibeventReadEvent, - e); + e->rev = event_new(e->base, e->context->c.fd, EV_READ | EV_PERSIST, redisLibeventReadEvent, e); - e->wev = event_new(e->base,e->context->c.fd, - EV_WRITE,redisLibeventWriteEvent, - e); + e->wev = event_new(e->base, e->context->c.fd, EV_WRITE, redisLibeventWriteEvent, e); if (e->rev == NULL || e->wev == NULL) { - free(e); - return NULL; + free(e); + return NULL; } - + event_add(e->wev, NULL); e->wev_set = 1; - //Authentication - if(redis_le_valid(e) && pwd) { - if(redisAsyncCommand(ac, NULL, e, "AUTH %s", pwd)!=REDIS_OK) { - e->invalid = 1; - } + // Authentication + if (redis_le_valid(e) && pwd) { + if (redisAsyncCommand(ac, NULL, e, "AUTH %s", pwd) != REDIS_OK) { + e->invalid = 1; + } } - if(redis_le_valid(e)) { - if(redisAsyncCommand(ac, NULL, e, "SELECT %d", db)!=REDIS_OK) { - e->invalid = 1; - } + if (redis_le_valid(e)) { + if (redisAsyncCommand(ac, NULL, e, "SELECT %d", db) != REDIS_OK) { + e->invalid = 1; + } } return (redis_context_handle)e; } -static void redis_reconnect(struct redisLibeventEvents *e) -{ - if(!e || !(e->allocated)) - return; +static void redis_reconnect(struct redisLibeventEvents *e) { + if (!e || !(e->allocated)) + return; if (e->rev) { - if(e->rev_set) - event_del(e->rev); - event_free(e->rev); - e->rev = NULL; + if (e->rev_set) + event_del(e->rev); + event_free(e->rev); + e->rev = NULL; } e->rev_set = 0; if (e->wev) { - if(e->wev_set) - event_del(e->wev); - event_free(e->wev); - e->wev = NULL; + if (e->wev_set) + event_del(e->wev); + event_free(e->wev); + e->wev = NULL; } e->wev_set = 0; redisAsyncContext *ac = NULL; - if(e->context) { - redisAsyncFree(e->context); - e->context = NULL; + if (e->context) { + redisAsyncFree(e->context); + e->context = NULL; } ac = redisAsyncConnect(e->ip, e->port); - if(!ac) { - return; + if (!ac) { + return; } e->context = ac; - /* Register functions to start/stop listening for events */ + /* Register functions to start/stop listening for events */ ac->ev.addRead = redisLibeventAddRead; ac->ev.delRead = redisLibeventDelRead; ac->ev.addWrite = redisLibeventAddWrite; @@ -341,37 +329,33 @@ static void redis_reconnect(struct redisLibeventEvents *e) ac->ev.data = e; /* Initialize and install read/write events */ - e->rev = event_new(e->base,e->context->c.fd, - EV_READ,redisLibeventReadEvent, - e); + e->rev = event_new(e->base, e->context->c.fd, EV_READ, redisLibeventReadEvent, e); - e->wev = event_new(e->base,e->context->c.fd, - EV_WRITE,redisLibeventWriteEvent, - e); + e->wev = event_new(e->base, e->context->c.fd, EV_WRITE, redisLibeventWriteEvent, e); if (e->rev == NULL || e->wev == NULL) { - return; + return; } event_add(e->wev, NULL); e->wev_set = 1; e->invalid = 0; - //Authentication - if(redis_le_valid(e) && e->pwd) { - if(redisAsyncCommand(ac, NULL, e, "AUTH %s", e->pwd)!=REDIS_OK) { - e->invalid = 1; - } + // Authentication + if (redis_le_valid(e) && e->pwd) { + if (redisAsyncCommand(ac, NULL, e, "AUTH %s", e->pwd) != REDIS_OK) { + e->invalid = 1; + } } - if(redis_le_valid(e)) { - if(redisAsyncCommand(ac, NULL, e, "SELECT %d", e->db)!=REDIS_OK) { - e->invalid = 1; - } + if (redis_le_valid(e)) { + if (redisAsyncCommand(ac, NULL, e, "SELECT %d", e->db) != REDIS_OK) { + e->invalid = 1; + } } - if(redis_le_valid(e)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: Re-connected to redis, async\n", __FUNCTION__); + if (redis_le_valid(e)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: Re-connected to redis, async\n", __FUNCTION__); } } @@ -379,4 +363,3 @@ static void redis_reconnect(struct redisLibeventEvents *e) #endif /* TURN_NO_HIREDIS */ - diff --git a/src/apps/common/hiredis_libevent2.h b/src/apps/common/hiredis_libevent2.h index 63369b0..cc0b746 100644 --- a/src/apps/common/hiredis_libevent2.h +++ b/src/apps/common/hiredis_libevent2.h @@ -42,16 +42,15 @@ extern "C" { #define DEFAULT_REDIS_PORT (6379) -typedef void* redis_context_handle; +typedef void *redis_context_handle; ////////////////////////////////////// #if !defined(TURN_NO_HIREDIS) - redis_context_handle redisLibeventAttach(struct event_base *base, char *ip, int port, char *pwd, int db); -void send_message_to_redis(redis_context_handle rch, const char *command, const char *key, const char *format,...); +void send_message_to_redis(redis_context_handle rch, const char *command, const char *key, const char *format, ...); int is_redis_asyncconn_good(redis_context_handle rch); diff --git a/src/apps/common/ns_turn_openssl.h b/src/apps/common/ns_turn_openssl.h index 8272f99..3289c93 100644 --- a/src/apps/common/ns_turn_openssl.h +++ b/src/apps/common/ns_turn_openssl.h @@ -31,15 +31,15 @@ #ifndef __NST_OPENSSL_LIB__ #define __NST_OPENSSL_LIB__ -#include -#include -#include #include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include #endif //__NST_OPENSSL_LIB__ diff --git a/src/apps/common/ns_turn_utils.c b/src/apps/common/ns_turn_utils.c index 099afbe..62b85ad 100644 --- a/src/apps/common/ns_turn_utils.c +++ b/src/apps/common/ns_turn_utils.c @@ -38,24 +38,23 @@ #include -#if defined(__unix__) || defined(unix) || defined(__APPLE__) \ - || defined(__DARWIN__) || defined(__MACH__) - #include +#if defined(__unix__) || defined(unix) || defined(__APPLE__) || defined(__DARWIN__) || defined(__MACH__) +#include #endif #include -#include #include +#include #include #if !defined(WINDOWS) - #include - #include - #ifdef SYS_gettid - #define gettid() ((pid_t)syscall(SYS_gettid)) - #endif +#include +#include +#ifdef SYS_gettid +#define gettid() ((pid_t)syscall(SYS_gettid)) +#endif #endif ////////// LOG TIME OPTIMIZATION /////////// @@ -66,12 +65,11 @@ static volatile turn_time_t log_start_time = 0; volatile int _log_time_value_set = 0; volatile turn_time_t _log_time_value = 0; -static inline turn_time_t log_time(void) -{ - if(!log_start_time) +static inline turn_time_t log_time(void) { + if (!log_start_time) log_start_time = turn_time(); - if(_log_time_value_set) + if (_log_time_value_set) return (_log_time_value - log_start_time); return (turn_time() - log_start_time); @@ -82,10 +80,10 @@ static inline turn_time_t log_time(void) #define MAGIC_CODE (0xEFCD1983) int turn_mutex_lock(const turn_mutex *mutex) { - if(mutex && mutex->mutex && (mutex->data == MAGIC_CODE)) { + if (mutex && mutex->mutex && (mutex->data == MAGIC_CODE)) { int ret = 0; - ret = pthread_mutex_lock((pthread_mutex_t*)mutex->mutex); - if(ret<0) { + ret = pthread_mutex_lock((pthread_mutex_t *)mutex->mutex); + if (ret < 0) { perror("Mutex lock"); } return ret; @@ -96,10 +94,10 @@ int turn_mutex_lock(const turn_mutex *mutex) { } int turn_mutex_unlock(const turn_mutex *mutex) { - if(mutex && mutex->mutex && (mutex->data == MAGIC_CODE)) { + if (mutex && mutex->mutex && (mutex->data == MAGIC_CODE)) { int ret = 0; - ret = pthread_mutex_unlock((pthread_mutex_t*)mutex->mutex); - if(ret<0) { + ret = pthread_mutex_unlock((pthread_mutex_t *)mutex->mutex); + if (ret < 0) { perror("Mutex unlock"); } return ret; @@ -109,50 +107,49 @@ int turn_mutex_unlock(const turn_mutex *mutex) { } } -int turn_mutex_init(turn_mutex* mutex) { - if(mutex) { - mutex->data=MAGIC_CODE; - mutex->mutex=malloc(sizeof(pthread_mutex_t)); - pthread_mutex_init((pthread_mutex_t*)mutex->mutex,NULL); +int turn_mutex_init(turn_mutex *mutex) { + if (mutex) { + mutex->data = MAGIC_CODE; + mutex->mutex = malloc(sizeof(pthread_mutex_t)); + pthread_mutex_init((pthread_mutex_t *)mutex->mutex, NULL); return 0; } else { return -1; } } -int turn_mutex_init_recursive(turn_mutex* mutex) { - int ret = -1; - if (mutex) { - pthread_mutexattr_t attr; - if (pthread_mutexattr_init(&attr) < 0) { - perror("Cannot init mutex attr"); - } else { - if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) < 0) { - perror("Cannot set type on mutex attr"); - } else { - mutex->mutex = malloc(sizeof(pthread_mutex_t)); - mutex->data = MAGIC_CODE; - if ((ret = pthread_mutex_init((pthread_mutex_t*) mutex->mutex, - &attr)) < 0) { - perror("Cannot init mutex"); - mutex->data = 0; - free(mutex->mutex); - mutex->mutex = NULL; - } - } - pthread_mutexattr_destroy(&attr); - } - } +int turn_mutex_init_recursive(turn_mutex *mutex) { + int ret = -1; + if (mutex) { + pthread_mutexattr_t attr; + if (pthread_mutexattr_init(&attr) < 0) { + perror("Cannot init mutex attr"); + } else { + if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) < 0) { + perror("Cannot set type on mutex attr"); + } else { + mutex->mutex = malloc(sizeof(pthread_mutex_t)); + mutex->data = MAGIC_CODE; + if ((ret = pthread_mutex_init((pthread_mutex_t *)mutex->mutex, &attr)) < 0) { + perror("Cannot init mutex"); + mutex->data = 0; + free(mutex->mutex); + mutex->mutex = NULL; + } + } + pthread_mutexattr_destroy(&attr); + } + } return ret; } -int turn_mutex_destroy(turn_mutex* mutex) { - if(mutex && mutex->mutex && mutex->data == MAGIC_CODE) { +int turn_mutex_destroy(turn_mutex *mutex) { + if (mutex && mutex->mutex && mutex->data == MAGIC_CODE) { int ret = 0; - ret = pthread_mutex_destroy((pthread_mutex_t*)(mutex->mutex)); + ret = pthread_mutex_destroy((pthread_mutex_t *)(mutex->mutex)); free(mutex->mutex); - mutex->mutex=NULL; - mutex->data=0; + mutex->mutex = NULL; + mutex->data = 0; return ret; } else { return 0; @@ -163,629 +160,582 @@ int turn_mutex_destroy(turn_mutex* mutex) { /* syslog facility */ /*BVB-594 Syslog facility */ -static char* str_fac[]={"LOG_AUTH","LOG_CRON","LOG_DAEMON", - "LOG_KERN","LOG_LOCAL0","LOG_LOCAL1", - "LOG_LOCAL2","LOG_LOCAL3","LOG_LOCAL4","LOG_LOCAL5", - "LOG_LOCAL6","LOG_LOCAL7","LOG_LPR","LOG_MAIL", - "LOG_NEWS","LOG_USER","LOG_UUCP", - "LOG_AUTHPRIV","LOG_SYSLOG", - 0}; +static char *str_fac[] = {"LOG_AUTH", "LOG_CRON", "LOG_DAEMON", "LOG_KERN", "LOG_LOCAL0", + "LOG_LOCAL1", "LOG_LOCAL2", "LOG_LOCAL3", "LOG_LOCAL4", "LOG_LOCAL5", + "LOG_LOCAL6", "LOG_LOCAL7", "LOG_LPR", "LOG_MAIL", "LOG_NEWS", + "LOG_USER", "LOG_UUCP", "LOG_AUTHPRIV", "LOG_SYSLOG", 0}; #if defined(__unix__) || defined(unix) || defined(__APPLE__) -static int int_fac[]={LOG_AUTH , LOG_CRON , LOG_DAEMON , - LOG_KERN , LOG_LOCAL0 , LOG_LOCAL1 , - LOG_LOCAL2 , LOG_LOCAL3 , LOG_LOCAL4 , LOG_LOCAL5 , - LOG_LOCAL6 , LOG_LOCAL7 , LOG_LPR , LOG_MAIL , - LOG_NEWS , LOG_USER , LOG_UUCP, - LOG_AUTHPRIV,LOG_SYSLOG, - 0}; +static int int_fac[] = {LOG_AUTH, LOG_CRON, LOG_DAEMON, LOG_KERN, LOG_LOCAL0, LOG_LOCAL1, LOG_LOCAL2, + LOG_LOCAL3, LOG_LOCAL4, LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_LPR, LOG_MAIL, + LOG_NEWS, LOG_USER, LOG_UUCP, LOG_AUTHPRIV, LOG_SYSLOG, 0}; static int syslog_facility = 0; -static int str_to_syslog_facility(char *s) -{ - int i; - for (i=0; str_fac[i]; i++) { - if (!strcasecmp(s,str_fac[i])) - return int_fac[i]; - } - return -1; +static int str_to_syslog_facility(char *s) { + int i; + for (i = 0; str_fac[i]; i++) { + if (!strcasecmp(s, str_fac[i])) + return int_fac[i]; + } + return -1; } #endif -void set_syslog_facility(char *val) -{ - if(val == NULL){ - return; - } +void set_syslog_facility(char *val) { + if (val == NULL) { + return; + } #if defined(__unix__) || defined(unix) || defined(__APPLE__) - int tmp = str_to_syslog_facility(val); - if(tmp == -1){ - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: invalid syslog-facility value (%s); ignored.\n", val); - return; - } - syslog_facility = tmp; + int tmp = str_to_syslog_facility(val); + if (tmp == -1) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: invalid syslog-facility value (%s); ignored.\n", val); + return; + } + syslog_facility = tmp; #endif } #if defined(TURN_LOG_FUNC_IMPL) -extern void TURN_LOG_FUNC_IMPL(TURN_LOG_LEVEL level, const char* format, va_list args); +extern void TURN_LOG_FUNC_IMPL(TURN_LOG_LEVEL level, const char *format, va_list args); #endif static int no_stdout_log = 0; -void set_no_stdout_log(int val) -{ - no_stdout_log = val; -} +void set_no_stdout_log(int val) { no_stdout_log = val; } #define MAX_LOG_TIMESTAMP_FORMAT_LEN 48 static char turn_log_timestamp_format[MAX_LOG_TIMESTAMP_FORMAT_LEN] = "%FT%T%z"; -void set_turn_log_timestamp_format(char* new_format) -{ - strncpy(turn_log_timestamp_format, new_format, MAX_LOG_TIMESTAMP_FORMAT_LEN-1); +void set_turn_log_timestamp_format(char *new_format) { + strncpy(turn_log_timestamp_format, new_format, MAX_LOG_TIMESTAMP_FORMAT_LEN - 1); } int use_new_log_timestamp_format = 0; -void addr_debug_print(int verbose, const ioa_addr *addr, const char* s) -{ - if (verbose) { - if (!addr) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: EMPTY\n", s); - } else { - char addrbuf[INET6_ADDRSTRLEN]; - if (!s) - s = ""; - if (addr->ss.sa_family == AF_INET) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "IPv4. %s: %s:%d\n", s, inet_ntop(AF_INET, - &addr->s4.sin_addr, addrbuf, INET6_ADDRSTRLEN), - nswap16(addr->s4.sin_port)); - } else if (addr->ss.sa_family == AF_INET6) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "IPv6. %s: %s:%d\n", s, inet_ntop(AF_INET6, - &addr->s6.sin6_addr, addrbuf, INET6_ADDRSTRLEN), - nswap16(addr->s6.sin6_port)); - } else { - if (addr_any_no_port(addr)) { - TURN_LOG_FUNC( - TURN_LOG_LEVEL_INFO, - "IP. %s: 0.0.0.0:%d\n", - s, - nswap16(addr->s4.sin_port)); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: wrong IP address family: %d\n", s, - (int) (addr->ss.sa_family)); - } - } - } - } +void addr_debug_print(int verbose, const ioa_addr *addr, const char *s) { + if (verbose) { + if (!addr) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: EMPTY\n", s); + } else { + char addrbuf[INET6_ADDRSTRLEN]; + if (!s) + s = ""; + if (addr->ss.sa_family == AF_INET) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "IPv4. %s: %s:%d\n", s, + inet_ntop(AF_INET, &addr->s4.sin_addr, addrbuf, INET6_ADDRSTRLEN), nswap16(addr->s4.sin_port)); + } else if (addr->ss.sa_family == AF_INET6) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "IPv6. %s: %s:%d\n", s, + inet_ntop(AF_INET6, &addr->s6.sin6_addr, addrbuf, INET6_ADDRSTRLEN), nswap16(addr->s6.sin6_port)); + } else { + if (addr_any_no_port(addr)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "IP. %s: 0.0.0.0:%d\n", s, nswap16(addr->s4.sin_port)); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: wrong IP address family: %d\n", s, (int)(addr->ss.sa_family)); + } + } + } + } } /*************************************/ #define FILE_STR_LEN (1025) -static FILE* _rtpfile = NULL; +static FILE *_rtpfile = NULL; static int to_syslog = 0; static int simple_log = 0; -static char log_fn[FILE_STR_LEN]="\0"; -static char log_fn_base[FILE_STR_LEN]="\0"; +static char log_fn[FILE_STR_LEN] = "\0"; +static char log_fn_base[FILE_STR_LEN] = "\0"; static volatile int to_reset_log_file = 0; static turn_mutex log_mutex; static int log_mutex_inited = 0; static void log_lock(void) { - if(!log_mutex_inited) { - log_mutex_inited=1; - turn_mutex_init_recursive(&log_mutex); - } - turn_mutex_lock(&log_mutex); + if (!log_mutex_inited) { + log_mutex_inited = 1; + turn_mutex_init_recursive(&log_mutex); + } + turn_mutex_lock(&log_mutex); } -static void log_unlock(void) { - turn_mutex_unlock(&log_mutex); -} +static void log_unlock(void) { turn_mutex_unlock(&log_mutex); } static void get_date(char *s, size_t sz) { - time_t curtm; - struct tm* tm_info; + time_t curtm; + struct tm *tm_info; - curtm = time(NULL); - tm_info = localtime(&curtm); + curtm = time(NULL); + tm_info = localtime(&curtm); - strftime(s, sz, "%F", tm_info); + strftime(s, sz, "%F", tm_info); } -void set_logfile(const char *fn) -{ - if(fn) { - log_lock(); - if(strcmp(fn,log_fn_base)) { - reset_rtpprintf(); - STRCPY(log_fn_base,fn); - } - log_unlock(); - } +void set_logfile(const char *fn) { + if (fn) { + log_lock(); + if (strcmp(fn, log_fn_base)) { + reset_rtpprintf(); + STRCPY(log_fn_base, fn); + } + log_unlock(); + } } -void set_log_file_line(int set) -{ - _log_file_line_set = set; -} +void set_log_file_line(int set) { _log_file_line_set = set; } -void reset_rtpprintf(void) -{ - log_lock(); - if(_rtpfile) { - if(_rtpfile != stdout) - fclose(_rtpfile); - _rtpfile = NULL; - } - log_unlock(); +void reset_rtpprintf(void) { + log_lock(); + if (_rtpfile) { + if (_rtpfile != stdout) + fclose(_rtpfile); + _rtpfile = NULL; + } + log_unlock(); } #define set_log_file_name(base, f) set_log_file_name_func(base, f, sizeof(f)) -static void set_log_file_name_func(char *base, char *f, size_t fsz) -{ - if(simple_log) { - strncpy(f,base,fsz); - return; - } +static void set_log_file_name_func(char *base, char *f, size_t fsz) { + if (simple_log) { + strncpy(f, base, fsz); + return; + } - char logdate[125]; - char *tail=strdup(".log"); + char logdate[125]; + char *tail = strdup(".log"); - get_date(logdate,sizeof(logdate)); + get_date(logdate, sizeof(logdate)); - char *base1=strdup(base); + char *base1 = strdup(base); - int len=(int)strlen(base1); + int len = (int)strlen(base1); - --len; + --len; - while(len>=0) { - if((base1[len]==' ')||(base1[len]=='\t')) { - base1[len]='_'; - } - --len; - } + while (len >= 0) { + if ((base1[len] == ' ') || (base1[len] == '\t')) { + base1[len] = '_'; + } + --len; + } - len=(int)strlen(base1); + len = (int)strlen(base1); - while(len>=0) { - if(base1[len]=='/') - break; - else if(base1[len]=='.') { - free(tail); - tail=strdup(base1+len); - base1[len]=0; - if(strlen(tail)<2) { - free(tail); - tail = strdup(".log"); - } - break; - } - --len; - } + while (len >= 0) { + if (base1[len] == '/') + break; + else if (base1[len] == '.') { + free(tail); + tail = strdup(base1 + len); + base1[len] = 0; + if (strlen(tail) < 2) { + free(tail); + tail = strdup(".log"); + } + break; + } + --len; + } - len=(int)strlen(base1); - if(len>0 && (base1[len-1]!='/') && (base1[len-1]!='-') && (base1[len-1]!='_')) { - snprintf(f, FILE_STR_LEN, "%s_%s%s", base1,logdate,tail); - } else { - snprintf(f, FILE_STR_LEN, "%s%s%s", base1,logdate,tail); - } + len = (int)strlen(base1); + if (len > 0 && (base1[len - 1] != '/') && (base1[len - 1] != '-') && (base1[len - 1] != '_')) { + snprintf(f, FILE_STR_LEN, "%s_%s%s", base1, logdate, tail); + } else { + snprintf(f, FILE_STR_LEN, "%s%s%s", base1, logdate, tail); + } - free(base1); - free(tail); + free(base1); + free(tail); } -static void sighup_callback_handler(int signum) -{ +static void sighup_callback_handler(int signum) { #if defined(__unix__) || defined(unix) || defined(__APPLE__) - if(signum == SIGHUP) { - to_reset_log_file = 1; - } + if (signum == SIGHUP) { + to_reset_log_file = 1; + } #endif } -static void set_rtpfile(void) -{ - if(to_reset_log_file) { - printf("%s: resetting the log file\n",__FUNCTION__); - reset_rtpprintf(); - to_reset_log_file = 0; - } +static void set_rtpfile(void) { + if (to_reset_log_file) { + printf("%s: resetting the log file\n", __FUNCTION__); + reset_rtpprintf(); + to_reset_log_file = 0; + } - if(to_syslog) { - return; - } else if (!_rtpfile) { + if (to_syslog) { + return; + } else if (!_rtpfile) { #if defined(__unix__) || defined(unix) || defined(__APPLE__) - signal(SIGHUP, sighup_callback_handler); + signal(SIGHUP, sighup_callback_handler); #endif - if(log_fn_base[0]) { - if(!strcmp(log_fn_base,"syslog")) { - _rtpfile = stdout; - to_syslog = 1; - } else if(!strcmp(log_fn_base,"stdout")|| !strcmp(log_fn_base,"-")) { - _rtpfile = stdout; - no_stdout_log = 1; - } else { - set_log_file_name(log_fn_base,log_fn); - _rtpfile = fopen(log_fn, "a"); - if(_rtpfile) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", log_fn); - } - if (!_rtpfile) { - fprintf(stderr,"ERROR: Cannot open log file for writing: %s\n",log_fn); - } else { - return; - } - } - } + if (log_fn_base[0]) { + if (!strcmp(log_fn_base, "syslog")) { + _rtpfile = stdout; + to_syslog = 1; + } else if (!strcmp(log_fn_base, "stdout") || !strcmp(log_fn_base, "-")) { + _rtpfile = stdout; + no_stdout_log = 1; + } else { + set_log_file_name(log_fn_base, log_fn); + _rtpfile = fopen(log_fn, "a"); + if (_rtpfile) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", log_fn); + } + if (!_rtpfile) { + fprintf(stderr, "ERROR: Cannot open log file for writing: %s\n", log_fn); + } else { + return; + } + } + } - if(!_rtpfile) { + if (!_rtpfile) { - char logbase[FILE_STR_LEN]; - char logtail[FILE_STR_LEN]; - char logf[FILE_STR_LEN]; + char logbase[FILE_STR_LEN]; + char logtail[FILE_STR_LEN]; + char logf[FILE_STR_LEN]; - if(simple_log) - snprintf(logtail, FILE_STR_LEN, "turn.log"); - else - snprintf(logtail, FILE_STR_LEN, "turn_%d_", (int)getpid()); + if (simple_log) + snprintf(logtail, FILE_STR_LEN, "turn.log"); + else + snprintf(logtail, FILE_STR_LEN, "turn_%d_", (int)getpid()); - if (snprintf(logbase, FILE_STR_LEN, "/var/log/turnserver/%s", logtail)<0) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "String truncation occured.\n"); + if (snprintf(logbase, FILE_STR_LEN, "/var/log/turnserver/%s", logtail) < 0) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "String truncation occured.\n"); - set_log_file_name(logbase, logf); + set_log_file_name(logbase, logf); - _rtpfile = fopen(logf, "a"); - if(_rtpfile) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf); - else { - if (snprintf(logbase, FILE_STR_LEN, "/var/log/%s", logtail)<0) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "String truncation occured.\n"); + _rtpfile = fopen(logf, "a"); + if (_rtpfile) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf); + else { + if (snprintf(logbase, FILE_STR_LEN, "/var/log/%s", logtail) < 0) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "String truncation occured.\n"); - set_log_file_name(logbase, logf); - _rtpfile = fopen(logf, "a"); - if(_rtpfile) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf); - else { - if (snprintf(logbase, FILE_STR_LEN, "/var/tmp/%s", logtail)<0) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "String truncation occured.\n"); + set_log_file_name(logbase, logf); + _rtpfile = fopen(logf, "a"); + if (_rtpfile) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf); + else { + if (snprintf(logbase, FILE_STR_LEN, "/var/tmp/%s", logtail) < 0) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "String truncation occured.\n"); - set_log_file_name(logbase, logf); - _rtpfile = fopen(logf, "a"); - if(_rtpfile) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf); - else { - if (snprintf(logbase, FILE_STR_LEN, "/tmp/%s", logtail)<0) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "String truncation occured.\n"); - set_log_file_name(logbase, logf); - _rtpfile = fopen(logf, "a"); - if(_rtpfile) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf); - else { - snprintf(logbase, FILE_STR_LEN, "%s", logtail); - set_log_file_name(logbase, logf); - _rtpfile = fopen(logf, "a"); - if(_rtpfile) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf); - else { - _rtpfile = stdout; - return; - } - } - } - } - } + set_log_file_name(logbase, logf); + _rtpfile = fopen(logf, "a"); + if (_rtpfile) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf); + else { + if (snprintf(logbase, FILE_STR_LEN, "/tmp/%s", logtail) < 0) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "String truncation occured.\n"); + set_log_file_name(logbase, logf); + _rtpfile = fopen(logf, "a"); + if (_rtpfile) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf); + else { + snprintf(logbase, FILE_STR_LEN, "%s", logtail); + set_log_file_name(logbase, logf); + _rtpfile = fopen(logf, "a"); + if (_rtpfile) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf); + else { + _rtpfile = stdout; + return; + } + } + } + } + } - STRCPY(log_fn_base,logbase); - STRCPY(log_fn,logf); - } + STRCPY(log_fn_base, logbase); + STRCPY(log_fn, logf); + } } -void set_log_to_syslog(int val) -{ - to_syslog = val; -} +void set_log_to_syslog(int val) { to_syslog = val; } -void set_simple_log(int val) -{ - simple_log = val; -} +void set_simple_log(int val) { simple_log = val; } #define Q(x) #x #define QUOTE(x) Q(x) -void rollover_logfile(void) -{ - if(to_syslog || !(log_fn[0])) - return; +void rollover_logfile(void) { + if (to_syslog || !(log_fn[0])) + return; - { - FILE *f = fopen(log_fn,"r"); - if(!f) { - fprintf(stderr, "log file is damaged\n"); - reset_rtpprintf(); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file reopened: %s\n", log_fn); - return; - } else { - fclose(f); - } - } + { + FILE *f = fopen(log_fn, "r"); + if (!f) { + fprintf(stderr, "log file is damaged\n"); + reset_rtpprintf(); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file reopened: %s\n", log_fn); + return; + } else { + fclose(f); + } + } - if(simple_log) - return; + if (simple_log) + return; - log_lock(); - if(_rtpfile && log_fn[0] && (_rtpfile != stdout)) { - char logf[FILE_STR_LEN]; + log_lock(); + if (_rtpfile && log_fn[0] && (_rtpfile != stdout)) { + char logf[FILE_STR_LEN]; - set_log_file_name(log_fn_base,logf); - if(strcmp(log_fn,logf)) { - fclose(_rtpfile); - log_fn[0]=0; - _rtpfile = fopen(logf, "w"); - if(_rtpfile) { - STRCPY(log_fn,logf); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", log_fn); - } else { - _rtpfile = stdout; - } - } - } - log_unlock(); + set_log_file_name(log_fn_base, logf); + if (strcmp(log_fn, logf)) { + fclose(_rtpfile); + log_fn[0] = 0; + _rtpfile = fopen(logf, "w"); + if (_rtpfile) { + STRCPY(log_fn, logf); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", log_fn); + } else { + _rtpfile = stdout; + } + } + } + log_unlock(); } -static int get_syslog_level(TURN_LOG_LEVEL level) -{ +static int get_syslog_level(TURN_LOG_LEVEL level) { #if defined(__unix__) || defined(unix) || defined(__APPLE__) - switch(level) { - case TURN_LOG_LEVEL_CONTROL: - return LOG_NOTICE; - case TURN_LOG_LEVEL_WARNING: - return LOG_WARNING; - case TURN_LOG_LEVEL_ERROR: - return LOG_ERR; - default: - ; - }; - return LOG_INFO; + switch (level) { + case TURN_LOG_LEVEL_CONTROL: + return LOG_NOTICE; + case TURN_LOG_LEVEL_WARNING: + return LOG_WARNING; + case TURN_LOG_LEVEL_ERROR: + return LOG_ERR; + default:; + }; + return LOG_INFO; #endif - return level; + return level; } #if defined(WINDOWS) -void err(int eval, const char *format, ...) -{ - va_list args; - va_start(args, format); - TURN_LOG_FUNC(eval, format, args); - va_end(args); +void err(int eval, const char *format, ...) { + va_list args; + va_start(args, format); + TURN_LOG_FUNC(eval, format, args); + va_end(args); } #endif -void turn_log_func_default(char* file, int line, TURN_LOG_LEVEL level, const char* format, ...) -{ - va_list args; - va_start(args,format); +void turn_log_func_default(char *file, int line, TURN_LOG_LEVEL level, const char *format, ...) { + va_list args; + va_start(args, format); #if defined(TURN_LOG_FUNC_IMPL) - TURN_LOG_FUNC_IMPL(level,format,args); + TURN_LOG_FUNC_IMPL(level, format, args); #else - /* Fix for Issue 24, raised by John Selbie: */ + /* Fix for Issue 24, raised by John Selbie: */ #define MAX_RTPPRINTF_BUFFER_SIZE (1024) - char s[MAX_RTPPRINTF_BUFFER_SIZE+1]; - size_t so_far = 0; - if (use_new_log_timestamp_format) { - time_t now = time(NULL); - so_far += strftime(s, sizeof(s), turn_log_timestamp_format, localtime(&now)); - } else { - so_far += snprintf(s, sizeof(s), "%lu: ", (unsigned long)log_time()); - } + char s[MAX_RTPPRINTF_BUFFER_SIZE + 1]; + size_t so_far = 0; + if (use_new_log_timestamp_format) { + time_t now = time(NULL); + so_far += strftime(s, sizeof(s), turn_log_timestamp_format, localtime(&now)); + } else { + so_far += snprintf(s, sizeof(s), "%lu: ", (unsigned long)log_time()); + } #ifdef SYS_gettid - so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "(%lu): ", (unsigned long)gettid()); + so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "(%lu): ", (unsigned long)gettid()); #endif - if (_log_file_line_set) - so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "%s(%d):", file, line); + if (_log_file_line_set) + so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "%s(%d):", file, line); - switch (level) - { - case TURN_LOG_LEVEL_DEBUG: - so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "DEBUG: "); - break; - case TURN_LOG_LEVEL_INFO: - so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "INFO: "); - break; - case TURN_LOG_LEVEL_CONTROL: - so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "CONTROL: "); - break; - case TURN_LOG_LEVEL_WARNING: - so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "WARNING: "); - break; - case TURN_LOG_LEVEL_ERROR: - so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "ERROR: "); - break; - } - so_far += vsnprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far+1), format, args); + switch (level) { + case TURN_LOG_LEVEL_DEBUG: + so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "DEBUG: "); + break; + case TURN_LOG_LEVEL_INFO: + so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "INFO: "); + break; + case TURN_LOG_LEVEL_CONTROL: + so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "CONTROL: "); + break; + case TURN_LOG_LEVEL_WARNING: + so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "WARNING: "); + break; + case TURN_LOG_LEVEL_ERROR: + so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "ERROR: "); + break; + } + so_far += vsnprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), format, args); - if(so_far > MAX_RTPPRINTF_BUFFER_SIZE+1) - { - so_far=MAX_RTPPRINTF_BUFFER_SIZE+1; - } - if(!no_stdout_log) - fwrite(s, so_far, 1, stdout); - /* write to syslog or to log file */ - if(to_syslog) { + if (so_far > MAX_RTPPRINTF_BUFFER_SIZE + 1) { + so_far = MAX_RTPPRINTF_BUFFER_SIZE + 1; + } + if (!no_stdout_log) + fwrite(s, so_far, 1, stdout); + /* write to syslog or to log file */ + if (to_syslog) { #if defined(WINDOWS) - //TODO: add event tracing: https://docs.microsoft.com/en-us/windows/win32/etw/about-event-tracing - // windows10: https://docs.microsoft.com/en-us/windows/win32/tracelogging/trace-logging-portal - printf("%s", s); + // TODO: add event tracing: https://docs.microsoft.com/en-us/windows/win32/etw/about-event-tracing + // windows10: https://docs.microsoft.com/en-us/windows/win32/tracelogging/trace-logging-portal + printf("%s", s); #else - syslog(syslog_facility | get_syslog_level(level), "%s", s); + syslog(syslog_facility | get_syslog_level(level), "%s", s); #endif - } else { - log_lock(); - set_rtpfile(); - if(fprintf(_rtpfile,"%s",s)<0) { - reset_rtpprintf(); - } else if(fflush(_rtpfile)<0) { - reset_rtpprintf(); - } - log_unlock(); - } + } else { + log_lock(); + set_rtpfile(); + if (fprintf(_rtpfile, "%s", s) < 0) { + reset_rtpprintf(); + } else if (fflush(_rtpfile) < 0) { + reset_rtpprintf(); + } + log_unlock(); + } #endif - va_end(args); - + va_end(args); } ///////////// ORIGIN /////////////////// -int get_default_protocol_port(const char* scheme, size_t slen) -{ - if(scheme && (slen>0)) { - switch(slen) { - case 3: - if(!memcmp("ftp",scheme,3)) - return 21; - if(!memcmp("svn",scheme,3)) - return 3690; - if(!memcmp("ssh",scheme,3)) - return 22; - if(!memcmp("sip",scheme,3)) - return 5060; - break; - case 4: - if(!memcmp("http",scheme,4)) - return 80; - if(!memcmp("ldap",scheme,4)) - return 389; - if(!memcmp("sips",scheme,4)) - return 5061; - if(!memcmp("turn",scheme,4)) - return 3478; - if(!memcmp("stun",scheme,4)) - return 3478; - break; - case 5: - if(!memcmp("https",scheme,5)) - return 443; - if(!memcmp("ldaps",scheme,5)) - return 636; - if(!memcmp("turns",scheme,5)) - return 5349; - if(!memcmp("stuns",scheme,5)) - return 5349; - break; - case 6: - if(!memcmp("telnet",scheme,6)) - return 23; - if(!memcmp("radius",scheme,6)) - return 1645; - break; - case 7: - if(!memcmp("svn+ssh",scheme,7)) - return 22; - break; - default: - return 0; - }; - } - return 0; +int get_default_protocol_port(const char *scheme, size_t slen) { + if (scheme && (slen > 0)) { + switch (slen) { + case 3: + if (!memcmp("ftp", scheme, 3)) + return 21; + if (!memcmp("svn", scheme, 3)) + return 3690; + if (!memcmp("ssh", scheme, 3)) + return 22; + if (!memcmp("sip", scheme, 3)) + return 5060; + break; + case 4: + if (!memcmp("http", scheme, 4)) + return 80; + if (!memcmp("ldap", scheme, 4)) + return 389; + if (!memcmp("sips", scheme, 4)) + return 5061; + if (!memcmp("turn", scheme, 4)) + return 3478; + if (!memcmp("stun", scheme, 4)) + return 3478; + break; + case 5: + if (!memcmp("https", scheme, 5)) + return 443; + if (!memcmp("ldaps", scheme, 5)) + return 636; + if (!memcmp("turns", scheme, 5)) + return 5349; + if (!memcmp("stuns", scheme, 5)) + return 5349; + break; + case 6: + if (!memcmp("telnet", scheme, 6)) + return 23; + if (!memcmp("radius", scheme, 6)) + return 1645; + break; + case 7: + if (!memcmp("svn+ssh", scheme, 7)) + return 22; + break; + default: + return 0; + }; + } + return 0; } -int get_canonic_origin(const char* o, char *co, int sz) -{ - int ret = -1; +int get_canonic_origin(const char *o, char *co, int sz) { + int ret = -1; - if(o && o[0] && co) { - co[0]=0; - struct evhttp_uri *uri = evhttp_uri_parse(o); - if(uri) { - const char *scheme = evhttp_uri_get_scheme(uri); - if(scheme && scheme[0]) { - size_t schlen = strlen(scheme); - if((schlen<(size_t)sz) && (schlen0) - snprintf(otmp+schlen,sizeof(otmp)-schlen-1,"://%s:%d",host,port); - else - snprintf(otmp+schlen,sizeof(otmp)-schlen-1,"://%s",host); + int port = evhttp_uri_get_port(uri); + if (port < 1) { + port = get_default_protocol_port(otmp, schlen); + } + if (port > 0) + snprintf(otmp + schlen, sizeof(otmp) - schlen - 1, "://%s:%d", host, port); + else + snprintf(otmp + schlen, sizeof(otmp) - schlen - 1, "://%s", host); - { - unsigned char *s = (unsigned char*)otmp + schlen + 3; - while(*s) { - *s = (unsigned char)tolower((int)*s); - ++s; - } - } + { + unsigned char *s = (unsigned char *)otmp + schlen + 3; + while (*s) { + *s = (unsigned char)tolower((int)*s); + ++s; + } + } - strncpy(co,otmp,sz); - co[sz]=0; - ret = 0; - } - } - } - evhttp_uri_free(uri); - } + strncpy(co, otmp, sz); + co[sz] = 0; + ret = 0; + } + } + } + evhttp_uri_free(uri); + } - if(ret<0) { - strncpy(co,o,sz); - co[sz]=0; - } - } + if (ret < 0) { + strncpy(co, o, sz); + co[sz] = 0; + } + } - return ret; + return ret; } ////////////////////////////////////////////////////////////////// -int is_secure_string(const uint8_t *string, int sanitizesql) -{ - int ret = 0; - if(string) { - unsigned char *s0 = (unsigned char*)strdup((const char*)string); - unsigned char *s = s0; - while(*s) { - *s = (unsigned char)tolower((int)*s); - ++s; - } - s = s0; - if(strstr((char*)s," ")||strstr((char*)s,"\t")||strstr((char*)s,"'")||strstr((char*)s,"\"")||strstr((char*)s,"\n")||strstr((char*)s,"\r")||strstr((char*)s,"\\")) { - ; - } else if(sanitizesql && strstr((char*)s,"union")&&strstr((char*)s,"select")) { - ; - } else { - ret = 1; - } - free(s); - } - return ret; +int is_secure_string(const uint8_t *string, int sanitizesql) { + int ret = 0; + if (string) { + unsigned char *s0 = (unsigned char *)strdup((const char *)string); + unsigned char *s = s0; + while (*s) { + *s = (unsigned char)tolower((int)*s); + ++s; + } + s = s0; + if (strstr((char *)s, " ") || strstr((char *)s, "\t") || strstr((char *)s, "'") || strstr((char *)s, "\"") || + strstr((char *)s, "\n") || strstr((char *)s, "\r") || strstr((char *)s, "\\")) { + ; + } else if (sanitizesql && strstr((char *)s, "union") && strstr((char *)s, "select")) { + ; + } else { + ret = 1; + } + free(s); + } + return ret; } ////////////////////////////////////////////////////////////////// diff --git a/src/apps/common/ns_turn_utils.h b/src/apps/common/ns_turn_utils.h index d40a283..b330862 100644 --- a/src/apps/common/ns_turn_utils.h +++ b/src/apps/common/ns_turn_utils.h @@ -36,9 +36,9 @@ #endif #if defined(WINDOWS) - #ifndef err - void err(int eval, const char *format, ...); - #endif +#ifndef err +void err(int eval, const char *format, ...); +#endif #endif #include "ns_turn_ioaddr.h" @@ -50,8 +50,8 @@ extern "C" { //////////////////////// LOG ////////////////////////// typedef enum { - TURN_LOG_LEVEL_DEBUG = 0, - TURN_LOG_LEVEL_INFO, + TURN_LOG_LEVEL_DEBUG = 0, + TURN_LOG_LEVEL_INFO, TURN_LOG_LEVEL_CONTROL, TURN_LOG_LEVEL_WARNING, TURN_LOG_LEVEL_ERROR @@ -61,7 +61,7 @@ typedef enum { #define TURN_VERBOSE_NORMAL (1) #define TURN_VERBOSE_EXTRA (2) -#define eve(v) ((v)==TURN_VERBOSE_EXTRA) +#define eve(v) ((v) == TURN_VERBOSE_EXTRA) void set_no_stdout_log(int val); void set_log_to_syslog(int val); @@ -69,15 +69,15 @@ void set_simple_log(int val); void set_syslog_facility(char *val); -void set_turn_log_timestamp_format(char* new_format); +void set_turn_log_timestamp_format(char *new_format); -void turn_log_func_default(char* file, int line, TURN_LOG_LEVEL level, const char* format, ...) +void turn_log_func_default(char *file, int line, TURN_LOG_LEVEL level, const char *format, ...) #ifdef __GNUC__ -__attribute__ ((format (printf, 4, 5))) + __attribute__((format(printf, 4, 5))) #endif -; + ; -void addr_debug_print(int verbose, const ioa_addr *addr, const char* s); +void addr_debug_print(int verbose, const ioa_addr *addr, const char *s); /* Log */ extern volatile int _log_time_value_set; diff --git a/src/apps/common/stun_buffer.c b/src/apps/common/stun_buffer.c index ff7818b..513bdb5 100644 --- a/src/apps/common/stun_buffer.c +++ b/src/apps/common/stun_buffer.c @@ -33,220 +33,208 @@ ////////////////////// BUFFERS /////////////////////////// int stun_init_buffer(stun_buffer *buf) { - if(!buf) return -1; + if (!buf) + return -1; memset(buf->buf, 0, sizeof(buf->buf)); - buf->len=0; - buf->offset=0; - buf->coffset=0; + buf->len = 0; + buf->offset = 0; + buf->coffset = 0; return 0; } int stun_get_size(const stun_buffer *buf) { - if(!buf) return 0; + if (!buf) + return 0; return sizeof(buf->buf); } //////////////////////////////////////////////////////////// -void stun_tid_from_message(const stun_buffer *buf, stun_tid* id) { - stun_tid_from_message_str(buf->buf,(size_t)(buf->len), id); +void stun_tid_from_message(const stun_buffer *buf, stun_tid *id) { + stun_tid_from_message_str(buf->buf, (size_t)(buf->len), id); } -void stun_tid_generate_in_message(stun_buffer* buf, stun_tid* id) { - if(buf) { +void stun_tid_generate_in_message(stun_buffer *buf, stun_tid *id) { + if (buf) { stun_tid_generate_in_message_str(buf->buf, id); } } //////////////////////////////////////////////////////// -static inline int is_channel_msg(const stun_buffer* buf) { - if(buf && buf->len>0) { +static inline int is_channel_msg(const stun_buffer *buf) { + if (buf && buf->len > 0) { return is_channel_msg_str(buf->buf, (size_t)(buf->len)); } return 0; } -int stun_is_command_message(const stun_buffer* buf) { - if(!buf || buf->len<=0) +int stun_is_command_message(const stun_buffer *buf) { + if (!buf || buf->len <= 0) return 0; else - return stun_is_command_message_str(buf->buf,(size_t)(buf->len)); + return stun_is_command_message_str(buf->buf, (size_t)(buf->len)); } -int stun_is_request(const stun_buffer* buf) { - return stun_is_request_str(buf->buf,(size_t)buf->len); -} +int stun_is_request(const stun_buffer *buf) { return stun_is_request_str(buf->buf, (size_t)buf->len); } -int stun_is_success_response(const stun_buffer* buf) { +int stun_is_success_response(const stun_buffer *buf) { return stun_is_success_response_str(buf->buf, (size_t)(buf->len)); } -int stun_is_error_response(const stun_buffer* buf, int *err_code, uint8_t *err_msg, size_t err_msg_size) { +int stun_is_error_response(const stun_buffer *buf, int *err_code, uint8_t *err_msg, size_t err_msg_size) { return stun_is_error_response_str(buf->buf, (size_t)(buf->len), err_code, err_msg, err_msg_size); } -int stun_is_response(const stun_buffer* buf) { - return stun_is_response_str(buf->buf,(size_t)(buf->len)); -} +int stun_is_response(const stun_buffer *buf) { return stun_is_response_str(buf->buf, (size_t)(buf->len)); } -int stun_is_indication(const stun_buffer* buf) { - if(is_channel_msg(buf)) return 0; +int stun_is_indication(const stun_buffer *buf) { + if (is_channel_msg(buf)) + return 0; return IS_STUN_INDICATION(stun_get_msg_type(buf)); } -uint16_t stun_get_method(const stun_buffer* buf) { - return stun_get_method_str(buf->buf, (size_t)(buf->len)); -} +uint16_t stun_get_method(const stun_buffer *buf) { return stun_get_method_str(buf->buf, (size_t)(buf->len)); } -uint16_t stun_get_msg_type(const stun_buffer* buf) { - if(!buf) return (uint16_t)-1; - return stun_get_msg_type_str(buf->buf,(size_t)buf->len); +uint16_t stun_get_msg_type(const stun_buffer *buf) { + if (!buf) + return (uint16_t)-1; + return stun_get_msg_type_str(buf->buf, (size_t)buf->len); } //////////////////////////////////////////////////////////// -static void stun_init_command(uint16_t message_type, stun_buffer* buf) { - buf->len=stun_get_size(buf); - stun_init_command_str(message_type, buf->buf, (size_t*)(&(buf->len))); +static void stun_init_command(uint16_t message_type, stun_buffer *buf) { + buf->len = stun_get_size(buf); + stun_init_command_str(message_type, buf->buf, (size_t *)(&(buf->len))); } -void stun_init_request(uint16_t method, stun_buffer* buf) { - stun_init_command(stun_make_request(method), buf); +void stun_init_request(uint16_t method, stun_buffer *buf) { stun_init_command(stun_make_request(method), buf); } + +void stun_init_indication(uint16_t method, stun_buffer *buf) { stun_init_command(stun_make_indication(method), buf); } + +void stun_init_success_response(uint16_t method, stun_buffer *buf, stun_tid *id) { + buf->len = stun_get_size(buf); + stun_init_success_response_str(method, buf->buf, (size_t *)(&(buf->len)), id); } -void stun_init_indication(uint16_t method, stun_buffer* buf) { - stun_init_command(stun_make_indication(method), buf); +void stun_init_error_response(uint16_t method, stun_buffer *buf, uint16_t error_code, const uint8_t *reason, + stun_tid *id) { + buf->len = stun_get_size(buf); + stun_init_error_response_str(method, buf->buf, (size_t *)(&(buf->len)), error_code, reason, id); } -void stun_init_success_response(uint16_t method, stun_buffer* buf, stun_tid* id) { - buf->len=stun_get_size(buf); - stun_init_success_response_str(method, buf->buf, (size_t*)(&(buf->len)), id); -} - -void stun_init_error_response(uint16_t method, stun_buffer* buf, uint16_t error_code, const uint8_t *reason, stun_tid* id) { - buf->len=stun_get_size(buf); - stun_init_error_response_str(method, buf->buf, (size_t*)(&(buf->len)), error_code, reason, id); -} - /////////////////////////////////////////////////////////////////////////////// -int stun_get_command_message_len(const stun_buffer* buf) { +int stun_get_command_message_len(const stun_buffer *buf) { return stun_get_command_message_len_str(buf->buf, (size_t)(buf->len)); } /////////////////////////////////////////////////////////////////////////////// -int stun_init_channel_message(uint16_t chnumber, stun_buffer* buf, int length, int do_padding) { - return stun_init_channel_message_str(chnumber, buf->buf, (size_t*)(&(buf->len)), length, do_padding); +int stun_init_channel_message(uint16_t chnumber, stun_buffer *buf, int length, int do_padding) { + return stun_init_channel_message_str(chnumber, buf->buf, (size_t *)(&(buf->len)), length, do_padding); } -int stun_is_channel_message(stun_buffer* buf, uint16_t* chnumber, int is_padding_mandatory) { - if(!buf) return 0; +int stun_is_channel_message(stun_buffer *buf, uint16_t *chnumber, int is_padding_mandatory) { + if (!buf) + return 0; size_t blen = (size_t)buf->len; int ret = stun_is_channel_message_str(buf->buf, &blen, chnumber, is_padding_mandatory); - if(ret) { - buf->len = blen; + if (ret) { + buf->len = blen; } return ret; } /////////////////////////////////////////////////////////////////////////////// -int stun_set_allocate_request(stun_buffer* buf, uint32_t lifetime, int af4, int af6, uint8_t transport, int mobile, const char *rt, int ep) { - return stun_set_allocate_request_str(buf->buf, (size_t*)(&(buf->len)), lifetime, af4, af6, transport, mobile, rt, ep); +int stun_set_allocate_request(stun_buffer *buf, uint32_t lifetime, int af4, int af6, uint8_t transport, int mobile, + const char *rt, int ep) { + return stun_set_allocate_request_str(buf->buf, (size_t *)(&(buf->len)), lifetime, af4, af6, transport, mobile, rt, + ep); } -int stun_set_allocate_response(stun_buffer* buf, stun_tid* tid, - const ioa_addr *relayed_addr1, const ioa_addr *relayed_addr2, - const ioa_addr *reflexive_addr, - uint32_t lifetime, uint32_t max_lifetime, int error_code, const uint8_t *reason, - uint64_t reservation_token, char *mobile_id) { - - return stun_set_allocate_response_str(buf->buf, (size_t*)(&(buf->len)), tid, - relayed_addr1, relayed_addr2, reflexive_addr, - lifetime, max_lifetime, error_code, reason, - reservation_token, mobile_id); +int stun_set_allocate_response(stun_buffer *buf, stun_tid *tid, const ioa_addr *relayed_addr1, + const ioa_addr *relayed_addr2, const ioa_addr *reflexive_addr, uint32_t lifetime, + uint32_t max_lifetime, int error_code, const uint8_t *reason, uint64_t reservation_token, + char *mobile_id) { + return stun_set_allocate_response_str(buf->buf, (size_t *)(&(buf->len)), tid, relayed_addr1, relayed_addr2, + reflexive_addr, lifetime, max_lifetime, error_code, reason, reservation_token, + mobile_id); } /////////////////////////////////////////////////////////////////////////////// -uint16_t stun_set_channel_bind_request(stun_buffer* buf, - const ioa_addr* peer_addr, uint16_t channel_number) { +uint16_t stun_set_channel_bind_request(stun_buffer *buf, const ioa_addr *peer_addr, uint16_t channel_number) { - return stun_set_channel_bind_request_str(buf->buf,(size_t*)(&(buf->len)), peer_addr, channel_number); + return stun_set_channel_bind_request_str(buf->buf, (size_t *)(&(buf->len)), peer_addr, channel_number); } -void stun_set_channel_bind_response(stun_buffer* buf, stun_tid* tid, int error_code, const uint8_t *reason) { - stun_set_channel_bind_response_str(buf->buf, (size_t*)(&(buf->len)), tid, error_code, reason); +void stun_set_channel_bind_response(stun_buffer *buf, stun_tid *tid, int error_code, const uint8_t *reason) { + stun_set_channel_bind_response_str(buf->buf, (size_t *)(&(buf->len)), tid, error_code, reason); } //////////////////////////////////////////////////////////////// -stun_attr_ref stun_attr_get_first(const stun_buffer* buf) { +stun_attr_ref stun_attr_get_first(const stun_buffer *buf) { return stun_attr_get_first_str(buf->buf, (size_t)(buf->len)); } -stun_attr_ref stun_attr_get_next(const stun_buffer* buf, stun_attr_ref prev) { +stun_attr_ref stun_attr_get_next(const stun_buffer *buf, stun_attr_ref prev) { return stun_attr_get_next_str(buf->buf, (size_t)(buf->len), prev); } -int stun_attr_add(stun_buffer* buf, uint16_t attr, const char* avalue, int alen) { - return stun_attr_add_str(buf->buf, (size_t*)(&(buf->len)), attr, (const uint8_t *)avalue, alen); +int stun_attr_add(stun_buffer *buf, uint16_t attr, const char *avalue, int alen) { + return stun_attr_add_str(buf->buf, (size_t *)(&(buf->len)), attr, (const uint8_t *)avalue, alen); } -int stun_attr_add_channel_number(stun_buffer* buf, uint16_t chnumber) { +int stun_attr_add_channel_number(stun_buffer *buf, uint16_t chnumber) { return stun_attr_add_channel_number_str(buf->buf, (size_t *)(&(buf->len)), chnumber); } -int stun_attr_add_addr(stun_buffer *buf,uint16_t attr_type, const ioa_addr* ca) { - return stun_attr_add_addr_str(buf->buf,(size_t*)(&(buf->len)), attr_type, ca); +int stun_attr_add_addr(stun_buffer *buf, uint16_t attr_type, const ioa_addr *ca) { + return stun_attr_add_addr_str(buf->buf, (size_t *)(&(buf->len)), attr_type, ca); } -int stun_attr_get_addr(const stun_buffer *buf, stun_attr_ref attr, ioa_addr* ca, - const ioa_addr *default_addr) { +int stun_attr_get_addr(const stun_buffer *buf, stun_attr_ref attr, ioa_addr *ca, const ioa_addr *default_addr) { return stun_attr_get_addr_str(buf->buf, (size_t)(buf->len), attr, ca, default_addr); } -int stun_attr_get_first_addr(const stun_buffer *buf, uint16_t attr_type, ioa_addr* ca, - const ioa_addr *default_addr) { +int stun_attr_get_first_addr(const stun_buffer *buf, uint16_t attr_type, ioa_addr *ca, const ioa_addr *default_addr) { return stun_attr_get_first_addr_str(buf->buf, (size_t)(buf->len), attr_type, ca, default_addr); } -int stun_attr_add_even_port(stun_buffer* buf, uint8_t value) { - if(value) value=0x80; - return stun_attr_add(buf,STUN_ATTRIBUTE_EVEN_PORT,(const char*)&value,1); +int stun_attr_add_even_port(stun_buffer *buf, uint8_t value) { + if (value) + value = 0x80; + return stun_attr_add(buf, STUN_ATTRIBUTE_EVEN_PORT, (const char *)&value, 1); } uint16_t stun_attr_get_first_channel_number(const stun_buffer *buf) { return stun_attr_get_first_channel_number_str(buf->buf, (size_t)(buf->len)); } -stun_attr_ref stun_attr_get_first_by_type(const stun_buffer* buf, uint16_t attr_type) { +stun_attr_ref stun_attr_get_first_by_type(const stun_buffer *buf, uint16_t attr_type) { return stun_attr_get_first_by_type_str(buf->buf, (size_t)(buf->len), attr_type); } /////////////////////////////////////////////////////////////////////////////// -void stun_set_binding_request(stun_buffer* buf) { - stun_set_binding_request_str(buf->buf, (size_t*)(&(buf->len))); +void stun_set_binding_request(stun_buffer *buf) { stun_set_binding_request_str(buf->buf, (size_t *)(&(buf->len))); } + +int stun_set_binding_response(stun_buffer *buf, stun_tid *tid, const ioa_addr *reflexive_addr, int error_code, + const uint8_t *reason) { + return stun_set_binding_response_str(buf->buf, (size_t *)(&(buf->len)), tid, reflexive_addr, error_code, reason, 0, 0, + 1); } -int stun_set_binding_response(stun_buffer* buf, stun_tid* tid, - const ioa_addr *reflexive_addr, int error_code, const uint8_t *reason) { - return stun_set_binding_response_str(buf->buf, (size_t*)(&(buf->len)), tid, - reflexive_addr, error_code, reason, - 0,0,1); -} +void stun_prepare_binding_request(stun_buffer *buf) { stun_set_binding_request_str(buf->buf, (size_t *)(&(buf->len))); } -void stun_prepare_binding_request(stun_buffer* buf) { - stun_set_binding_request_str(buf->buf, (size_t*)(&(buf->len))); -} - -int stun_is_binding_response(const stun_buffer* buf) { +int stun_is_binding_response(const stun_buffer *buf) { return stun_is_binding_response_str(buf->buf, (size_t)(buf->len)); } diff --git a/src/apps/common/stun_buffer.h b/src/apps/common/stun_buffer.h index 5ab35c2..ee7f21a 100644 --- a/src/apps/common/stun_buffer.h +++ b/src/apps/common/stun_buffer.h @@ -40,11 +40,11 @@ extern "C" { /////////////////////////////////////////////////////////////// typedef struct _stun_buffer { - uint8_t channel[STUN_CHANNEL_HEADER_LENGTH]; - uint8_t buf[STUN_BUFFER_SIZE]; - size_t len; - uint16_t offset; - uint8_t coffset; + uint8_t channel[STUN_CHANNEL_HEADER_LENGTH]; + uint8_t buf[STUN_BUFFER_SIZE]; + size_t len; + uint16_t offset; + uint8_t coffset; } stun_buffer; ////////////////////////////////////////////////////////////// @@ -54,74 +54,74 @@ int stun_get_size(const stun_buffer *buf); ////////////////////////////////////////////////////////////// -void stun_tid_generate_in_message(stun_buffer* buf, stun_tid* id); -void stun_tid_from_message(const stun_buffer *buf, stun_tid* id); +void stun_tid_generate_in_message(stun_buffer *buf, stun_tid *id); +void stun_tid_from_message(const stun_buffer *buf, stun_tid *id); /////////////////////////////////////////////////////////////// -int stun_is_command_message(const stun_buffer* buf); -int stun_is_request(const stun_buffer* buf); -int stun_is_response(const stun_buffer* buf); -int stun_is_success_response(const stun_buffer* buf); -int stun_is_error_response(const stun_buffer* buf, int *err_code, uint8_t *err_msg, size_t err_msg_size); -int stun_is_indication(const stun_buffer* buf); -uint16_t stun_get_method(const stun_buffer* buf); -uint16_t stun_get_msg_type(const stun_buffer* buf); +int stun_is_command_message(const stun_buffer *buf); +int stun_is_request(const stun_buffer *buf); +int stun_is_response(const stun_buffer *buf); +int stun_is_success_response(const stun_buffer *buf); +int stun_is_error_response(const stun_buffer *buf, int *err_code, uint8_t *err_msg, size_t err_msg_size); +int stun_is_indication(const stun_buffer *buf); +uint16_t stun_get_method(const stun_buffer *buf); +uint16_t stun_get_msg_type(const stun_buffer *buf); /////////////////////////////////////////////////////////////// -void stun_init_request(uint16_t method, stun_buffer* buf); -void stun_init_indication(uint16_t method, stun_buffer* buf); -void stun_init_success_response(uint16_t method, stun_buffer* buf, stun_tid* id); -void stun_init_error_response(uint16_t method, stun_buffer* buf, uint16_t error_code, const uint8_t *reason, stun_tid* id); +void stun_init_request(uint16_t method, stun_buffer *buf); +void stun_init_indication(uint16_t method, stun_buffer *buf); +void stun_init_success_response(uint16_t method, stun_buffer *buf, stun_tid *id); +void stun_init_error_response(uint16_t method, stun_buffer *buf, uint16_t error_code, const uint8_t *reason, + stun_tid *id); /////////////////////////////////////////////////////////////// -int stun_attr_add(stun_buffer* buf, uint16_t attr, const char* avalue, int alen); -int stun_attr_add_channel_number(stun_buffer* buf, uint16_t chnumber); -int stun_attr_add_addr(stun_buffer *buf,uint16_t attr_type, const ioa_addr* ca); +int stun_attr_add(stun_buffer *buf, uint16_t attr, const char *avalue, int alen); +int stun_attr_add_channel_number(stun_buffer *buf, uint16_t chnumber); +int stun_attr_add_addr(stun_buffer *buf, uint16_t attr_type, const ioa_addr *ca); -stun_attr_ref stun_attr_get_first(const stun_buffer* buf); -stun_attr_ref stun_attr_get_first_by_type(const stun_buffer* buf, uint16_t attr_type); -stun_attr_ref stun_attr_get_next(const stun_buffer* buf, stun_attr_ref prev); -int stun_attr_get_addr(const stun_buffer *buf, stun_attr_ref attr, ioa_addr* ca, const ioa_addr *default_addr); -int stun_attr_add_even_port(stun_buffer* buf, uint8_t value); +stun_attr_ref stun_attr_get_first(const stun_buffer *buf); +stun_attr_ref stun_attr_get_first_by_type(const stun_buffer *buf, uint16_t attr_type); +stun_attr_ref stun_attr_get_next(const stun_buffer *buf, stun_attr_ref prev); +int stun_attr_get_addr(const stun_buffer *buf, stun_attr_ref attr, ioa_addr *ca, const ioa_addr *default_addr); +int stun_attr_add_even_port(stun_buffer *buf, uint8_t value); -int stun_attr_get_first_addr(const stun_buffer *buf, uint16_t attr_type, ioa_addr* ca, const ioa_addr *default_addr); +int stun_attr_get_first_addr(const stun_buffer *buf, uint16_t attr_type, ioa_addr *ca, const ioa_addr *default_addr); uint16_t stun_attr_get_first_channel_number(const stun_buffer *buf); /////////////////////////////////////////////////////////////// -int stun_get_command_message_len(const stun_buffer* buf); +int stun_get_command_message_len(const stun_buffer *buf); /////////////////////////////////////////////////////////////// -int stun_init_channel_message(uint16_t chnumber, stun_buffer* buf, int length, int do_padding); -int stun_is_channel_message(stun_buffer* buf, uint16_t* chnumber, int is_padding_madatory); +int stun_init_channel_message(uint16_t chnumber, stun_buffer *buf, int length, int do_padding); +int stun_is_channel_message(stun_buffer *buf, uint16_t *chnumber, int is_padding_madatory); /////////////////////////////////////////////////////////////// -int stun_set_allocate_request(stun_buffer* buf, uint32_t lifetime, int af4, int af6, uint8_t transport, int mobile, const char* rt, int ep); -int stun_set_allocate_response(stun_buffer* buf, stun_tid* tid, - const ioa_addr *relayed_addr1, const ioa_addr *relayed_addr2, - const ioa_addr *reflexive_addr, - uint32_t lifetime, uint32_t max_lifetime, - int error_code, const uint8_t *reason, - uint64_t reservation_token, char *mobile_id); +int stun_set_allocate_request(stun_buffer *buf, uint32_t lifetime, int af4, int af6, uint8_t transport, int mobile, + const char *rt, int ep); +int stun_set_allocate_response(stun_buffer *buf, stun_tid *tid, const ioa_addr *relayed_addr1, + const ioa_addr *relayed_addr2, const ioa_addr *reflexive_addr, uint32_t lifetime, + uint32_t max_lifetime, int error_code, const uint8_t *reason, uint64_t reservation_token, + char *mobile_id); /////////////////////////////////////////////////////////////// -void stun_set_binding_request(stun_buffer* buf); -int stun_set_binding_response(stun_buffer* buf, stun_tid* tid, - const ioa_addr *reflexive_addr, int error_code, const uint8_t *reason); +void stun_set_binding_request(stun_buffer *buf); +int stun_set_binding_response(stun_buffer *buf, stun_tid *tid, const ioa_addr *reflexive_addr, int error_code, + const uint8_t *reason); -void stun_prepare_binding_request(stun_buffer* buf); -int stun_is_binding_response(const stun_buffer* buf); +void stun_prepare_binding_request(stun_buffer *buf); +int stun_is_binding_response(const stun_buffer *buf); /////////////////////////////////////////////////////////////// -uint16_t stun_set_channel_bind_request(stun_buffer* buf, const ioa_addr* peer_addr, uint16_t channel_number); -void stun_set_channel_bind_response(stun_buffer* buf, stun_tid* tid, int error_code, const uint8_t *reason); +uint16_t stun_set_channel_bind_request(stun_buffer *buf, const ioa_addr *peer_addr, uint16_t channel_number); +void stun_set_channel_bind_response(stun_buffer *buf, stun_tid *tid, int error_code, const uint8_t *reason); /////////////////////////////////////////////////////////////// diff --git a/src/apps/common/win/getopt.c b/src/apps/common/win/getopt.c index 0ed0dd2..285d5a4 100644 --- a/src/apps/common/win/getopt.c +++ b/src/apps/common/win/getopt.c @@ -50,54 +50,52 @@ */ #include -#include -#include #include #include #include +#include +#include #include -#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */ +#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */ #ifdef REPLACE_GETOPT -int opterr = 1; /* if error message should be printed */ -int optind = 1; /* index into parent argv vector */ -int optopt = '?'; /* character checked for validity */ -#undef optreset /* see getopt.h */ -#define optreset __mingw_optreset -int optreset; /* reset getopt */ -char *optarg; /* argument associated with option */ +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt = '?'; /* character checked for validity */ +#undef optreset /* see getopt.h */ +#define optreset __mingw_optreset +int optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ #endif -#define PRINT_ERROR ((opterr) && (*options != ':')) +#define PRINT_ERROR ((opterr) && (*options != ':')) -#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ -#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ -#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ +#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ +#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ +#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ /* return values */ -#define BADCH (int)'?' -#define BADARG ((*options == ':') ? (int)':' : (int)'?') -#define INORDER (int)1 +#define BADCH (int)'?' +#define BADARG ((*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 #ifndef __CYGWIN__ #define __progname __argv[0] #else -extern char __declspec(dllimport) *__progname; +extern char __declspec(dllimport) * __progname; #endif #ifdef __CYGWIN__ static char EMSG[] = ""; #else -#define EMSG "" +#define EMSG "" #endif -static int getopt_internal(int, char * const *, const char *, - const struct option *, int *, int); -static int parse_long_options(char * const *, const char *, - const struct option *, int *, int); +static int getopt_internal(int, char *const *, const char *, const struct option *, int *, int); +static int parse_long_options(char *const *, const char *, const struct option *, int *, int); static int gcd(int, int); -static void permute_args(int, int, int, char * const *); +static void permute_args(int, int, int, char *const *); static char *place = EMSG; /* option letter processing */ @@ -113,40 +111,34 @@ static const char noarg[] = "option doesn't take an argument -- %.*s"; static const char illoptchar[] = "unknown option -- %c"; static const char illoptstring[] = "unknown option -- %s"; -static void -_vwarnx(const char *fmt,va_list ap) -{ - (void)fprintf(stderr,"%s: ",__progname); +static void _vwarnx(const char *fmt, va_list ap) { + (void)fprintf(stderr, "%s: ", __progname); if (fmt != NULL) - (void)vfprintf(stderr,fmt,ap); - (void)fprintf(stderr,"\n"); + (void)vfprintf(stderr, fmt, ap); + (void)fprintf(stderr, "\n"); } -static void -warnx(const char *fmt,...) -{ +static void warnx(const char *fmt, ...) { va_list ap; - va_start(ap,fmt); - _vwarnx(fmt,ap); + va_start(ap, fmt); + _vwarnx(fmt, ap); va_end(ap); } /* * Compute the greatest common divisor of a and b. */ -static int -gcd(int a, int b) -{ - int c; +static int gcd(int a, int b) { + int c; - c = a % b; - while (c != 0) { - a = b; - b = c; - c = a % b; - } + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } - return (b); + return (b); } /* @@ -154,36 +146,33 @@ gcd(int a, int b) * from nonopt_end to opt_end (keeping the same order of arguments * in each block). */ -static void -permute_args(int panonopt_start, int panonopt_end, int opt_end, - char * const *nargv) -{ - int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; - char *swap; +static void permute_args(int panonopt_start, int panonopt_end, int opt_end, char *const *nargv) { + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; - /* - * compute lengths of blocks and number and size of cycles - */ - nnonopts = panonopt_end - panonopt_start; - nopts = opt_end - panonopt_end; - ncycle = gcd(nnonopts, nopts); - cyclelen = (opt_end - panonopt_start) / ncycle; + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd(nnonopts, nopts); + cyclelen = (opt_end - panonopt_start) / ncycle; - for (i = 0; i < ncycle; i++) { - cstart = panonopt_end+i; - pos = cstart; - for (j = 0; j < cyclelen; j++) { - if (pos >= panonopt_end) - pos -= nnonopts; - else - pos += nopts; - swap = nargv[pos]; - /* LINTED const cast */ - ((char **) nargv)[pos] = nargv[cstart]; - /* LINTED const cast */ - ((char **)nargv)[cstart] = swap; - } - } + for (i = 0; i < ncycle; i++) { + cstart = panonopt_end + i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= panonopt_end) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + /* LINTED const cast */ + ((char **)nargv)[pos] = nargv[cstart]; + /* LINTED const cast */ + ((char **)nargv)[cstart] = swap; + } + } } /* @@ -191,127 +180,116 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end, * Parse long options in argc/argv argument vector. * Returns -1 if short_too is set and the option does not match long_options. */ -static int -parse_long_options(char * const *nargv, const char *options, - const struct option *long_options, int *idx, int short_too) -{ - char *current_argv, *has_equal; - size_t current_argv_len; - int i, ambiguous, match; +static int parse_long_options(char *const *nargv, const char *options, const struct option *long_options, int *idx, + int short_too) { + char *current_argv, *has_equal; + size_t current_argv_len; + int i, ambiguous, match; -#define IDENTICAL_INTERPRETATION(_x, _y) \ - (long_options[(_x)].has_arg == long_options[(_y)].has_arg && \ - long_options[(_x)].flag == long_options[(_y)].flag && \ - long_options[(_x)].val == long_options[(_y)].val) +#define IDENTICAL_INTERPRETATION(_x, _y) \ + (long_options[(_x)].has_arg == long_options[(_y)].has_arg && long_options[(_x)].flag == long_options[(_y)].flag && \ + long_options[(_x)].val == long_options[(_y)].val) - current_argv = place; - match = -1; - ambiguous = 0; + current_argv = place; + match = -1; + ambiguous = 0; - optind++; + optind++; - if ((has_equal = strchr(current_argv, '=')) != NULL) { - /* argument found (--option=arg) */ - current_argv_len = has_equal - current_argv; - has_equal++; - } else - current_argv_len = strlen(current_argv); + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); - for (i = 0; long_options[i].name; i++) { - /* find matching long option */ - if (strncmp(current_argv, long_options[i].name, - current_argv_len)) - continue; + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, current_argv_len)) + continue; - if (strlen(long_options[i].name) == current_argv_len) { - /* exact match */ - match = i; - ambiguous = 0; - break; - } - /* - * If this is a known short option, don't allow - * a partial match of a single character. - */ - if (short_too && current_argv_len == 1) - continue; + if (strlen(long_options[i].name) == current_argv_len) { + /* exact match */ + match = i; + ambiguous = 0; + break; + } + /* + * If this is a known short option, don't allow + * a partial match of a single character. + */ + if (short_too && current_argv_len == 1) + continue; - if (match == -1) /* partial match */ - match = i; - else if (!IDENTICAL_INTERPRETATION(i, match)) - ambiguous = 1; - } - if (ambiguous) { - /* ambiguous abbreviation */ - if (PRINT_ERROR) - warnx(ambig, (int)current_argv_len, - current_argv); - optopt = 0; - return (BADCH); - } - if (match != -1) { /* option found */ - if (long_options[match].has_arg == no_argument - && has_equal) { - if (PRINT_ERROR) - warnx(noarg, (int)current_argv_len, - current_argv); - /* - * XXX: GNU sets optopt to val regardless of flag - */ - if (long_options[match].flag == NULL) - optopt = long_options[match].val; - else - optopt = 0; - return (BADARG); - } - if (long_options[match].has_arg == required_argument || - long_options[match].has_arg == optional_argument) { - if (has_equal) - optarg = has_equal; - else if (long_options[match].has_arg == - required_argument) { - /* - * optional argument doesn't use next nargv - */ - optarg = nargv[optind++]; - } - } - if ((long_options[match].has_arg == required_argument) - && (optarg == NULL)) { - /* - * Missing argument; leading ':' indicates no error - * should be generated. - */ - if (PRINT_ERROR) - warnx(recargstring, - current_argv); - /* - * XXX: GNU sets optopt to val regardless of flag - */ - if (long_options[match].flag == NULL) - optopt = long_options[match].val; - else - optopt = 0; - --optind; - return (BADARG); - } - } else { /* unknown option */ - if (short_too) { - --optind; - return (-1); - } - if (PRINT_ERROR) - warnx(illoptstring, current_argv); - optopt = 0; - return (BADCH); - } - if (idx) - *idx = match; - if (long_options[match].flag) { - *long_options[match].flag = long_options[match].val; - return (0); - } else - return (long_options[match].val); + if (match == -1) /* partial match */ + match = i; + else if (!IDENTICAL_INTERPRETATION(i, match)) + ambiguous = 1; + } + if (ambiguous) { + /* ambiguous abbreviation */ + if (PRINT_ERROR) + warnx(ambig, (int)current_argv_len, current_argv); + optopt = 0; + return (BADCH); + } + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument && has_equal) { + if (PRINT_ERROR) + warnx(noarg, (int)current_argv_len, current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + return (BADARG); + } + if (long_options[match].has_arg == required_argument || long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else if (long_options[match].has_arg == required_argument) { + /* + * optional argument doesn't use next nargv + */ + optarg = nargv[optind++]; + } + } + if ((long_options[match].has_arg == required_argument) && (optarg == NULL)) { + /* + * Missing argument; leading ':' indicates no error + * should be generated. + */ + if (PRINT_ERROR) + warnx(recargstring, current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + --optind; + return (BADARG); + } + } else { /* unknown option */ + if (short_too) { + --optind; + return (-1); + } + if (PRINT_ERROR) + warnx(illoptstring, current_argv); + optopt = 0; + return (BADCH); + } + if (idx) + *idx = match; + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + return (0); + } else + return (long_options[match].val); #undef IDENTICAL_INTERPRETATION } @@ -319,197 +297,185 @@ parse_long_options(char * const *nargv, const char *options, * getopt_internal -- * Parse argc/argv argument vector. Called by user level routines. */ -static int -getopt_internal(int nargc, char * const *nargv, const char *options, - const struct option *long_options, int *idx, int flags) -{ - const char *oli; /* option letter list index */ - int optchar, short_too; - static int posixly_correct = -1; +static int getopt_internal(int nargc, char *const *nargv, const char *options, const struct option *long_options, + int *idx, int flags) { + const char *oli; /* option letter list index */ + int optchar, short_too; + static int posixly_correct = -1; - if (options == NULL) - return (-1); + if (options == NULL) + return (-1); - /* - * XXX Some GNU programs (like cvs) set optind to 0 instead of - * XXX using optreset. Work around this braindamage. - */ - if (optind == 0) - optind = optreset = 1; + /* + * XXX Some GNU programs (like cvs) set optind to 0 instead of + * XXX using optreset. Work around this braindamage. + */ + if (optind == 0) + optind = optreset = 1; - /* - * Disable GNU extensions if POSIXLY_CORRECT is set or options - * string begins with a '+'. - * - * CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or - * optreset != 0 for GNU compatibility. - */ - if (posixly_correct == -1 || optreset != 0) - posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); - if (*options == '-') - flags |= FLAG_ALLARGS; - else if (posixly_correct || *options == '+') - flags &= ~FLAG_PERMUTE; - if (*options == '+' || *options == '-') - options++; + /* + * Disable GNU extensions if POSIXLY_CORRECT is set or options + * string begins with a '+'. + * + * CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or + * optreset != 0 for GNU compatibility. + */ + if (posixly_correct == -1 || optreset != 0) + posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); + if (*options == '-') + flags |= FLAG_ALLARGS; + else if (posixly_correct || *options == '+') + flags &= ~FLAG_PERMUTE; + if (*options == '+' || *options == '-') + options++; - optarg = NULL; - if (optreset) - nonopt_start = nonopt_end = -1; + optarg = NULL; + if (optreset) + nonopt_start = nonopt_end = -1; start: - if (optreset || !*place) { /* update scanning pointer */ - optreset = 0; - if (optind >= nargc) { /* end of argument vector */ - place = EMSG; - if (nonopt_end != -1) { - /* do permutation, if we have to */ - permute_args(nonopt_start, nonopt_end, - optind, nargv); - optind -= nonopt_end - nonopt_start; - } - else if (nonopt_start != -1) { - /* - * If we skipped non-options, set optind - * to the first of them. - */ - optind = nonopt_start; - } - nonopt_start = nonopt_end = -1; - return (-1); - } - if (*(place = nargv[optind]) != '-' || - (place[1] == '\0' && strchr(options, '-') == NULL)) { - place = EMSG; /* found non-option */ - if (flags & FLAG_ALLARGS) { - /* - * GNU extension: - * return non-option as argument to option 1 - */ - optarg = nargv[optind++]; - return (INORDER); - } - if (!(flags & FLAG_PERMUTE)) { - /* - * If no permutation wanted, stop parsing - * at first non-option. - */ - return (-1); - } - /* do permutation */ - if (nonopt_start == -1) - nonopt_start = optind; - else if (nonopt_end != -1) { - permute_args(nonopt_start, nonopt_end, - optind, nargv); - nonopt_start = optind - - (nonopt_end - nonopt_start); - nonopt_end = -1; - } - optind++; - /* process next argument */ - goto start; - } - if (nonopt_start != -1 && nonopt_end == -1) - nonopt_end = optind; + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc) { /* end of argument vector */ + place = EMSG; + if (nonopt_end != -1) { + /* do permutation, if we have to */ + permute_args(nonopt_start, nonopt_end, optind, nargv); + optind -= nonopt_end - nonopt_start; + } else if (nonopt_start != -1) { + /* + * If we skipped non-options, set optind + * to the first of them. + */ + optind = nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + if (*(place = nargv[optind]) != '-' || (place[1] == '\0' && strchr(options, '-') == NULL)) { + place = EMSG; /* found non-option */ + if (flags & FLAG_ALLARGS) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return (INORDER); + } + if (!(flags & FLAG_PERMUTE)) { + /* + * If no permutation wanted, stop parsing + * at first non-option. + */ + return (-1); + } + /* do permutation */ + if (nonopt_start == -1) + nonopt_start = optind; + else if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, optind, nargv); + nonopt_start = optind - (nonopt_end - nonopt_start); + nonopt_end = -1; + } + optind++; + /* process next argument */ + goto start; + } + if (nonopt_start != -1 && nonopt_end == -1) + nonopt_end = optind; - /* - * If we have "-" do nothing, if "--" we are done. - */ - if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { - optind++; - place = EMSG; - /* - * We found an option (--), so if we skipped - * non-options, we have to permute. - */ - if (nonopt_end != -1) { - permute_args(nonopt_start, nonopt_end, - optind, nargv); - optind -= nonopt_end - nonopt_start; - } - nonopt_start = nonopt_end = -1; - return (-1); - } - } + /* + * If we have "-" do nothing, if "--" we are done. + */ + if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { + optind++; + place = EMSG; + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, optind, nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + } - /* - * Check long options if: - * 1) we were passed some - * 2) the arg is not just "-" - * 3) either the arg starts with -- we are getopt_long_only() - */ - if (long_options != NULL && place != nargv[optind] && - (*place == '-' || (flags & FLAG_LONGONLY))) { - short_too = 0; - if (*place == '-') - place++; /* --foo long option */ - else if (*place != ':' && strchr(options, *place) != NULL) - short_too = 1; /* could be short option too */ + /* + * Check long options if: + * 1) we were passed some + * 2) the arg is not just "-" + * 3) either the arg starts with -- we are getopt_long_only() + */ + if (long_options != NULL && place != nargv[optind] && (*place == '-' || (flags & FLAG_LONGONLY))) { + short_too = 0; + if (*place == '-') + place++; /* --foo long option */ + else if (*place != ':' && strchr(options, *place) != NULL) + short_too = 1; /* could be short option too */ - optchar = parse_long_options(nargv, options, long_options, - idx, short_too); - if (optchar != -1) { - place = EMSG; - return (optchar); - } - } + optchar = parse_long_options(nargv, options, long_options, idx, short_too); + if (optchar != -1) { + place = EMSG; + return (optchar); + } + } - if ((optchar = (int)*place++) == (int)':' || - (optchar == (int)'-' && *place != '\0') || - (oli = strchr(options, optchar)) == NULL) { - /* - * If the user specified "-" and '-' isn't listed in - * options, return -1 (non-option) as per POSIX. - * Otherwise, it is an unknown option character (or ':'). - */ - if (optchar == (int)'-' && *place == '\0') - return (-1); - if (!*place) - ++optind; - if (PRINT_ERROR) - warnx(illoptchar, optchar); - optopt = optchar; - return (BADCH); - } - if (long_options != NULL && optchar == 'W' && oli[1] == ';') { - /* -W long-option */ - if (*place) /* no space */ - /* NOTHING */; - else if (++optind >= nargc) { /* no arg */ - place = EMSG; - if (PRINT_ERROR) - warnx(recargchar, optchar); - optopt = optchar; - return (BADARG); - } else /* white space */ - place = nargv[optind]; - optchar = parse_long_options(nargv, options, long_options, - idx, 0); - place = EMSG; - return (optchar); - } - if (*++oli != ':') { /* doesn't take argument */ - if (!*place) - ++optind; - } else { /* takes (optional) argument */ - optarg = NULL; - if (*place) /* no white space */ - optarg = place; - else if (oli[1] != ':') { /* arg not optional */ - if (++optind >= nargc) { /* no arg */ - place = EMSG; - if (PRINT_ERROR) - warnx(recargchar, optchar); - optopt = optchar; - return (BADARG); - } else - optarg = nargv[optind]; - } - place = EMSG; - ++optind; - } - /* dump back option letter */ - return (optchar); + if ((optchar = (int)*place++) == (int)':' || (optchar == (int)'-' && *place != '\0') || + (oli = strchr(options, optchar)) == NULL) { + /* + * If the user specified "-" and '-' isn't listed in + * options, return -1 (non-option) as per POSIX. + * Otherwise, it is an unknown option character (or ':'). + */ + if (optchar == (int)'-' && *place == '\0') + return (-1); + if (!*place) + ++optind; + if (PRINT_ERROR) + warnx(illoptchar, optchar); + optopt = optchar; + return (BADCH); + } + if (long_options != NULL && optchar == 'W' && oli[1] == ';') { + /* -W long-option */ + if (*place) /* no space */ + /* NOTHING */; + else if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else /* white space */ + place = nargv[optind]; + optchar = parse_long_options(nargv, options, long_options, idx, 0); + place = EMSG; + return (optchar); + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*place) + ++optind; + } else { /* takes (optional) argument */ + optarg = NULL; + if (*place) /* no white space */ + optarg = place; + else if (oli[1] != ':') { /* arg not optional */ + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else + optarg = nargv[optind]; + } + place = EMSG; + ++optind; + } + /* dump back option letter */ + return (optchar); } #ifdef REPLACE_GETOPT @@ -519,19 +485,17 @@ start: * * [eventually this will replace the BSD getopt] */ -int -getopt(int nargc, char * const *nargv, const char *options) -{ +int getopt(int nargc, char *const *nargv, const char *options) { - /* - * We don't pass FLAG_PERMUTE to getopt_internal() since - * the BSD getopt(3) (unlike GNU) has never done this. - * - * Furthermore, since many privileged programs call getopt() - * before dropping privileges it makes sense to keep things - * as simple (and bug-free) as possible. - */ - return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); + /* + * We don't pass FLAG_PERMUTE to getopt_internal() since + * the BSD getopt(3) (unlike GNU) has never done this. + * + * Furthermore, since many privileged programs call getopt() + * before dropping privileges it makes sense to keep things + * as simple (and bug-free) as possible. + */ + return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); } #endif /* REPLACE_GETOPT */ @@ -539,24 +503,16 @@ getopt(int nargc, char * const *nargv, const char *options) * getopt_long -- * Parse argc/argv argument vector. */ -int -getopt_long(int nargc, char * const *nargv, const char *options, - const struct option *long_options, int *idx) -{ +int getopt_long(int nargc, char *const *nargv, const char *options, const struct option *long_options, int *idx) { - return (getopt_internal(nargc, nargv, options, long_options, idx, - FLAG_PERMUTE)); + return (getopt_internal(nargc, nargv, options, long_options, idx, FLAG_PERMUTE)); } /* * getopt_long_only -- * Parse argc/argv argument vector. */ -int -getopt_long_only(int nargc, char * const *nargv, const char *options, - const struct option *long_options, int *idx) -{ +int getopt_long_only(int nargc, char *const *nargv, const char *options, const struct option *long_options, int *idx) { - return (getopt_internal(nargc, nargv, options, long_options, idx, - FLAG_PERMUTE|FLAG_LONGONLY)); + return (getopt_internal(nargc, nargv, options, long_options, idx, FLAG_PERMUTE | FLAG_LONGONLY)); } diff --git a/src/apps/common/win/getopt.h b/src/apps/common/win/getopt.h index f3f864b..4e9ddc6 100644 --- a/src/apps/common/win/getopt.h +++ b/src/apps/common/win/getopt.h @@ -4,9 +4,9 @@ * This file has no copyright assigned and is placed in the Public Domain. * This file is a part of the w64 mingw-runtime package. * - * The w64 mingw-runtime package and its code is distributed in the hope that it - * will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR - * IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to + * The w64 mingw-runtime package and its code is distributed in the hope that it + * will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR + * IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to * warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ @@ -15,28 +15,28 @@ /* All the headers include this file. */ #include -#if defined( WINGETOPT_SHARED_LIB ) -# if defined( BUILDING_WINGETOPT_DLL ) -# define WINGETOPT_API __declspec(dllexport) -# else -# define WINGETOPT_API __declspec(dllimport) -# endif +#if defined(WINGETOPT_SHARED_LIB) +#if defined(BUILDING_WINGETOPT_DLL) +#define WINGETOPT_API __declspec(dllexport) #else -# define WINGETOPT_API +#define WINGETOPT_API __declspec(dllimport) +#endif +#else +#define WINGETOPT_API #endif #ifdef __cplusplus extern "C" { #endif -WINGETOPT_API extern int optind; /* index of first non-option in argv */ -WINGETOPT_API extern int optopt; /* single option character, as parsed */ -WINGETOPT_API extern int opterr; /* flag to enable built-in diagnostics... */ - /* (user may set to zero, to suppress) */ +WINGETOPT_API extern int optind; /* index of first non-option in argv */ +WINGETOPT_API extern int optopt; /* single option character, as parsed */ +WINGETOPT_API extern int opterr; /* flag to enable built-in diagnostics... */ + /* (user may set to zero, to suppress) */ -WINGETOPT_API extern char *optarg; /* pointer to argument of current option */ +WINGETOPT_API extern char *optarg; /* pointer to argument of current option */ -extern int getopt(int nargc, char * const *nargv, const char *options); +extern int getopt(int nargc, char *const *nargv, const char *options); #ifdef _BSD_SOURCE /* @@ -45,7 +45,7 @@ extern int getopt(int nargc, char * const *nargv, const char *options); * proclaim their BSD heritage, before including this header; however, * to maintain portability, developers are advised to avoid it. */ -# define optreset __mingw_optreset +#define optreset __mingw_optreset extern int optreset; #endif #ifdef __cplusplus @@ -69,25 +69,23 @@ extern int optreset; extern "C" { #endif -struct option /* specification for a long form option... */ +struct option /* specification for a long form option... */ { - const char *name; /* option name, without leading hyphens */ - int has_arg; /* does it take an argument? */ - int *flag; /* where to save its status, or NULL */ - int val; /* its associated status value */ + const char *name; /* option name, without leading hyphens */ + int has_arg; /* does it take an argument? */ + int *flag; /* where to save its status, or NULL */ + int val; /* its associated status value */ }; -enum /* permitted values for its `has_arg' field... */ -{ - no_argument = 0, /* option never takes an argument */ - required_argument, /* option always requires an argument */ - optional_argument /* option may take an argument */ +enum /* permitted values for its `has_arg' field... */ +{ no_argument = 0, /* option never takes an argument */ + required_argument, /* option always requires an argument */ + optional_argument /* option may take an argument */ }; -extern int getopt_long(int nargc, char * const *nargv, const char *options, - const struct option *long_options, int *idx); -extern int getopt_long_only(int nargc, char * const *nargv, const char *options, - const struct option *long_options, int *idx); +extern int getopt_long(int nargc, char *const *nargv, const char *options, const struct option *long_options, int *idx); +extern int getopt_long_only(int nargc, char *const *nargv, const char *options, const struct option *long_options, + int *idx); /* * Previous MinGW implementation had... */ @@ -95,7 +93,7 @@ extern int getopt_long_only(int nargc, char * const *nargv, const char *options, /* * ...for the long form API only; keep this for compatibility. */ -# define HAVE_DECL_GETOPT 1 +#define HAVE_DECL_GETOPT 1 #endif #ifdef __cplusplus diff --git a/src/apps/natdiscovery/natdiscovery.c b/src/apps/natdiscovery/natdiscovery.c index 069fde6..a74e991 100644 --- a/src/apps/natdiscovery/natdiscovery.c +++ b/src/apps/natdiscovery/natdiscovery.c @@ -1,46 +1,46 @@ /* -* Copyright (C) 2011, 2012, 2013 Citrix Systems -* -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the project nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND -* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE -* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -*/ + * Copyright (C) 2011, 2012, 2013 Citrix Systems + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ -#include #include +#include #include #include #if defined(WINDOWS) #include #else -#include #include +#include #endif -#include "ns_turn_utils.h" #include "apputils.h" +#include "ns_turn_utils.h" #include "stun_buffer.h" #ifdef __cplusplus @@ -55,763 +55,764 @@ static int counter = 0; #ifdef __cplusplus +static int init_socket(int *socketfd, ioa_addr *local_addr, int local_port, ioa_addr *remote_addr) { + int ret = 0; -static int init_socket(int *socketfd, ioa_addr *local_addr, int local_port, ioa_addr *remote_addr){ - int ret=0; + if (local_port >= 0) { + addr_set_port(local_addr, local_port); + } - if (local_port >= 0) { - addr_set_port(local_addr, local_port); - } + *socketfd = socket(remote_addr->ss.sa_family, SOCK_DGRAM, 0); + if (udp_fd < 0) + err(-1, NULL); - *socketfd = socket(remote_addr->ss.sa_family, SOCK_DGRAM, 0); - if (udp_fd < 0) - err(-1, NULL); + if (!addr_any(local_addr)) { + if (addr_bind(*socketfd, local_addr, 0, 1, UDP_SOCKET) < 0) + err(-1, NULL); + } - if (!addr_any(local_addr)) { - if (addr_bind(*socketfd, local_addr,0,1,UDP_SOCKET) < 0) - err(-1, NULL); - } - - return ret; + return ret; } +static int stunclient_send(int sockfd, ioa_addr *local_addr, int *local_port, ioa_addr *remote_addr, int change_ip, + int change_port, int padding, int response_port) { + int ret = 0; -static int stunclient_send(int sockfd, ioa_addr *local_addr, int *local_port, ioa_addr *remote_addr, int change_ip, int change_port, int padding, int response_port){ - int ret=0; + turn::StunMsgRequest req(STUN_METHOD_BINDING); - turn::StunMsgRequest req(STUN_METHOD_BINDING); + req.constructBindingRequest(); - req.constructBindingRequest(); + if (response_port >= 0) { + turn::StunAttrResponsePort rpa; + rpa.setResponsePort((uint16_t)response_port); + try { + req.addAttr(rpa); + } catch (turn::WrongStunAttrFormatException &ex1) { + printf("Wrong rp attr format\n"); + exit(-1); + } catch (turn::WrongStunBufferFormatException &ex2) { + printf("Wrong stun buffer format (1)\n"); + exit(-1); + } catch (...) { + printf("Wrong something (1)\n"); + exit(-1); + } + } + if (change_ip || change_port) { + turn::StunAttrChangeRequest cra; + cra.setChangeIp(change_ip); + cra.setChangePort(change_port); + try { + req.addAttr(cra); + } catch (turn::WrongStunAttrFormatException &ex1) { + printf("Wrong cr attr format\n"); + exit(-1); + } catch (turn::WrongStunBufferFormatException &ex2) { + printf("Wrong stun buffer format (2)\n"); + exit(-1); + } catch (...) { + printf("Wrong something (2)\n"); + exit(-1); + } + } + if (padding) { + turn::StunAttrPadding pa; + pa.setPadding(1500); + try { + req.addAttr(pa); + } catch (turn::WrongStunAttrFormatException &ex1) { + printf("Wrong p attr format\n"); + exit(-1); + } catch (turn::WrongStunBufferFormatException &ex2) { + printf("Wrong stun buffer format (3)\n"); + exit(-1); + } catch (...) { + printf("Wrong something (3)\n"); + exit(-1); + } + } - if (response_port >= 0) { - turn::StunAttrResponsePort rpa; - rpa.setResponsePort((uint16_t)response_port); - try { - req.addAttr(rpa); - } catch(turn::WrongStunAttrFormatException &ex1) { - printf("Wrong rp attr format\n"); - exit(-1); - } catch(turn::WrongStunBufferFormatException &ex2) { - printf("Wrong stun buffer format (1)\n"); - exit(-1); - } catch(...) { - printf("Wrong something (1)\n"); - exit(-1); - } - } - if (change_ip || change_port) { - turn::StunAttrChangeRequest cra; - cra.setChangeIp(change_ip); - cra.setChangePort(change_port); - try { - req.addAttr(cra); - } catch(turn::WrongStunAttrFormatException &ex1) { - printf("Wrong cr attr format\n"); - exit(-1); - } catch(turn::WrongStunBufferFormatException &ex2) { - printf("Wrong stun buffer format (2)\n"); - exit(-1); - } catch(...) { - printf("Wrong something (2)\n"); - exit(-1); - } - } - if (padding) { - turn::StunAttrPadding pa; - pa.setPadding(1500); - try { - req.addAttr(pa); - } catch(turn::WrongStunAttrFormatException &ex1) { - printf("Wrong p attr format\n"); - exit(-1); - } catch(turn::WrongStunBufferFormatException &ex2) { - printf("Wrong stun buffer format (3)\n"); - exit(-1); - } catch(...) { - printf("Wrong something (3)\n"); - exit(-1); - } - } + { + int len = 0; + int slen = get_ioa_addr_len(remote_addr); - { - int len = 0; - int slen = get_ioa_addr_len(remote_addr); + do { + len = sendto(sockfd, req.getRawBuffer(), req.getSize(), 0, (struct sockaddr *)remote_addr, (socklen_t)slen); + } while (len < 0 && ((errno == EINTR) || (errno == ENOBUFS) || (errno == EAGAIN))); - do { - len = sendto(sockfd, req.getRawBuffer(), req.getSize(), 0, (struct sockaddr*) remote_addr, (socklen_t) slen); - } while (len < 0 && ((errno == EINTR) || (errno == ENOBUFS) || (errno == EAGAIN))); + if (len < 0) + err(-1, NULL); + } - if (len < 0) - err(-1, NULL); + if (addr_get_from_sock(sockfd, local_addr) < 0) { + printf("%s: Cannot get address from local socket\n", __FUNCTION__); + } else { + *local_port = addr_get_port(local_addr); + } - } - - if (addr_get_from_sock(sockfd, local_addr) < 0) { - printf("%s: Cannot get address from local socket\n", __FUNCTION__); - } else { - *local_port = addr_get_port(local_addr); - } - - return ret; + return ret; } +static int stunclient_receive(int sockfd, ioa_addr *local_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, + int *rfc5780) { + int ret = 0; -static int stunclient_receive(int sockfd, ioa_addr *local_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *rfc5780){ - int ret=0; + { + int len = 0; + stun_buffer buf; + uint8_t *ptr = buf.buf; + int recvd = 0; + const int to_recv = sizeof(buf.buf); + struct timeval tv; + tv.tv_sec = 3; /* 3 Secs Timeout */ + tv.tv_usec = 0; // Not init'ing this can cause strange errors - { - int len = 0; - stun_buffer buf; - uint8_t *ptr = buf.buf; - int recvd = 0; - const int to_recv = sizeof(buf.buf); - struct timeval tv; + setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)); - tv.tv_sec = 3; /* 3 Secs Timeout */ - tv.tv_usec = 0; // Not init'ing this can cause strange errors + do { + len = recv(sockfd, ptr, to_recv - recvd, 0); + if (len > 0) { + recvd += len; + ptr += len; + break; + } + } while (len < 0 && (errno == EINTR)); - setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval)); + if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { + printf("STUN receive timeout..\n"); + ret = 1; + return ret; + } + if (recvd > 0) + len = recvd; + buf.len = len; - do { - len = recv(sockfd, ptr, to_recv - recvd, 0); - if (len > 0) { - recvd += len; - ptr += len; - break; - } - } while (len < 0 && (errno == EINTR)); + try { + turn::StunMsgResponse res(buf.buf, sizeof(buf.buf), (size_t)buf.len, true); - if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { - printf("STUN receive timeout..\n"); - ret = 1; - return ret; - } - if (recvd > 0) - len = recvd; - buf.len = len; + if (res.isCommand()) { + if (res.isSuccess()) { - try { - turn::StunMsgResponse res(buf.buf, sizeof(buf.buf), (size_t)buf.len, true); + if (res.isBindingResponse()) { - if (res.isCommand()) { - if(res.isSuccess()) { + turn::StunAttrIterator iter(res, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS); + if (!iter.eof()) { - if (res.isBindingResponse()) { + turn::StunAttrAddr addr(iter); + addr.getAddr(*reflexive_addr); - turn::StunAttrIterator iter(res,STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS); - if (!iter.eof()) { + turn::StunAttrIterator iter1(res, STUN_ATTRIBUTE_OTHER_ADDRESS); + if (!iter1.eof()) { + *rfc5780 = 1; + printf("\n========================================\n"); + printf("RFC 5780 response %d\n", ++counter); + turn::StunAttrIterator iter2(res, STUN_ATTRIBUTE_MAPPED_ADDRESS); + if (!iter2.eof()) { + ioa_addr mapped_addr; + addr_set_any(&mapped_addr); + turn::StunAttrAddr addr2(iter2); + addr2.getAddr(mapped_addr); + if (!addr_eq(&mapped_addr, reflexive_addr)) { + printf("-= ALG detected! Mapped and XOR-Mapped differ! =-\n"); + addr_debug_print(1, &mapped_addr, "Mapped Address: "); + } else { + printf("No ALG: Mapped == XOR-Mapped\n"); + } + } else { + printf("Not received mapped address attribute!\n"); + } + turn::StunAttrAddr addr1(iter1); + addr1.getAddr(*other_addr); + turn::StunAttrIterator iter3(res, STUN_ATTRIBUTE_RESPONSE_ORIGIN); + if (!iter3.eof()) { + ioa_addr response_origin; + turn::StunAttrAddr addr3(iter3); + addr3.getAddr(response_origin); + addr_debug_print(1, &response_origin, "Response origin: "); + } + addr_debug_print(1, other_addr, "Other addr: "); + } + addr_debug_print(1, reflexive_addr, "UDP reflexive addr"); + addr_debug_print(1, local_addr, "Local addr: "); + } else { + printf("Cannot read the response\n"); + } + } else { + printf("Wrong type of response\n"); + } + } else { + int err_code = res.getError(); + std::string reason = res.getReason(); - turn::StunAttrAddr addr(iter); - addr.getAddr(*reflexive_addr); + printf("The response is an error %d (%s)\n", err_code, reason.c_str()); + } + } else { + printf("The response is not a response message\n"); + } + } catch (...) { + turn::StunMsgRequest msg(buf.buf, sizeof(buf.buf), (size_t)buf.len, true); + if (msg.isRequest(buf.buf, (size_t)buf.len)) { + printf("Received a request (maybe a successful hairpinning)\n"); + return ret; + } else { + printf("The response is not a well formed STUN message\n"); + } + ret = 1; + } + } - turn::StunAttrIterator iter1(res,STUN_ATTRIBUTE_OTHER_ADDRESS); - if (!iter1.eof()) { - *rfc5780 = 1; - printf("\n========================================\n"); - printf("RFC 5780 response %d\n",++counter); - turn::StunAttrIterator iter2(res,STUN_ATTRIBUTE_MAPPED_ADDRESS); - if (!iter2.eof()) { - ioa_addr mapped_addr; - addr_set_any(&mapped_addr); - turn::StunAttrAddr addr2(iter2); - addr2.getAddr(mapped_addr); - if (!addr_eq(&mapped_addr,reflexive_addr)){ - printf("-= ALG detected! Mapped and XOR-Mapped differ! =-\n"); - addr_debug_print(1, &mapped_addr, "Mapped Address: "); - } else { - printf("No ALG: Mapped == XOR-Mapped\n"); - } - } else { - printf("Not received mapped address attribute!\n"); - } turn::StunAttrAddr addr1(iter1); - addr1.getAddr(*other_addr); - turn::StunAttrIterator iter3(res,STUN_ATTRIBUTE_RESPONSE_ORIGIN); - if (!iter3.eof()) { - ioa_addr response_origin; - turn::StunAttrAddr addr3(iter3); - addr3.getAddr(response_origin); - addr_debug_print(1, &response_origin, "Response origin: "); - } - addr_debug_print(1, other_addr, "Other addr: "); - } - addr_debug_print(1, reflexive_addr, "UDP reflexive addr"); - addr_debug_print(1, local_addr, "Local addr: "); - } else { - printf("Cannot read the response\n"); - } - } else { - printf("Wrong type of response\n"); - } - } else { - int err_code = res.getError(); - std::string reason = res.getReason(); - - printf("The response is an error %d (%s)\n", err_code, reason.c_str()); - } - } else { - printf("The response is not a response message\n"); - } - } catch(...) { - turn::StunMsgRequest msg(buf.buf, sizeof(buf.buf), (size_t)buf.len, true); - if (msg.isRequest(buf.buf,(size_t)buf.len)) { - printf("Received a request (maybe a successful hairpinning)\n"); - return ret; - } else { - printf("The response is not a well formed STUN message\n"); - } - ret=1; - } - } - - return ret; + return ret; } +static int run_stunclient(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, + int *local_port, int *rfc5780, int change_ip, int change_port, int padding) { + int ret = 0; -static int run_stunclient(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip, int change_port, int padding){ - int ret=0; + ret = init_socket(&udp_fd, local_addr, *local_port, remote_addr); + ret = stunclient_send(udp_fd, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1); + ret = stunclient_receive(udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); + close(udp_fd); - ret=init_socket(&udp_fd, local_addr, *local_port, remote_addr); - ret=stunclient_send(udp_fd, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1); - ret=stunclient_receive(udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); - close(udp_fd); - - return ret; + return ret; } +static int run_stunclient_hairpinning(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, + ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip, + int change_port, int padding) { + int ret = 0; -static int run_stunclient_hairpinning(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip, int change_port, int padding){ - int ret=0; + init_socket(&udp_fd, local_addr, *local_port, remote_addr); - init_socket(&udp_fd,local_addr,*local_port,remote_addr); + ret = stunclient_send(udp_fd, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1); + ret = stunclient_receive(udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); - ret=stunclient_send(udp_fd, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1); - ret=stunclient_receive(udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); + addr_cpy(remote_addr, reflexive_addr); + addr_set_port(local_addr, 0); + init_socket(&udp_fd2, local_addr, 0, remote_addr); - addr_cpy(remote_addr,reflexive_addr); - addr_set_port(local_addr, 0); + ret = stunclient_send(udp_fd2, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1); + ret = stunclient_receive(udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); - init_socket(&udp_fd2,local_addr,0,remote_addr); + if (ret) { + ret = stunclient_receive(udp_fd2, local_addr, reflexive_addr, other_addr, rfc5780); + } + close(udp_fd); + close(udp_fd2); - ret=stunclient_send(udp_fd2, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1); - ret=stunclient_receive(udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); - - if(ret){ - ret=stunclient_receive(udp_fd2, local_addr, reflexive_addr, other_addr, rfc5780); - } - close(udp_fd); - close(udp_fd2); - - return ret; + return ret; } -static int run_stunclient_lifetime(int timer,ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip, int change_port, int padding){ - int ret=0; - int response_port; +static int run_stunclient_lifetime(int timer, ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, + ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip, int change_port, + int padding) { + int ret = 0; + int response_port; - init_socket(&udp_fd, local_addr, *local_port, remote_addr); + init_socket(&udp_fd, local_addr, *local_port, remote_addr); - ret=stunclient_send(udp_fd, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1); - ret=stunclient_receive(udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); + ret = stunclient_send(udp_fd, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1); + ret = stunclient_receive(udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); - addr_set_port(local_addr, 0); - sleep(timer); + addr_set_port(local_addr, 0); + sleep(timer); - init_socket(&udp_fd2,local_addr,0,remote_addr); - response_port=addr_get_port(reflexive_addr); + init_socket(&udp_fd2, local_addr, 0, remote_addr); + response_port = addr_get_port(reflexive_addr); - ret=stunclient_send(udp_fd2, local_addr, local_port, remote_addr, change_ip, change_port, padding, response_port); - ret=stunclient_receive(udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); + ret = stunclient_send(udp_fd2, local_addr, local_port, remote_addr, change_ip, change_port, padding, response_port); + ret = stunclient_receive(udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); - socket_closesocket(udp_fd); - socket_closesocket(udp_fd2); + socket_closesocket(udp_fd); + socket_closesocket(udp_fd2); - return ret; + return ret; } #else -static int init_socket(int *socketfd, ioa_addr *local_addr, int local_port, ioa_addr *remote_addr){ - int ret=0; +static int init_socket(int *socketfd, ioa_addr *local_addr, int local_port, ioa_addr *remote_addr) { + int ret = 0; - *socketfd = socket(remote_addr->ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL); - if (udp_fd < 0) - err(-1, NULL); + *socketfd = socket(remote_addr->ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL); + if (udp_fd < 0) + err(-1, NULL); - if (local_port >= 0) { - addr_set_port(local_addr, local_port); - } - if (!addr_any(local_addr)) { - if (addr_bind(*socketfd, local_addr,0,1,UDP_SOCKET) < 0) { - err(-1, NULL); - } - } + if (local_port >= 0) { + addr_set_port(local_addr, local_port); + } + if (!addr_any(local_addr)) { + if (addr_bind(*socketfd, local_addr, 0, 1, UDP_SOCKET) < 0) { + err(-1, NULL); + } + } - return ret; + return ret; } -static int stunclient_send(stun_buffer *buf, int sockfd, ioa_addr *local_addr, int *local_port, ioa_addr *remote_addr, int change_ip, int change_port, int padding, int response_port){ - int ret=0; +static int stunclient_send(stun_buffer *buf, int sockfd, ioa_addr *local_addr, int *local_port, ioa_addr *remote_addr, + int change_ip, int change_port, int padding, int response_port) { + int ret = 0; - stun_prepare_binding_request(buf); + stun_prepare_binding_request(buf); - if (response_port >= 0) { - stun_attr_add_response_port_str((uint8_t*) (buf->buf), (size_t*) &(buf->len), (uint16_t) response_port); - } - if (change_ip || change_port) { - stun_attr_add_change_request_str((uint8_t*) buf->buf, (size_t*) &(buf->len), change_ip, change_port); - } - if (padding) { - if(stun_attr_add_padding_str((uint8_t*) buf->buf, (size_t*) &(buf->len), 1500)<0) { - printf("%s: ERROR: Cannot add padding\n",__FUNCTION__); - } - } + if (response_port >= 0) { + stun_attr_add_response_port_str((uint8_t *)(buf->buf), (size_t *)&(buf->len), (uint16_t)response_port); + } + if (change_ip || change_port) { + stun_attr_add_change_request_str((uint8_t *)buf->buf, (size_t *)&(buf->len), change_ip, change_port); + } + if (padding) { + if (stun_attr_add_padding_str((uint8_t *)buf->buf, (size_t *)&(buf->len), 1500) < 0) { + printf("%s: ERROR: Cannot add padding\n", __FUNCTION__); + } + } - { - int len = 0; - int slen = get_ioa_addr_len(remote_addr); + { + int len = 0; + int slen = get_ioa_addr_len(remote_addr); - do { - len = sendto(sockfd, buf->buf, buf->len, 0, (struct sockaddr*) remote_addr, (socklen_t) slen); - } while (len < 0 && ((errno == EINTR) || (errno == ENOBUFS) || (errno == EAGAIN))); + do { + len = sendto(sockfd, buf->buf, buf->len, 0, (struct sockaddr *)remote_addr, (socklen_t)slen); + } while (len < 0 && ((errno == EINTR) || (errno == ENOBUFS) || (errno == EAGAIN))); - if (len < 0) - err(-1, NULL); + if (len < 0) + err(-1, NULL); + } - } + if (addr_get_from_sock(sockfd, local_addr) < 0) { + printf("%s: Cannot get address from local socket\n", __FUNCTION__); + } else { + *local_port = addr_get_port(local_addr); + } - if (addr_get_from_sock(sockfd, local_addr) < 0) { - printf("%s: Cannot get address from local socket\n", __FUNCTION__); - } else { - *local_port = addr_get_port(local_addr); - } - - return ret; + return ret; } +static int stunclient_receive(stun_buffer *buf, int sockfd, ioa_addr *local_addr, ioa_addr *reflexive_addr, + ioa_addr *other_addr, int *rfc5780) { + int ret = 0; -static int stunclient_receive(stun_buffer *buf, int sockfd, ioa_addr *local_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *rfc5780){ - int ret=0; + { + int len = 0; + uint8_t *ptr = buf->buf; + int recvd = 0; + const int to_recv = sizeof(buf->buf); + struct timeval tv; + tv.tv_sec = 3; /* 3 Secs Timeout */ + tv.tv_usec = 0; // Not init'ing this can cause strange errors - { - int len = 0; - uint8_t *ptr = buf->buf; - int recvd = 0; - const int to_recv = sizeof(buf->buf); - struct timeval tv; + setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)); - tv.tv_sec = 3; /* 3 Secs Timeout */ - tv.tv_usec = 0; // Not init'ing this can cause strange errors + do { + len = recv(sockfd, ptr, to_recv - recvd, 0); + if (len > 0) { + recvd += len; + ptr += len; + break; + } + } while (len < 0 && (errno == EINTR)); - setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval)); + if (recvd > 0) + len = recvd; + buf->len = len; - do { - len = recv(sockfd, ptr, to_recv - recvd, 0); - if (len > 0) { - recvd += len; - ptr += len; - break; - } - } while (len < 0 && (errno == EINTR)); + if (stun_is_command_message(buf)) { - if (recvd > 0) - len = recvd; - buf->len = len; + if (stun_is_response(buf)) { - if (stun_is_command_message(buf)) { + if (stun_is_success_response(buf)) { - if (stun_is_response(buf)) { + if (stun_is_binding_response(buf)) { - if (stun_is_success_response(buf)) { + addr_set_any(reflexive_addr); + if (stun_attr_get_first_addr(buf, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, reflexive_addr, NULL) >= 0) { - if (stun_is_binding_response(buf)) { + stun_attr_ref sar = stun_attr_get_first_by_type_str(buf->buf, buf->len, STUN_ATTRIBUTE_OTHER_ADDRESS); + if (sar) { + *rfc5780 = 1; + printf("\n========================================\n"); + printf("RFC 5780 response %d\n", ++counter); + ioa_addr mapped_addr; + addr_set_any(&mapped_addr); + if (stun_attr_get_first_addr(buf, STUN_ATTRIBUTE_MAPPED_ADDRESS, &mapped_addr, NULL) >= 0) { + if (!addr_eq(&mapped_addr, reflexive_addr)) { + printf("-= ALG detected! Mapped and XOR-Mapped differ! =-\n"); + addr_debug_print(1, &mapped_addr, "Mapped Address: "); + } else { + printf("No ALG: Mapped == XOR-Mapped\n"); + } + } else { + printf("Not received mapped address attribute.\n"); + } + stun_attr_get_addr_str((uint8_t *)buf->buf, (size_t)buf->len, sar, other_addr, NULL); + sar = stun_attr_get_first_by_type_str(buf->buf, buf->len, STUN_ATTRIBUTE_RESPONSE_ORIGIN); + if (sar) { + ioa_addr response_origin; + stun_attr_get_addr_str((uint8_t *)buf->buf, (size_t)buf->len, sar, &response_origin, NULL); + addr_debug_print(1, &response_origin, "Response origin: "); + } + addr_debug_print(1, other_addr, "Other addr: "); + } + addr_debug_print(1, reflexive_addr, "UDP reflexive addr"); + addr_debug_print(1, local_addr, "Local addr: "); + } else { + printf("Cannot read the response\n"); + } + } else { + printf("Wrong type of response\n"); + } + } else { + int err_code = 0; + uint8_t err_msg[1025] = "\0"; + size_t err_msg_size = sizeof(err_msg); + if (stun_is_error_response(buf, &err_code, err_msg, err_msg_size)) { + printf("The response is an error %d (%s)\n", err_code, (char *)err_msg); + } else { + printf("The response is an unrecognized error\n"); + } + } + } else if (stun_is_request(buf)) { + printf("Received a request (maybe a successful hairpinning)\n"); + } else { + printf("The response is not a response message\n"); + ret = 1; + } + } else { + if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { + printf("STUN receive timeout..\n"); + } else { + printf("The response is not a STUN message\n"); + } + ret = 1; + } + } - addr_set_any(reflexive_addr); - if (stun_attr_get_first_addr(buf, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, reflexive_addr, NULL) >= 0) { - - stun_attr_ref sar = stun_attr_get_first_by_type_str(buf->buf, buf->len, STUN_ATTRIBUTE_OTHER_ADDRESS); - if (sar) { - *rfc5780 = 1; - printf("\n========================================\n"); - printf("RFC 5780 response %d\n",++counter); - ioa_addr mapped_addr; - addr_set_any(&mapped_addr); - if (stun_attr_get_first_addr(buf, STUN_ATTRIBUTE_MAPPED_ADDRESS, &mapped_addr, NULL) >= 0) { - if (!addr_eq(&mapped_addr,reflexive_addr)){ - printf("-= ALG detected! Mapped and XOR-Mapped differ! =-\n"); - addr_debug_print(1, &mapped_addr, "Mapped Address: "); - }else { - printf("No ALG: Mapped == XOR-Mapped\n"); - } - } else { - printf("Not received mapped address attribute.\n"); - } - stun_attr_get_addr_str((uint8_t *) buf->buf, (size_t) buf->len, sar, other_addr, NULL); - sar = stun_attr_get_first_by_type_str(buf->buf, buf->len, STUN_ATTRIBUTE_RESPONSE_ORIGIN); - if (sar) { - ioa_addr response_origin; - stun_attr_get_addr_str((uint8_t *) buf->buf, (size_t) buf->len, sar, &response_origin, NULL); - addr_debug_print(1, &response_origin, "Response origin: "); - } - addr_debug_print(1, other_addr, "Other addr: "); - } - addr_debug_print(1, reflexive_addr, "UDP reflexive addr"); - addr_debug_print(1, local_addr, "Local addr: "); - } else { - printf("Cannot read the response\n"); - } - } else { - printf("Wrong type of response\n"); - } - } else { - int err_code = 0; - uint8_t err_msg[1025] = "\0"; - size_t err_msg_size = sizeof(err_msg); - if (stun_is_error_response(buf, &err_code, err_msg, err_msg_size)) { - printf("The response is an error %d (%s)\n", err_code, (char*) err_msg); - } else { - printf("The response is an unrecognized error\n"); - } - } - } else if (stun_is_request(buf)) { - printf("Received a request (maybe a successful hairpinning)\n"); - } else { - printf("The response is not a response message\n"); - ret=1; - } - } else { - if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { - printf("STUN receive timeout..\n"); - }else{ - printf("The response is not a STUN message\n"); - } - ret=1; - } - } - - return ret; + return ret; } +static int run_stunclient(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, + int *local_port, int *rfc5780, int change_ip, int change_port, int padding) { + int ret = 0; + stun_buffer buf; -static int run_stunclient(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip, int change_port, int padding){ - int ret=0; - stun_buffer buf; + init_socket(&udp_fd, local_addr, *local_port, remote_addr); - init_socket(&udp_fd, local_addr, *local_port, remote_addr); + ret = stunclient_send(&buf, udp_fd, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1); + ret = stunclient_receive(&buf, udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); - ret=stunclient_send(&buf, udp_fd, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1); - ret=stunclient_receive(&buf, udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); + socket_closesocket(udp_fd); - socket_closesocket(udp_fd); - - return ret; + return ret; } -static int run_stunclient_hairpinning(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip, int change_port, int padding){ - int ret=0; - stun_buffer buf; - stun_buffer buf2; +static int run_stunclient_hairpinning(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, + ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip, + int change_port, int padding) { + int ret = 0; + stun_buffer buf; + stun_buffer buf2; - init_socket(&udp_fd, local_addr, *local_port, remote_addr); + init_socket(&udp_fd, local_addr, *local_port, remote_addr); - ret=stunclient_send(&buf, udp_fd, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1); - ret=stunclient_receive(&buf, udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); + ret = stunclient_send(&buf, udp_fd, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1); + ret = stunclient_receive(&buf, udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); + addr_cpy(remote_addr, reflexive_addr); + addr_set_port(local_addr, 0); - addr_cpy(remote_addr,reflexive_addr); - addr_set_port(local_addr, 0); + init_socket(&udp_fd2, local_addr, 0, remote_addr); - init_socket(&udp_fd2,local_addr,0,remote_addr); + ret = stunclient_send(&buf2, udp_fd2, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1); + ret = stunclient_receive(&buf, udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); - ret=stunclient_send(&buf2, udp_fd2, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1); - ret=stunclient_receive(&buf, udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); + if (ret) { + ret = stunclient_receive(&buf2, udp_fd2, local_addr, reflexive_addr, other_addr, rfc5780); + } - if(ret){ - ret=stunclient_receive(&buf2, udp_fd2, local_addr, reflexive_addr, other_addr, rfc5780); - } + socket_closesocket(udp_fd); + socket_closesocket(udp_fd2); - socket_closesocket(udp_fd); - socket_closesocket(udp_fd2); - - return ret; + return ret; } +static int run_stunclient_lifetime(int timer, ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, + ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip, int change_port, + int padding) { + int ret = 0; + stun_buffer buf; + stun_buffer buf2; + int response_port; -static int run_stunclient_lifetime(int timer,ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip, int change_port, int padding){ - int ret=0; - stun_buffer buf; - stun_buffer buf2; - int response_port; + init_socket(&udp_fd, local_addr, *local_port, remote_addr); - init_socket(&udp_fd, local_addr, *local_port, remote_addr); + ret = stunclient_send(&buf, udp_fd, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1); + ret = stunclient_receive(&buf, udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); - ret=stunclient_send(&buf, udp_fd, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1); - ret=stunclient_receive(&buf, udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); + addr_set_port(local_addr, 0); + sleep(timer); - addr_set_port(local_addr, 0); - sleep(timer); + init_socket(&udp_fd2, local_addr, 0, remote_addr); + response_port = addr_get_port(reflexive_addr); - init_socket(&udp_fd2,local_addr,0,remote_addr); - response_port=addr_get_port(reflexive_addr); + ret = stunclient_send(&buf2, udp_fd2, local_addr, local_port, remote_addr, change_ip, change_port, padding, + response_port); + ret = stunclient_receive(&buf, udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); - ret=stunclient_send(&buf2, udp_fd2, local_addr, local_port, remote_addr, change_ip, change_port, padding, response_port); - ret=stunclient_receive(&buf, udp_fd, local_addr, reflexive_addr, other_addr, rfc5780); + socket_closesocket(udp_fd); + socket_closesocket(udp_fd2); - socket_closesocket(udp_fd); - socket_closesocket(udp_fd2); - - return ret; + return ret; } #endif //////////////// local definitions ///////////////// -static char Usage[] = -"Usage: natdiscovery [options] address\n" -"Options:\n" -" -m NAT mapping behavior discovery\n" -" -f NAT filtering behavior discovery\n" -" -t NAT mapping lifetime behavior discovery\n" -" Requires a timer (-T)\n" -" -c NAT collision behavior discovery\n" -" Requires an alternative IP address (-A)\n" -" -H NAT hairpinning behavior discovery\n" -" -P Add 1500 byte Padding to the behavior discovery\n" -" Applicable with all except NAT mapping Lifetime discovery\n" -" -p STUN server port (Default: 3478)\n" -" -L Local address to use (optional)\n" -" -l Local port to use (use with -L)\n" -" -A Local alternative address to use\n" -" Used by collision behavior discovery\n" -" -T Mapping lifetime timer (sec)\n" -" Used by mapping lifetime behavior discovery\n"; +static char Usage[] = "Usage: natdiscovery [options] address\n" + "Options:\n" + " -m NAT mapping behavior discovery\n" + " -f NAT filtering behavior discovery\n" + " -t NAT mapping lifetime behavior discovery\n" + " Requires a timer (-T)\n" + " -c NAT collision behavior discovery\n" + " Requires an alternative IP address (-A)\n" + " -H NAT hairpinning behavior discovery\n" + " -P Add 1500 byte Padding to the behavior discovery\n" + " Applicable with all except NAT mapping Lifetime discovery\n" + " -p STUN server port (Default: 3478)\n" + " -L Local address to use (optional)\n" + " -l Local port to use (use with -L)\n" + " -A Local alternative address to use\n" + " Used by collision behavior discovery\n" + " -T Mapping lifetime timer (sec)\n" + " Used by mapping lifetime behavior discovery\n"; ////////////////////////////////////////////////// -static void init(int first, ioa_addr *local_addr, ioa_addr *remote_addr, int *local_port, int port, int *rfc5780, char* local_addr_string, char* remote_param) -{ - addr_set_any(local_addr); +static void init(int first, ioa_addr *local_addr, ioa_addr *remote_addr, int *local_port, int port, int *rfc5780, + char *local_addr_string, char *remote_param) { + addr_set_any(local_addr); - if(local_addr_string[0]) { - if(make_ioa_addr((const uint8_t*)local_addr_string, 0, local_addr)<0) { - err(-1,NULL); - } - } - if (!first) *local_port=-1; - *rfc5780 = 0; + if (local_addr_string[0]) { + if (make_ioa_addr((const uint8_t *)local_addr_string, 0, local_addr) < 0) { + err(-1, NULL); + } + } + if (!first) + *local_port = -1; + *rfc5780 = 0; - if (make_ioa_addr((const uint8_t*)remote_param, port, remote_addr) < 0) - err(-1, NULL); + if (make_ioa_addr((const uint8_t *)remote_param, port, remote_addr) < 0) + err(-1, NULL); } -static void discoveryresult(const char *decision){ - printf("\n========================================\n"); - printf("%s",decision); - printf("\n========================================\n"); +static void discoveryresult(const char *decision) { + printf("\n========================================\n"); + printf("%s", decision); + printf("\n========================================\n"); } -int main(int argc, char **argv) -{ - int remote_port = DEFAULT_STUN_PORT; - char local_addr_string[256]="\0"; - char local2_addr_string[256]="\0"; - int c=0; - int mapping = 0; - int filtering = 0; - int lifetime=0; - int timer=-1; - int collision = 0; - int padding = 0; - int hairpinning = 0; - int local_port=-1; - int rfc5780; - int first=1; - ioa_addr other_addr, reflexive_addr, tmp_addr, remote_addr, local_addr, local2_addr; +int main(int argc, char **argv) { + int remote_port = DEFAULT_STUN_PORT; + char local_addr_string[256] = "\0"; + char local2_addr_string[256] = "\0"; + int c = 0; + int mapping = 0; + int filtering = 0; + int lifetime = 0; + int timer = -1; + int collision = 0; + int padding = 0; + int hairpinning = 0; + int local_port = -1; + int rfc5780; + int first = 1; + ioa_addr other_addr, reflexive_addr, tmp_addr, remote_addr, local_addr, local2_addr; - if (socket_init()) return -1; + if (socket_init()) + return -1; - set_logfile("stdout"); - set_no_stdout_log(1); - set_system_parameters(0); + set_logfile("stdout"); + set_no_stdout_log(1); + set_system_parameters(0); - memset(local_addr_string, 0, sizeof(local_addr_string)); - memset(local2_addr_string, 0, sizeof(local2_addr_string)); - addr_set_any(&remote_addr); - addr_set_any(&other_addr); - addr_set_any(&reflexive_addr); - addr_set_any(&tmp_addr); + memset(local_addr_string, 0, sizeof(local_addr_string)); + memset(local2_addr_string, 0, sizeof(local2_addr_string)); + addr_set_any(&remote_addr); + addr_set_any(&other_addr); + addr_set_any(&reflexive_addr); + addr_set_any(&tmp_addr); - while ((c = getopt(argc, argv, "mftcPHp:L:l:A:T:")) != -1) { - switch(c) { - case 'm': - mapping=1; - break; - case 'f': - filtering=1; - break; - case 't': - lifetime=1; - break; - case 'c': - collision=1; - break; - case 'H': - hairpinning=1; - break; - case 'P': - padding=1; - break; - case 'p': - remote_port = atoi(optarg); - break; - case 'L': - STRCPY(local_addr_string, optarg); - break; - case 'l': - local_port = atoi(optarg); - break; - case 'A': - STRCPY(local2_addr_string, optarg); - break; - case 'T': - timer = atoi(optarg); - break; - default: - fprintf(stderr,"%s\n", Usage); - exit(1); - } - } + while ((c = getopt(argc, argv, "mftcPHp:L:l:A:T:")) != -1) { + switch (c) { + case 'm': + mapping = 1; + break; + case 'f': + filtering = 1; + break; + case 't': + lifetime = 1; + break; + case 'c': + collision = 1; + break; + case 'H': + hairpinning = 1; + break; + case 'P': + padding = 1; + break; + case 'p': + remote_port = atoi(optarg); + break; + case 'L': + STRCPY(local_addr_string, optarg); + break; + case 'l': + local_port = atoi(optarg); + break; + case 'A': + STRCPY(local2_addr_string, optarg); + break; + case 'T': + timer = atoi(optarg); + break; + default: + fprintf(stderr, "%s\n", Usage); + exit(1); + } + } - if(optind>=argc) { - fprintf(stderr, "%s\n", Usage); - exit(-1); - } + if (optind >= argc) { + fprintf(stderr, "%s\n", Usage); + exit(-1); + } - if(collision && !strcmp(local2_addr_string,"\0")){ - fprintf(stderr, "Use \"-A\" to add an Alternative local IP address.\n"); - fprintf(stderr, "It is mandatory with \"-c\" collision behavior detection..\n"); - exit(-1); - } + if (collision && !strcmp(local2_addr_string, "\0")) { + fprintf(stderr, "Use \"-A\" to add an Alternative local IP address.\n"); + fprintf(stderr, "It is mandatory with \"-c\" collision behavior detection..\n"); + exit(-1); + } - if(lifetime && timer==-1){ - fprintf(stderr, "Use \"-T\" to add a timer value (in sec).\n"); - fprintf(stderr, "It is mandatory with \"-b\" mapping lifetime behavior detection..\n"); - exit(-1); - } + if (lifetime && timer == -1) { + fprintf(stderr, "Use \"-T\" to add a timer value (in sec).\n"); + fprintf(stderr, "It is mandatory with \"-b\" mapping lifetime behavior detection..\n"); + exit(-1); + } - if(local_port>=0 && !strcmp(local_addr_string,"\0")){ - fprintf(stderr, "To use local port please specify local address \"-L\"!\n"); - fprintf(stderr, "We need to know the address familly to set the port.\n"); - exit(-1); - } + if (local_port >= 0 && !strcmp(local_addr_string, "\0")) { + fprintf(stderr, "To use local port please specify local address \"-L\"!\n"); + fprintf(stderr, "We need to know the address familly to set the port.\n"); + exit(-1); + } + if (lifetime) { + printf("\n-= Mapping Lifetime Behavior Discovery =-\n"); + init(first, &local_addr, &remote_addr, &local_port, remote_port, &rfc5780, local_addr_string, argv[optind]); + first = 0; + run_stunclient_lifetime(timer, &local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780, 0, 0, + padding); + } - if(lifetime) { - printf("\n-= Mapping Lifetime Behavior Discovery =-\n"); - init(first, &local_addr, &remote_addr, &local_port, remote_port, &rfc5780, local_addr_string, argv[optind]); - first=0; - run_stunclient_lifetime(timer, &local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding); - } + if (hairpinning) { + printf("\n-= Hairpinning Behavior Discovery =-\n"); + init(first, &local_addr, &remote_addr, &local_port, remote_port, &rfc5780, local_addr_string, argv[optind]); + first = 0; + run_stunclient_hairpinning(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780, 0, 0, + padding); + } - if(hairpinning) { - printf("\n-= Hairpinning Behavior Discovery =-\n"); - init(first, &local_addr, &remote_addr, &local_port, remote_port, &rfc5780, local_addr_string, argv[optind]); - first=0; - run_stunclient_hairpinning(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding); - } + if (mapping) { + printf("\n-= Mapping Behavior Discovery =-\n"); + init(first, &local_addr, &remote_addr, &local_port, remote_port, &rfc5780, local_addr_string, argv[optind]); + first = 0; + run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780, 0, 0, padding); + if (addr_eq(&local_addr, &reflexive_addr)) { + discoveryresult("No NAT! (Endpoint Independent Mapping)"); + } + if (rfc5780) { + if (!addr_any(&other_addr)) { + addr_cpy(&tmp_addr, &reflexive_addr); - if(mapping) { - printf("\n-= Mapping Behavior Discovery =-\n"); - init(first,&local_addr, &remote_addr, &local_port, remote_port, &rfc5780, local_addr_string, argv[optind]); - first=0; + addr_cpy(&remote_addr, &other_addr); + addr_set_port(&remote_addr, remote_port); - run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding); - if (addr_eq(&local_addr,&reflexive_addr)){ - discoveryresult("No NAT! (Endpoint Independent Mapping)"); - } - if(rfc5780) { - if(!addr_any(&other_addr)){ - addr_cpy(&tmp_addr, &reflexive_addr); + run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780, 0, 0, padding); - addr_cpy(&remote_addr, &other_addr); - addr_set_port(&remote_addr, remote_port); + if (addr_eq(&tmp_addr, &reflexive_addr)) { + discoveryresult("NAT with Endpoint Independent Mapping!"); + } else { + addr_cpy(&tmp_addr, &reflexive_addr); + addr_cpy(&remote_addr, &other_addr); + run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780, 0, 0, padding); + if (addr_eq(&tmp_addr, &reflexive_addr)) { + discoveryresult("NAT with Address Dependent Mapping!"); + } else { + discoveryresult("NAT with Address and Port Dependent Mapping!"); + } + } + } + } + } - run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding); + if (filtering) { + printf("\n-= Filtering Behavior Discovery =-\n"); + init(first, &local_addr, &remote_addr, &local_port, remote_port, &rfc5780, local_addr_string, argv[optind]); + first = 0; - if(addr_eq(&tmp_addr,&reflexive_addr)){ - discoveryresult("NAT with Endpoint Independent Mapping!"); - } else { - addr_cpy(&tmp_addr, &reflexive_addr); - addr_cpy(&remote_addr, &other_addr); - run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding); - if(addr_eq(&tmp_addr,&reflexive_addr)){ - discoveryresult("NAT with Address Dependent Mapping!"); - } else { - discoveryresult("NAT with Address and Port Dependent Mapping!"); - } - } - } - } - } + run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780, 0, 0, padding); + if (addr_eq(&local_addr, &reflexive_addr)) { + discoveryresult("No NAT! (Endpoint Independent Mapping)"); + } + if (rfc5780) { + if (!addr_any(&other_addr)) { + int res = 0; + res = run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780, 1, 1, + padding); + if (!res) { + discoveryresult("NAT with Endpoint Independent Filtering!"); + } else { + res = 0; + res = run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780, 0, 1, + padding); + if (!res) { + discoveryresult("NAT with Address Dependent Filtering!"); + } else { + discoveryresult("NAT with Address and Port Dependent Filtering!"); + } + } + } + } + } + if (collision) { + printf("\n-= Collision Behavior Discovery =-\n"); + init(first, &local_addr, &remote_addr, &local_port, remote_port, &rfc5780, local_addr_string, argv[optind]); + first = 0; - if(filtering) { - printf("\n-= Filtering Behavior Discovery =-\n"); - init(first,&local_addr, &remote_addr, &local_port, remote_port, &rfc5780, local_addr_string, argv[optind]); - first=0; + addr_set_any(&local2_addr); - run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding); - if(addr_eq(&local_addr, &reflexive_addr)){ - discoveryresult("No NAT! (Endpoint Independent Mapping)"); - } - if(rfc5780) { - if(!addr_any(&other_addr)){ - int res=0; - res=run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,1,1,padding); - if (!res) { - discoveryresult("NAT with Endpoint Independent Filtering!"); - } else { - res=0; - res=run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,1,padding); - if(!res){ - discoveryresult("NAT with Address Dependent Filtering!"); - } else { - discoveryresult("NAT with Address and Port Dependent Filtering!"); - } - } - } - } - } + if (local2_addr_string[0]) { + if (make_ioa_addr((const uint8_t *)local2_addr_string, 0, &local2_addr) < 0) { + err(-1, NULL); + } + } + run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780, 0, 0, padding); + addr_set_port(&local2_addr, addr_get_port(&local_addr)); + run_stunclient(&local2_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780, 0, 0, padding); + } + if (!filtering && !mapping && !collision && !hairpinning && !lifetime) { + printf("Please use either -f or -m or -c or -t or -H parameter for Filtering or Mapping behavior discovery.\n"); + } + socket_closesocket(udp_fd); + socket_closesocket(udp_fd2); - if(collision) { - printf("\n-= Collision Behavior Discovery =-\n"); - init(first,&local_addr, &remote_addr, &local_port, remote_port, &rfc5780, local_addr_string, argv[optind]); - first=0; - - addr_set_any(&local2_addr); - - if(local2_addr_string[0]) { - if(make_ioa_addr((const uint8_t*)local2_addr_string, 0, &local2_addr)<0) { - err(-1,NULL); - } - } - - run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding); - addr_set_port(&local2_addr,addr_get_port(&local_addr)); - run_stunclient(&local2_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding); - } - - if (!filtering && !mapping && !collision && !hairpinning && !lifetime) { - printf("Please use either -f or -m or -c or -t or -H parameter for Filtering or Mapping behavior discovery.\n"); - } - socket_closesocket(udp_fd); - socket_closesocket(udp_fd2); - - return 0; + return 0; } diff --git a/src/apps/oauth/oauth.c b/src/apps/oauth/oauth.c index b4b07b0..40e315d 100644 --- a/src/apps/oauth/oauth.c +++ b/src/apps/oauth/oauth.c @@ -32,456 +32,441 @@ #include #endif -#include -#include -#include -#include #include #include +#include +#include +#include +#include -#include "ns_turn_utils.h" #include "apputils.h" +#include "ns_turn_utils.h" #include "stun_buffer.h" //////////////////////////////////////////////////// -#define OAUTH_TOKEN_SIZE 1000 //TODO: find insted of 1000 the real max of encoded token length +#define OAUTH_TOKEN_SIZE 1000 // TODO: find insted of 1000 the real max of encoded token length #define OAUTH_MAC_KEY_SIZE 32 #define OAUTH_LTK_ID_SIZE 32 #define OAUTH_LTK_SIZE 32 #define OAUTH_LTK_BASE64ENCODED_SIZE 44 #define OAUTH_TOKEN_LIFETIME 3600 -#define OAUTH_AS_RS_ALG_SIZE 7 -#define OAUTH_SERVER_NAME_SIZE 255 -#define OAUTH_GCM_NONCE_BASE64ENCODED_SIZE 16 +#define OAUTH_AS_RS_ALG_SIZE 7 +#define OAUTH_SERVER_NAME_SIZE 255 +#define OAUTH_GCM_NONCE_BASE64ENCODED_SIZE 16 #define OAUTH_HMAC_ALG_SIZE 20 +static int setup_ikm_key(const char *kid, const char *ikm_key, const turn_time_t key_timestamp, + const turn_time_t key_lifetime, const char *as_rs_alg, oauth_key *key) { -static int setup_ikm_key(const char *kid, - const char *ikm_key, - const turn_time_t key_timestamp, - const turn_time_t key_lifetime, - const char *as_rs_alg, - oauth_key *key) { + memset(key, 0, sizeof(*key)); - memset(key, 0, sizeof(*key)); + oauth_key_data okd; + memset(&okd, 0, sizeof(okd)); - oauth_key_data okd; - memset(&okd, 0, sizeof(okd)); + { + oauth_key_data_raw okdr; + memset(&okdr, 0, sizeof(okdr)); - { - oauth_key_data_raw okdr; - memset(&okdr, 0, sizeof(okdr)); + STRCPY(okdr.kid, kid); + STRCPY(okdr.ikm_key, ikm_key); + STRCPY(okdr.as_rs_alg, as_rs_alg); + okdr.timestamp = key_timestamp; + okdr.lifetime = key_lifetime; - STRCPY(okdr.kid,kid); - STRCPY(okdr.ikm_key,ikm_key); - STRCPY(okdr.as_rs_alg,as_rs_alg); - okdr.timestamp = key_timestamp; - okdr.lifetime = key_lifetime; + convert_oauth_key_data_raw(&okdr, &okd); + } - convert_oauth_key_data_raw(&okdr, &okd); - } + char err_msg[1025] = "\0"; + size_t err_msg_size = sizeof(err_msg) - 1; - char err_msg[1025] = "\0"; - size_t err_msg_size = sizeof(err_msg) - 1; + if (convert_oauth_key_data(&okd, key, err_msg, err_msg_size) < 0) { + fprintf(stderr, "%s\n", err_msg); + return -1; + } - if (convert_oauth_key_data(&okd, key, err_msg, err_msg_size) < 0) { - fprintf(stderr, "%s\n", err_msg); - return -1; - } - - return 0; + return 0; } +static int encode_token(const char *server_name, const char *gcm_nonce, const char *mac_key, + const uint64_t token_timestamp, const uint32_t token_lifetime, const oauth_key key, + char *base64encoded_etoken) { + oauth_token ot; + memset(&ot, 0, sizeof(ot)); -static int encode_token(const char* server_name, - const char* gcm_nonce, - const char* mac_key, - const uint64_t token_timestamp, - const uint32_t token_lifetime, - const oauth_key key, - char* base64encoded_etoken) { + const size_t mac_key_length = strlen(mac_key); + ot.enc_block.key_length = (uint16_t)mac_key_length; + STRCPY(ot.enc_block.mac_key, mac_key); + ot.enc_block.timestamp = token_timestamp; + ot.enc_block.lifetime = token_lifetime; + encoded_oauth_token etoken; + memset(&etoken, 0, sizeof(etoken)); - oauth_token ot; - memset(&ot, 0, sizeof(ot)); + // TODO: avoid this hack + if (!*gcm_nonce) + gcm_nonce = NULL; - const size_t mac_key_length=strlen(mac_key); - ot.enc_block.key_length = (uint16_t)mac_key_length; - STRCPY(ot.enc_block.mac_key,mac_key); - ot.enc_block.timestamp = token_timestamp; - ot.enc_block.lifetime = token_lifetime; + if (encode_oauth_token((const uint8_t *)server_name, &etoken, &key, &ot, (const uint8_t *)gcm_nonce) < 0) { + fprintf(stderr, "%s: cannot encode oauth token\n", __FUNCTION__); + return -1; + } - encoded_oauth_token etoken; - memset(&etoken, 0, sizeof(etoken)); + size_t base64encoded_etoken_length; + char *tmp = base64_encode((unsigned char *)(etoken.token), etoken.size, &base64encoded_etoken_length); + STRCPY(base64encoded_etoken, tmp); + free(tmp); - // TODO: avoid this hack - if (!*gcm_nonce) gcm_nonce=NULL; - - if (encode_oauth_token((const uint8_t *) server_name, &etoken, &key, &ot,(const uint8_t *) gcm_nonce) < 0) { - fprintf(stderr, "%s: cannot encode oauth token\n", - __FUNCTION__); - return -1; - } - - size_t base64encoded_etoken_length; - char *tmp=base64_encode((unsigned char *)(etoken.token), etoken.size, &base64encoded_etoken_length); - STRCPY(base64encoded_etoken,tmp); - free(tmp); - - return 0; + return 0; } -static int validate_decode_token(const char* server_name, - const oauth_key key, - const char* base64encoded_etoken, oauth_token* dot) { +static int validate_decode_token(const char *server_name, const oauth_key key, const char *base64encoded_etoken, + oauth_token *dot) { - - memset((dot), 0, sizeof(*dot)); + memset((dot), 0, sizeof(*dot)); - encoded_oauth_token etoken; - memset(&etoken, 0, sizeof(etoken)); + encoded_oauth_token etoken; + memset(&etoken, 0, sizeof(etoken)); - const size_t base64encoded_etoken_length=strlen(base64encoded_etoken); - unsigned char *tmp = base64_decode(base64encoded_etoken,base64encoded_etoken_length,&etoken.size); - memcpy(etoken.token,tmp,etoken.size); - free(tmp); - - if (decode_oauth_token((const uint8_t *) server_name, &etoken, &key, dot) < 0) { - fprintf(stderr, "%s: cannot decode oauth token\n", - __FUNCTION__); - return -1; - } else { - return 0; - }; + const size_t base64encoded_etoken_length = strlen(base64encoded_etoken); + unsigned char *tmp = base64_decode(base64encoded_etoken, base64encoded_etoken_length, &etoken.size); + memcpy(etoken.token, tmp, etoken.size); + free(tmp); + + if (decode_oauth_token((const uint8_t *)server_name, &etoken, &key, dot) < 0) { + fprintf(stderr, "%s: cannot decode oauth token\n", __FUNCTION__); + return -1; + } else { + return 0; + }; } -static void print_token_body(oauth_token* dot) { - printf("\n"); - printf("Token non-encrpyted body:\n"); - printf("{\n"); - size_t base64encoded_nonce_length; - char *base64encoded_nonce = base64_encode((unsigned char *)dot->enc_block.nonce, dot->enc_block.nonce_length,&base64encoded_nonce_length); - printf(" nonce: %s\n", base64encoded_nonce); - printf(" nonce length: %d\n", (int) dot->enc_block.nonce_length); - free(base64encoded_nonce); - printf("Token encrpyted body:\n"); - printf("{\n"); - printf(" mac key: %s\n", (char*) dot->enc_block.mac_key); - printf(" mac key length: %d\n", (int) dot->enc_block.key_length); - time_t time=dot->enc_block.timestamp>>16; - unsigned msec=(dot->enc_block.timestamp & 0xFFFF)*64; - printf(" timestamp:\n"); - printf(" unixtime: %u (localtime: %s )", (unsigned int)time, ctime(&time)); - printf(" msec:%u\n", msec); - printf(" lifetime: %lu\n", (unsigned long) dot->enc_block.lifetime); - printf("}\n"); +static void print_token_body(oauth_token *dot) { + printf("\n"); + printf("Token non-encrpyted body:\n"); + printf("{\n"); + size_t base64encoded_nonce_length; + char *base64encoded_nonce = + base64_encode((unsigned char *)dot->enc_block.nonce, dot->enc_block.nonce_length, &base64encoded_nonce_length); + printf(" nonce: %s\n", base64encoded_nonce); + printf(" nonce length: %d\n", (int)dot->enc_block.nonce_length); + free(base64encoded_nonce); + printf("Token encrpyted body:\n"); + printf("{\n"); + printf(" mac key: %s\n", (char *)dot->enc_block.mac_key); + printf(" mac key length: %d\n", (int)dot->enc_block.key_length); + time_t time = dot->enc_block.timestamp >> 16; + unsigned msec = (dot->enc_block.timestamp & 0xFFFF) * 64; + printf(" timestamp:\n"); + printf(" unixtime: %u (localtime: %s )", (unsigned int)time, ctime(&time)); + printf(" msec:%u\n", msec); + printf(" lifetime: %lu\n", (unsigned long)dot->enc_block.lifetime); + printf("}\n"); } //////////////// local definitions ///////////////// const char Usage[] = - "Usage: oauth [ -e / -d ] [options]\n" - "Options:\n" - "\n" - " -h, --help usage\n\n" - " -v, --verbose verbose mode\n\n" - " -e, --encrypt encrypt token\n" - " -d, --decrypt decrypt validate token\n\n" - " -i, --server-name server name (max. 255 char)\n" - " -j, --auth-key-id Auth key id (max. 32 char)\n" - " -k, --auth-key base64 encoded Auth key\n" - " -l --auth-key-timestamp Auth key timestamp (sec since epoch)\n" - " -m, --auth-key-lifetime Auth key lifetime in sec\n" - " -n, --auth-key-as-rs-alg Authorization Server(AS) - Resource Server (RS) encryption algorithm\n" - " -o, --token-nonce base64 encoded nonce base64(12 octet) = 16 char\n" - " -p, --token-mac-key base64 encoded MAC key base64(32 octet) = 44 char\n" - " -q, --token-timestamp timestamp in format 64 bit unsigned (Native format - Unix),\n" - " so 48 bit for secs since epoch UTC + 16 bit for 1/64000 fractions of a second.\n" - " e.g.: the actual unixtimestamp 16 bit left shifted. (Default: actual gmtime)\n" - " -r, --token-lifetime lifetime in sec (Default: 3600)\n" - " -t, --token base64 encoded encrypted token for validation and decryption\n" - " -u, --hmac-alg stun client hmac algorithm\n"; + "Usage: oauth [ -e / -d ] [options]\n" + "Options:\n" + "\n" + " -h, --help usage\n\n" + " -v, --verbose verbose mode\n\n" + " -e, --encrypt encrypt token\n" + " -d, --decrypt decrypt validate token\n\n" + " -i, --server-name server name (max. 255 char)\n" + " -j, --auth-key-id Auth key id (max. 32 char)\n" + " -k, --auth-key base64 encoded Auth key\n" + " -l --auth-key-timestamp Auth key timestamp (sec since epoch)\n" + " -m, --auth-key-lifetime Auth key lifetime in sec\n" + " -n, --auth-key-as-rs-alg Authorization Server(AS) - Resource Server (RS) encryption algorithm\n" + " -o, --token-nonce base64 encoded nonce base64(12 octet) = 16 char\n" + " -p, --token-mac-key base64 encoded MAC key base64(32 octet) = 44 char\n" + " -q, --token-timestamp timestamp in format 64 bit unsigned (Native format - Unix),\n" + " so 48 bit for secs since epoch UTC + 16 bit for 1/64000 fractions of a " + "second.\n" + " e.g.: the actual unixtimestamp 16 bit left shifted. (Default: actual " + "gmtime)\n" + " -r, --token-lifetime lifetime in sec (Default: 3600)\n" + " -t, --token base64 encoded encrypted token for validation and decryption\n" + " -u, --hmac-alg stun client hmac algorithm\n"; ////////////////////////////////////////////////// - -int main(int argc, char **argv) -{ +int main(int argc, char **argv) { oauth_key key; - //init vars with default values - char gcm_nonce[OAUTH_GCM_NONCE_SIZE+1]=""; + // init vars with default values + char gcm_nonce[OAUTH_GCM_NONCE_SIZE + 1] = ""; - char mac_key[OAUTH_MAC_KEY_SIZE+1]=""; + char mac_key[OAUTH_MAC_KEY_SIZE + 1] = ""; time_t current_time = time(NULL); - struct tm* gmt = gmtime(¤t_time); + struct tm *gmt = gmtime(¤t_time); uint64_t token_timestamp = (unsigned long long)mktime(gmt) << 16; uint32_t token_lifetime = OAUTH_TOKEN_LIFETIME; - - //oauth_key - char kid[OAUTH_LTK_ID_SIZE+1] = ""; - char base64encoded_ltk[OAUTH_LTK_BASE64ENCODED_SIZE+1]=""; + + // oauth_key + char kid[OAUTH_LTK_ID_SIZE + 1] = ""; + char base64encoded_ltk[OAUTH_LTK_BASE64ENCODED_SIZE + 1] = ""; turn_time_t key_timestamp = 0; turn_time_t key_lifetime = 0; - char as_rs_alg[OAUTH_AS_RS_ALG_SIZE+1]="A256GCM"; - char server_name[OAUTH_SERVER_NAME_SIZE+1] = ""; + char as_rs_alg[OAUTH_AS_RS_ALG_SIZE + 1] = "A256GCM"; + char server_name[OAUTH_SERVER_NAME_SIZE + 1] = ""; - char base64encoded_etoken[OAUTH_TOKEN_SIZE]=""; + char base64encoded_etoken[OAUTH_TOKEN_SIZE] = ""; - //TODO: replace SHA1 with an option. Actualy both big browser chrome and mozilla supports AFAIU implemented only SHA1. - char hmac_alg[OAUTH_HMAC_ALG_SIZE+1]="HMAC-SHA1"; + // TODO: replace SHA1 with an option. Actualy both big browser chrome and mozilla supports AFAIU implemented only + // SHA1. + char hmac_alg[OAUTH_HMAC_ALG_SIZE + 1] = "HMAC-SHA1"; - static int verbose_flag=0; - static int encrypt_flag=0; - static int decrypt_flag=0; + static int verbose_flag = 0; + static int encrypt_flag = 0; + static int decrypt_flag = 0; - static struct option long_options[] = - { - /* These options set a flag. */ - {"verbose", no_argument, &verbose_flag, 1}, - {"encrypt", no_argument, &encrypt_flag, 1}, - {"decrypt", no_argument, &decrypt_flag, 1}, - {"help", no_argument, 0, 'h'}, - {"server-name", required_argument, 0, 'i'}, - {"auth-key-id", required_argument, 0, 'j'}, - {"auth-key", required_argument, 0, 'k'}, - {"auth-key-timestamp", required_argument, 0, 'l'}, - {"auth-key-lifetime", required_argument, 0, 'm'}, - {"auth-key-as-rs-alg", required_argument, 0, 'n'}, - {"token-nonce", required_argument, 0, 'o'}, - {"token-mac-key", required_argument, 0, 'p'}, - {"token-timestamp", required_argument, 0, 'q'}, - {"token-lifetime", required_argument, 0, 'r'}, - {"token", required_argument, 0, 't'}, - {"hmac-alg", required_argument, 0, 'u'}, - {0, 0, 0, 0} - }; + static struct option long_options[] = {/* These options set a flag. */ + {"verbose", no_argument, &verbose_flag, 1}, + {"encrypt", no_argument, &encrypt_flag, 1}, + {"decrypt", no_argument, &decrypt_flag, 1}, + {"help", no_argument, 0, 'h'}, + {"server-name", required_argument, 0, 'i'}, + {"auth-key-id", required_argument, 0, 'j'}, + {"auth-key", required_argument, 0, 'k'}, + {"auth-key-timestamp", required_argument, 0, 'l'}, + {"auth-key-lifetime", required_argument, 0, 'm'}, + {"auth-key-as-rs-alg", required_argument, 0, 'n'}, + {"token-nonce", required_argument, 0, 'o'}, + {"token-mac-key", required_argument, 0, 'p'}, + {"token-timestamp", required_argument, 0, 'q'}, + {"token-lifetime", required_argument, 0, 'r'}, + {"token", required_argument, 0, 't'}, + {"hmac-alg", required_argument, 0, 'u'}, + {0, 0, 0, 0}}; /* getopt_long stores the option index here. */ int option_index = 0; - //tmp vars - size_t nonce_size=0; + // tmp vars + size_t nonce_size = 0; char *nonce_val; size_t mac_key_size; char *mac_key_val; - int i; - int c=0; + int c = 0; set_logfile("stdout"); set_no_stdout_log(1); set_system_parameters(0); - while ((c = getopt_long(argc, argv, "hvedi:j:k:l:m:n:o:p:q:r:t:u:",long_options, &option_index)) != -1) { - switch(c) { + while ((c = getopt_long(argc, argv, "hvedi:j:k:l:m:n:o:p:q:r:t:u:", long_options, &option_index)) != -1) { + switch (c) { case 'h': fprintf(stderr, "%s\n", Usage); - exit(1); + exit(1); break; case 'v': - verbose_flag=1; + verbose_flag = 1; break; case 'e': - encrypt_flag=1; + encrypt_flag = 1; break; case 'd': - decrypt_flag=1; + decrypt_flag = 1; break; case 'i': - //server-name - if ( strlen(optarg) <= OAUTH_SERVER_NAME_SIZE ) { - STRCPY(server_name,optarg); + // server-name + if (strlen(optarg) <= OAUTH_SERVER_NAME_SIZE) { + STRCPY(server_name, optarg); } else { - fprintf(stderr,"Server-name must not exceed %d!\n", OAUTH_LTK_ID_SIZE ); + fprintf(stderr, "Server-name must not exceed %d!\n", OAUTH_LTK_ID_SIZE); exit(1); } break; - case 'j': - //auth-key-id - if ( strlen(optarg) <= OAUTH_LTK_ID_SIZE ) { - STRCPY(kid,optarg); + case 'j': + // auth-key-id + if (strlen(optarg) <= OAUTH_LTK_ID_SIZE) { + STRCPY(kid, optarg); } else { - fprintf(stderr,"Key ID must not exceed %d!\n", OAUTH_LTK_ID_SIZE ); + fprintf(stderr, "Key ID must not exceed %d!\n", OAUTH_LTK_ID_SIZE); exit(1); } break; case 'k': - //auth-key - if ( strlen(optarg) <= OAUTH_LTK_BASE64ENCODED_SIZE ) { - STRCPY(base64encoded_ltk,optarg); + // auth-key + if (strlen(optarg) <= OAUTH_LTK_BASE64ENCODED_SIZE) { + STRCPY(base64encoded_ltk, optarg); } else { - fprintf(stderr,"Key must not exceed %d!\n", OAUTH_LTK_BASE64ENCODED_SIZE ); + fprintf(stderr, "Key must not exceed %d!\n", OAUTH_LTK_BASE64ENCODED_SIZE); exit(1); } break; case 'l': - //auth-key-timestamp + // auth-key-timestamp key_timestamp = atoi(optarg); break; case 'm': - //auth-key-lifetime - key_lifetime=atoi(optarg); + // auth-key-lifetime + key_lifetime = atoi(optarg); break; case 'n': - //auth-key-as-rs-alg - if ( strlen(optarg) <= OAUTH_AS_RS_ALG_SIZE ) { - STRCPY(as_rs_alg,optarg); + // auth-key-as-rs-alg + if (strlen(optarg) <= OAUTH_AS_RS_ALG_SIZE) { + STRCPY(as_rs_alg, optarg); } else { - fprintf(stderr,"AS-RS Alg must not exceed %d!\n", OAUTH_AS_RS_ALG_SIZE ); + fprintf(stderr, "AS-RS Alg must not exceed %d!\n", OAUTH_AS_RS_ALG_SIZE); exit(1); } break; case 'o': - //token-nonce - nonce_val = (char*)base64_decode(optarg,strlen(optarg),&nonce_size); - if (nonce_size > OAUTH_GCM_NONCE_SIZE){ - nonce_size=OAUTH_GCM_NONCE_SIZE; - } - strncpy(gcm_nonce,nonce_val,nonce_size); - gcm_nonce[ nonce_size ]='\0'; + // token-nonce + nonce_val = (char *)base64_decode(optarg, strlen(optarg), &nonce_size); + if (nonce_size > OAUTH_GCM_NONCE_SIZE) { + nonce_size = OAUTH_GCM_NONCE_SIZE; + } + strncpy(gcm_nonce, nonce_val, nonce_size); + gcm_nonce[nonce_size] = '\0'; break; case 'p': - //token-mac-key - mac_key_val = (char*)base64_decode(optarg,strlen(optarg),&mac_key_size); - if (mac_key_size > OAUTH_MAC_KEY_SIZE){ - mac_key_size=OAUTH_MAC_KEY_SIZE; - } - strncpy(mac_key,mac_key_val,mac_key_size); - mac_key[mac_key_size]='\0'; + // token-mac-key + mac_key_val = (char *)base64_decode(optarg, strlen(optarg), &mac_key_size); + if (mac_key_size > OAUTH_MAC_KEY_SIZE) { + mac_key_size = OAUTH_MAC_KEY_SIZE; + } + strncpy(mac_key, mac_key_val, mac_key_size); + mac_key[mac_key_size] = '\0'; break; case 'q': - //token-timestamp - token_timestamp=strtoull(optarg,0,10); + // token-timestamp + token_timestamp = strtoull(optarg, 0, 10); break; case 'r': - //token-lifetime - token_lifetime=atoi(optarg); + // token-lifetime + token_lifetime = atoi(optarg); break; case 't': - if ( strlen(optarg) <= OAUTH_TOKEN_SIZE ) { - STRCPY(base64encoded_etoken,optarg); + if (strlen(optarg) <= OAUTH_TOKEN_SIZE) { + STRCPY(base64encoded_etoken, optarg); } else { - fprintf(stderr,"base64 encoded encrypted token must not exceed %d!\n", OAUTH_TOKEN_SIZE ); + fprintf(stderr, "base64 encoded encrypted token must not exceed %d!\n", OAUTH_TOKEN_SIZE); exit(1); } break; case 'u': - //hmac-alg - if ( strlen(optarg) <= OAUTH_HMAC_ALG_SIZE ) { - STRCPY(hmac_alg,optarg); + // hmac-alg + if (strlen(optarg) <= OAUTH_HMAC_ALG_SIZE) { + STRCPY(hmac_alg, optarg); } else { - fprintf(stderr,"STUN client HMAC Alg must not exceed %d!\n", OAUTH_HMAC_ALG_SIZE ); + fprintf(stderr, "STUN client HMAC Alg must not exceed %d!\n", OAUTH_HMAC_ALG_SIZE); exit(1); } break; default: - fprintf(stderr,"%s\n", Usage); + fprintf(stderr, "%s\n", Usage); exit(1); break; } } for (i = optind; i < argc; i++) - printf ("Non-option argument %s\n", argv[i]); + printf("Non-option argument %s\n", argv[i]); - if(optind>argc) { + if (optind > argc) { fprintf(stderr, "%s\n", Usage); exit(-1); } - if (!(encrypt_flag || decrypt_flag)){ - fprintf(stderr, "Use either encrypt or decrypt.\nPlease use -h or --help for the detailed help\n"); - exit(-1); + if (!(encrypt_flag || decrypt_flag)) { + fprintf(stderr, "Use either encrypt or decrypt.\nPlease use -h or --help for the detailed help\n"); + exit(-1); } - - //check if we have required params - //TODO: more compact warnning handling - if (encrypt_flag || decrypt_flag){ - if (strlen(server_name) == 0) { - fprintf(stderr, "For encode/decode --server-name/-i is mandatory \n"); - exit(-1); - } - - if (strlen(kid) == 0){ - fprintf(stderr, "For encode/decode --auth-key-id/-j is mandatory \n"); - exit(-1); - } - if (strlen(base64encoded_ltk) == 0){ - fprintf(stderr, "For encode/decode --auth-key/-k is mandatory \n"); - exit(-1); - } - if (key_timestamp == 0){ - fprintf(stderr, "For encode/decode --auth-key-timestamp/-l is mandatory \n"); - exit(-1); - } - if (key_lifetime == 0){ - fprintf(stderr, "For encode/decode --auth-key-lifetime/-m is mandatory \n"); - exit(-1); + + // check if we have required params + // TODO: more compact warnning handling + if (encrypt_flag || decrypt_flag) { + if (strlen(server_name) == 0) { + fprintf(stderr, "For encode/decode --server-name/-i is mandatory \n"); + exit(-1); } - if (encrypt_flag && strlen(mac_key) == 0) { - fprintf(stderr, "For encode --token-mac-key/-p is mandatory \n"); - exit(-1); + if (strlen(kid) == 0) { + fprintf(stderr, "For encode/decode --auth-key-id/-j is mandatory \n"); + exit(-1); } - - if (!encrypt_flag && decrypt_flag && strlen(base64encoded_etoken) == 0) { - fprintf(stderr, "For decode --token/-t is mandatory \n"); - exit(-1); + if (strlen(base64encoded_ltk) == 0) { + fprintf(stderr, "For encode/decode --auth-key/-k is mandatory \n"); + exit(-1); } - + if (key_timestamp == 0) { + fprintf(stderr, "For encode/decode --auth-key-timestamp/-l is mandatory \n"); + exit(-1); + } + if (key_lifetime == 0) { + fprintf(stderr, "For encode/decode --auth-key-lifetime/-m is mandatory \n"); + exit(-1); + } + + if (encrypt_flag && strlen(mac_key) == 0) { + fprintf(stderr, "For encode --token-mac-key/-p is mandatory \n"); + exit(-1); + } + + if (!encrypt_flag && decrypt_flag && strlen(base64encoded_etoken) == 0) { + fprintf(stderr, "For decode --token/-t is mandatory \n"); + exit(-1); + } + // Expiry warnings - if ( (unsigned long long)key_timestamp<<16 > token_timestamp +((unsigned long long)token_lifetime << 16) ) { - fprintf(stderr,"\nWARNING: Token expiry is earlear then Auth key life time start timestamp!!\n\n"); + if ((unsigned long long)key_timestamp << 16 > token_timestamp + ((unsigned long long)token_lifetime << 16)) { + fprintf(stderr, "\nWARNING: Token expiry is earlear then Auth key life time start timestamp!!\n\n"); } else { - if( (unsigned long long)key_timestamp<<16 > token_timestamp) { - fprintf(stderr,"\nWARNING: Token life time start timestamp is earlier then Auth key start timestamp!!\n\n"); - } + if ((unsigned long long)key_timestamp << 16 > token_timestamp) { + fprintf(stderr, "\nWARNING: Token life time start timestamp is earlier then Auth key start timestamp!!\n\n"); + } } - if( (unsigned long long)( key_timestamp + key_lifetime )<<16 < token_timestamp ) { - fprintf(stderr,"\nWARNING: Auth key will expire before token lifetime start timestamp!!\n\n"); + if ((unsigned long long)(key_timestamp + key_lifetime) << 16 < token_timestamp) { + fprintf(stderr, "\nWARNING: Auth key will expire before token lifetime start timestamp!!\n\n"); } else { - if( (unsigned long long)( key_timestamp + key_lifetime)<<16 < token_timestamp + ((unsigned long long)token_lifetime << 16) ) { - fprintf(stderr,"\nWARNING: Auth key will expire before token expiry!!\n\n"); - } + if ((unsigned long long)(key_timestamp + key_lifetime) << 16 < + token_timestamp + ((unsigned long long)token_lifetime << 16)) { + fprintf(stderr, "\nWARNING: Auth key will expire before token expiry!!\n\n"); + } } - if ( setup_ikm_key(kid, base64encoded_ltk, key_timestamp, key_lifetime, as_rs_alg, &key) == 0 ) { - if(encrypt_flag) { - if (encode_token(server_name, gcm_nonce, mac_key, token_timestamp, token_lifetime, key, base64encoded_etoken) == 0 ) { - printf("{\n"); - printf(" \"access_token\":\"%s\",\n",base64encoded_etoken); - printf(" \"token_type\":\"pop\",\n"); - printf(" \"expires_in\":%u,\n",token_lifetime); - printf(" \"kid\":\"%s\",\n",kid); - printf(" \"key\":\"%s\",\n",mac_key); - printf(" \"alg\":\"%s\"\n",hmac_alg); - printf("}\n"); - } else { - fprintf(stderr, "Error during token encode\n"); - exit(-1); - } + if (setup_ikm_key(kid, base64encoded_ltk, key_timestamp, key_lifetime, as_rs_alg, &key) == 0) { + if (encrypt_flag) { + if (encode_token(server_name, gcm_nonce, mac_key, token_timestamp, token_lifetime, key, base64encoded_etoken) == + 0) { + printf("{\n"); + printf(" \"access_token\":\"%s\",\n", base64encoded_etoken); + printf(" \"token_type\":\"pop\",\n"); + printf(" \"expires_in\":%u,\n", token_lifetime); + printf(" \"kid\":\"%s\",\n", kid); + printf(" \"key\":\"%s\",\n", mac_key); + printf(" \"alg\":\"%s\"\n", hmac_alg); + printf("}\n"); + } else { + fprintf(stderr, "Error during token encode\n"); + exit(-1); } - if (decrypt_flag) { - oauth_token dot; - if ( validate_decode_token(server_name, key, base64encoded_etoken,&dot) == 0) { - printf("-=Valid token!=-\n"); - if (verbose_flag) print_token_body(&dot); - } else { - fprintf(stderr, "Error during token validation and decoding\n"); - exit(-1); - } + } + if (decrypt_flag) { + oauth_token dot; + if (validate_decode_token(server_name, key, base64encoded_etoken, &dot) == 0) { + printf("-=Valid token!=-\n"); + if (verbose_flag) + print_token_body(&dot); + } else { + fprintf(stderr, "Error during token validation and decoding\n"); + exit(-1); } - } else { - fprintf(stderr, "Error during key setup\n"); - exit(-1); + } + } else { + fprintf(stderr, "Error during key setup\n"); + exit(-1); } - } return 0; diff --git a/src/apps/peer/mainudpserver.c b/src/apps/peer/mainudpserver.c index 4063452..c8ef9f3 100644 --- a/src/apps/peer/mainudpserver.c +++ b/src/apps/peer/mainudpserver.c @@ -28,12 +28,12 @@ * SUCH DAMAGE. */ +#include "apputils.h" #include "ns_turn_utils.h" #include "udpserver.h" -#include "apputils.h" -#include #include +#include #include #include #if defined(_MSC_VER) @@ -44,66 +44,62 @@ //////////////// local definitions ///////////////// -static char Usage[] = - "Usage: server [options]\n" - "Options:\n" - " -p Listening UDP port (Default: 3480)\n" - " -d Listening interface device (optional)\n" - " -L Listening address\n" - " -v verbose\n"; - +static char Usage[] = "Usage: server [options]\n" + "Options:\n" + " -p Listening UDP port (Default: 3480)\n" + " -d Listening interface device (optional)\n" + " -L Listening address\n" + " -v verbose\n"; ////////////////////////////////////////////////// -int main(int argc, char **argv) -{ - int port = PEER_DEFAULT_PORT; - char **local_addr_list=NULL; - size_t las = 0; - int verbose = TURN_VERBOSE_NONE; - int c; - char ifname[1025] = "\0"; +int main(int argc, char **argv) { + int port = PEER_DEFAULT_PORT; + char **local_addr_list = NULL; + size_t las = 0; + int verbose = TURN_VERBOSE_NONE; + int c; + char ifname[1025] = "\0"; - if (socket_init()) return -1; + if (socket_init()) + return -1; - IS_TURN_SERVER = 1; + IS_TURN_SERVER = 1; - set_logfile("stdout"); - set_no_stdout_log(1); - set_system_parameters(0); + set_logfile("stdout"); + set_no_stdout_log(1); + set_system_parameters(0); - while ((c = getopt(argc, argv, "d:p:L:v")) != -1) - switch (c){ - case 'd': - STRCPY(ifname, optarg); - break; - case 'p': - port = atoi(optarg); - break; - case 'L': - local_addr_list = (char**)realloc(local_addr_list,++las*sizeof(char*)); - local_addr_list[las-1]=strdup(optarg); - break; - case 'v': - verbose = TURN_VERBOSE_NORMAL; - break; - default: - fprintf(stderr, "%s\n", Usage); - exit(1); - } + while ((c = getopt(argc, argv, "d:p:L:v")) != -1) + switch (c) { + case 'd': + STRCPY(ifname, optarg); + break; + case 'p': + port = atoi(optarg); + break; + case 'L': + local_addr_list = (char **)realloc(local_addr_list, ++las * sizeof(char *)); + local_addr_list[las - 1] = strdup(optarg); + break; + case 'v': + verbose = TURN_VERBOSE_NORMAL; + break; + default: + fprintf(stderr, "%s\n", Usage); + exit(1); + } - if(las<1) { - local_addr_list = (char**)realloc(local_addr_list,++las*sizeof(char*)); - local_addr_list[las-1]=strdup("0.0.0.0"); - local_addr_list = (char**)realloc(local_addr_list,++las*sizeof(char*)); - local_addr_list[las-1]=strdup("::"); - } + if (las < 1) { + local_addr_list = (char **)realloc(local_addr_list, ++las * sizeof(char *)); + local_addr_list[las - 1] = strdup("0.0.0.0"); + local_addr_list = (char **)realloc(local_addr_list, ++las * sizeof(char *)); + local_addr_list[las - 1] = strdup("::"); + } + server_type *server = start_udp_server(verbose, ifname, local_addr_list, las, port); + run_udp_server(server); + clean_udp_server(server); - server_type* server = start_udp_server(verbose, ifname, local_addr_list, las, port); - run_udp_server(server); - clean_udp_server(server); - - return 0; + return 0; } - diff --git a/src/apps/peer/udpserver.c b/src/apps/peer/udpserver.c index cdbbd3e..f25d425 100644 --- a/src/apps/peer/udpserver.c +++ b/src/apps/peer/udpserver.c @@ -28,17 +28,18 @@ * SUCH DAMAGE. */ -#include "apputils.h" #include "udpserver.h" +#include "apputils.h" #include "stun_buffer.h" /////////////// io handlers /////////////////// -static void udp_server_input_handler(evutil_socket_t fd, short what, void* arg) { +static void udp_server_input_handler(evutil_socket_t fd, short what, void *arg) { - if(!(what&EV_READ)) return; + if (!(what & EV_READ)) + return; - ioa_addr *addr = (ioa_addr*)arg; + ioa_addr *addr = (ioa_addr *)arg; int len = 0; int slen = get_ioa_addr_len(addr); @@ -46,34 +47,36 @@ static void udp_server_input_handler(evutil_socket_t fd, short what, void* arg) ioa_addr remote_addr; do { - len = recvfrom(fd, buffer.buf, sizeof(buffer.buf)-1, 0, (struct sockaddr*) &remote_addr, (socklen_t*) &slen); - } while(len<0 && (errno==EINTR)); - - buffer.len=len; + len = recvfrom(fd, buffer.buf, sizeof(buffer.buf) - 1, 0, (struct sockaddr *)&remote_addr, (socklen_t *)&slen); + } while (len < 0 && (errno == EINTR)); - if(len>=0) { + buffer.len = len; + + if (len >= 0) { do { - len = sendto(fd, buffer.buf, buffer.len, 0, (const struct sockaddr*) &remote_addr, (socklen_t) slen); + len = sendto(fd, buffer.buf, buffer.len, 0, (const struct sockaddr *)&remote_addr, (socklen_t)slen); } while (len < 0 && ((errno == EINTR) || (errno == ENOBUFS) || (errno == EAGAIN))); } } ///////////////////// operations ////////////////////////// -static int udp_create_server_socket(server_type* server, - const char* ifname, const char *local_address, int port) { +static int udp_create_server_socket(server_type *server, const char *ifname, const char *local_address, int port) { - if(server && server->verbose) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Start\n"); + if (server && server->verbose) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Start\n"); - if(!server) return -1; + if (!server) + return -1; evutil_socket_t udp_fd = -1; - ioa_addr *server_addr = (ioa_addr*)malloc(sizeof(ioa_addr)); + ioa_addr *server_addr = (ioa_addr *)malloc(sizeof(ioa_addr)); - STRCPY(server->ifname,ifname); + STRCPY(server->ifname, ifname); + + if (make_ioa_addr((const uint8_t *)local_address, port, server_addr) < 0) + return -1; - if(make_ioa_addr((const uint8_t*)local_address, port, server_addr)<0) return -1; - udp_fd = socket(server_addr->ss.sa_family, RELAY_DGRAM_SOCKET_TYPE, RELAY_DGRAM_SOCKET_PROTOCOL); if (udp_fd < 0) { perror("socket"); @@ -81,49 +84,53 @@ static int udp_create_server_socket(server_type* server, return -1; } - if(sock_bind_to_device(udp_fd, (unsigned char*)server->ifname)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind udp server socket to device %s\n",server->ifname); + if (sock_bind_to_device(udp_fd, (unsigned char *)server->ifname) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Cannot bind udp server socket to device %s\n", server->ifname); } - set_sock_buf_size(udp_fd,UR_SERVER_SOCK_BUF_SIZE); - - if(addr_bind(udp_fd,server_addr,1,1,UDP_SOCKET)<0) return -1; - + set_sock_buf_size(udp_fd, UR_SERVER_SOCK_BUF_SIZE); + + if (addr_bind(udp_fd, server_addr, 1, 1, UDP_SOCKET) < 0) + return -1; + socket_set_nonblocking(udp_fd); - struct event *udp_ev = event_new(server->event_base,udp_fd,EV_READ|EV_PERSIST, - udp_server_input_handler,server_addr); - - event_add(udp_ev,NULL); - - if(server && server->verbose) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "End\n"); - + struct event *udp_ev = + event_new(server->event_base, udp_fd, EV_READ | EV_PERSIST, udp_server_input_handler, server_addr); + + event_add(udp_ev, NULL); + + if (server && server->verbose) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "End\n"); + return 0; } -static server_type* init_server(int verbose, const char* ifname, char **local_addresses, size_t las, int port) { +static server_type *init_server(int verbose, const char *ifname, char **local_addresses, size_t las, int port) { - server_type* server=(server_type*)malloc(sizeof(server_type)); + server_type *server = (server_type *)malloc(sizeof(server_type)); - if(!server) return server; + if (!server) + return server; memset(server, 0, sizeof(server_type)); - server->verbose=verbose; + server->verbose = verbose; server->event_base = turn_event_base_new(); - while(las) { + while (las) { udp_create_server_socket(server, ifname, local_addresses[--las], port); - udp_create_server_socket(server, ifname, local_addresses[las], port+1); + udp_create_server_socket(server, ifname, local_addresses[las], port + 1); } return server; } -static int clean_server(server_type* server) { - if(server) { - if(server->event_base) event_base_free(server->event_base); +static int clean_server(server_type *server) { + if (server) { + if (server->event_base) + event_base_free(server->event_base); free(server); } return 0; @@ -131,14 +138,15 @@ static int clean_server(server_type* server) { /////////////////////////////////////////////////////////// -static void run_events(server_type* server) { +static void run_events(server_type *server) { - if(!server) return; + if (!server) + return; struct timeval timeout; - timeout.tv_sec=0; - timeout.tv_usec=100000; + timeout.tv_sec = 0; + timeout.tv_usec = 100000; event_base_loopexit(server->event_base, &timeout); event_base_dispatch(server->event_base); @@ -146,28 +154,28 @@ static void run_events(server_type* server) { ///////////////////////////////////////////////////////////// - -server_type* start_udp_server(int verbose, const char* ifname, char **local_addresses, size_t las, int port) { +server_type *start_udp_server(int verbose, const char *ifname, char **local_addresses, size_t las, int port) { return init_server(verbose, ifname, local_addresses, las, port); } -void run_udp_server(server_type* server) { - - if(server) { - - unsigned int cycle=0; - +void run_udp_server(server_type *server) { + + if (server) { + + unsigned int cycle = 0; + while (1) { - + cycle++; - + run_events(server); } - } + } } -void clean_udp_server(server_type* server) { - if(server) clean_server(server); +void clean_udp_server(server_type *server) { + if (server) + clean_server(server); } ////////////////////////////////////////////////////////////////// diff --git a/src/apps/peer/udpserver.h b/src/apps/peer/udpserver.h index 6dd1b03..3ff1d86 100644 --- a/src/apps/peer/udpserver.h +++ b/src/apps/peer/udpserver.h @@ -50,17 +50,17 @@ typedef struct server_info server_type; struct server_info { char ifname[1025]; - struct event_base* event_base; + struct event_base *event_base; int verbose; }; ////////////////////////////// -server_type* start_udp_server(int verbose, const char* ifname, char **local_addresses, size_t las, int port); +server_type *start_udp_server(int verbose, const char *ifname, char **local_addresses, size_t las, int port); -void run_udp_server(server_type* server); +void run_udp_server(server_type *server); -void clean_udp_server(server_type* server); +void clean_udp_server(server_type *server); /////////////////////////////////////////// diff --git a/src/apps/relay/acme.c b/src/apps/relay/acme.c index 40404a3..160eb88 100644 --- a/src/apps/relay/acme.c +++ b/src/apps/relay/acme.c @@ -12,81 +12,78 @@ #define GET_ACME_PREFIX_LEN 32 static int is_acme_req(char *req, size_t len) { - static const char *A = " - 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz "; - int c, i, k; + static const char *A = " - 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ " + " _ abcdefghijklmnopqrstuvwxyz "; + int c, i, k; - // Check first request line. Should be like: GET path HTTP/1.x - if (strncmp(req, GET_ACME_PREFIX, GET_ACME_PREFIX_LEN)) - return -1; - // Usually (for LE) the "method path" is 32 + 43 = 55 chars. But other - // implementations may choose longer pathes. We define PATHMAX = 127 chars - // to be prepared for "DoS" attacks (STUN msg size max. is ~ 64K). - len -= 21; // min size of trailing headers - if (len > 131) - len = 131; - for (i=GET_ACME_PREFIX_LEN; i < (int) len; i++) { - // find the end of the path - if (req[i] != ' ') - continue; - // consider path < 10 chars invalid. Also we wanna see a "trailer". - if (i < (GET_ACME_PREFIX_LEN + 10) || strncmp(req + i, " HTTP/1.", 8)) - return -2; - // finally check for allowed chars - for (k=GET_ACME_PREFIX_LEN; k < i; k++) { - c = req[k]; - if ((c > 127) || (A[c] == ' ')) - return -3; - } - // all checks passed: sufficient for us to answer with a redirect - return i; - } - return -4; // end of path not found + // Check first request line. Should be like: GET path HTTP/1.x + if (strncmp(req, GET_ACME_PREFIX, GET_ACME_PREFIX_LEN)) + return -1; + // Usually (for LE) the "method path" is 32 + 43 = 55 chars. But other + // implementations may choose longer pathes. We define PATHMAX = 127 chars + // to be prepared for "DoS" attacks (STUN msg size max. is ~ 64K). + len -= 21; // min size of trailing headers + if (len > 131) + len = 131; + for (i = GET_ACME_PREFIX_LEN; i < (int)len; i++) { + // find the end of the path + if (req[i] != ' ') + continue; + // consider path < 10 chars invalid. Also we wanna see a "trailer". + if (i < (GET_ACME_PREFIX_LEN + 10) || strncmp(req + i, " HTTP/1.", 8)) + return -2; + // finally check for allowed chars + for (k = GET_ACME_PREFIX_LEN; k < i; k++) { + c = req[k]; + if ((c > 127) || (A[c] == ' ')) + return -3; + } + // all checks passed: sufficient for us to answer with a redirect + return i; + } + return -4; // end of path not found } -int try_acme_redirect(char *req, size_t len, const char *url, - ioa_socket_handle s) -{ - static const char *HTML = - "301 Moved Permanently\ +int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s) { + static const char *HTML = "301 Moved Permanently\

301 Moved Permanently

"; - char http_response[1024]; - size_t plen, rlen; + char http_response[1024]; + size_t plen, rlen; - if (url == NULL || url[0] == '\0' || req == NULL || s == 0 ) - return 1; - if (len < (GET_ACME_PREFIX_LEN + 32) || len > (512 - GET_ACME_PREFIX_LEN) - || (plen = is_acme_req(req, len)) < (GET_ACME_PREFIX_LEN + 1)) - return 2; + if (url == NULL || url[0] == '\0' || req == NULL || s == 0) + return 1; + if (len < (GET_ACME_PREFIX_LEN + 32) || len > (512 - GET_ACME_PREFIX_LEN) || + (plen = is_acme_req(req, len)) < (GET_ACME_PREFIX_LEN + 1)) + return 2; - req[plen] = '\0'; + req[plen] = '\0'; - snprintf(http_response, sizeof(http_response) - 1, - "HTTP/1.1 301 Moved Permanently\r\n" - "Content-Type: text/html\r\n" - "Content-Length: %zu\r\n" - "Connection: close\r\n" - "Location: %s%s\r\n" - "\r\n%s", strlen(HTML), url, req + GET_ACME_PREFIX_LEN, HTML); + snprintf(http_response, sizeof(http_response) - 1, + "HTTP/1.1 301 Moved Permanently\r\n" + "Content-Type: text/html\r\n" + "Content-Length: %zu\r\n" + "Connection: close\r\n" + "Location: %s%s\r\n" + "\r\n%s", + strlen(HTML), url, req + GET_ACME_PREFIX_LEN, HTML); - rlen = strlen(http_response); + rlen = strlen(http_response); #ifdef LIBEV_OK - ioa_network_buffer_handle nbh_acme = ioa_network_buffer_allocate(s->e); - uint8_t *data = ioa_network_buffer_data(nbh_acme); - memcpy(data, http_response, rlen); - ioa_network_buffer_set_size(nbh_acme, rlen); - send_data_from_ioa_socket_nbh(s, NULL, nbh_acme, TTL_IGNORE, TOS_IGNORE, NULL); + ioa_network_buffer_handle nbh_acme = ioa_network_buffer_allocate(s->e); + uint8_t *data = ioa_network_buffer_data(nbh_acme); + memcpy(data, http_response, rlen); + ioa_network_buffer_set_size(nbh_acme, rlen); + send_data_from_ioa_socket_nbh(s, NULL, nbh_acme, TTL_IGNORE, TOS_IGNORE, NULL); #else - if (write(s->fd, http_response, rlen) == -1) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, - "Sending redirect to '%s%s' failed",url, req + GET_ACME_PREFIX_LEN); - } else if (((turn_turnserver *)s->session->server)->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirected to %s%s\n", - url, req + GET_ACME_PREFIX_LEN); - } + if (write(s->fd, http_response, rlen) == -1) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Sending redirect to '%s%s' failed", url, req + GET_ACME_PREFIX_LEN); + } else if (((turn_turnserver *)s->session->server)->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirected to %s%s\n", url, req + GET_ACME_PREFIX_LEN); + } #endif - req[plen] = ' '; + req[plen] = ' '; - return 0; + return 0; } diff --git a/src/apps/relay/acme.h b/src/apps/relay/acme.h index 133c22d..0fab3dd 100644 --- a/src/apps/relay/acme.h +++ b/src/apps/relay/acme.h @@ -31,12 +31,12 @@ #ifndef __TURN_ACME__ #define __TURN_ACME__ -#include "ns_turn_utils.h" -#include "ns_turn_server.h" #include "apputils.h" +#include "ns_turn_server.h" +#include "ns_turn_utils.h" -#include #include +#include #ifdef __cplusplus extern "C" { @@ -54,4 +54,3 @@ int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle #endif /// __TURN_ACME__ /// - diff --git a/src/apps/relay/dbdrivers/dbd_mongo.c b/src/apps/relay/dbdrivers/dbd_mongo.c index 314ec9c..d12884b 100644 --- a/src/apps/relay/dbdrivers/dbd_mongo.c +++ b/src/apps/relay/dbdrivers/dbd_mongo.c @@ -29,116 +29,110 @@ * SUCH DAMAGE. */ -#include "../mainrelay.h" #include "dbd_mongo.h" +#include "../mainrelay.h" #if !defined(TURN_NO_MONGO) -#include #include +#include /////////////////////////////////////////////////////////////////////////////////////////////////////////// -const char * MONGO_DEFAULT_DB = "turn"; +const char *MONGO_DEFAULT_DB = "turn"; struct _MONGO { - mongoc_uri_t * uri; - mongoc_client_t * client; - const char * database; + mongoc_uri_t *uri; + mongoc_client_t *client; + const char *database; }; typedef struct _MONGO MONGO; -static void mongo_logger(mongoc_log_level_t log_level, const char * log_domain, const char * message, void * user_data) { - UNUSED_ARG(log_domain); - UNUSED_ARG(user_data); +static void mongo_logger(mongoc_log_level_t log_level, const char *log_domain, const char *message, void *user_data) { + UNUSED_ARG(log_domain); + UNUSED_ARG(user_data); TURN_LOG_LEVEL l = TURN_LOG_LEVEL_INFO; - + UNUSED_ARG(l); - switch(log_level) { - case MONGOC_LOG_LEVEL_ERROR: - l = TURN_LOG_LEVEL_ERROR; - break; - case MONGOC_LOG_LEVEL_WARNING: - l = TURN_LOG_LEVEL_WARNING; - break; - default: - l = TURN_LOG_LEVEL_INFO; - break; + switch (log_level) { + case MONGOC_LOG_LEVEL_ERROR: + l = TURN_LOG_LEVEL_ERROR; + break; + case MONGOC_LOG_LEVEL_WARNING: + l = TURN_LOG_LEVEL_WARNING; + break; + default: + l = TURN_LOG_LEVEL_INFO; + break; } - TURN_LOG_FUNC(l, "%s\n", message); + TURN_LOG_FUNC(l, "%s\n", message); } -static void MongoFree(MONGO * info) { - if(info) { - if(info->uri) mongoc_uri_destroy(info->uri); - if(info->client) mongoc_client_destroy(info->client); - free(info); - } +static void MongoFree(MONGO *info) { + if (info) { + if (info->uri) + mongoc_uri_destroy(info->uri); + if (info->client) + mongoc_client_destroy(info->client); + free(info); + } } -static MONGO * get_mongodb_connection(void) { +static MONGO *get_mongodb_connection(void) { - persistent_users_db_t * pud = get_persistent_users_db(); + persistent_users_db_t *pud = get_persistent_users_db(); - MONGO * mydbconnection = (MONGO *) pthread_getspecific(connection_key); + MONGO *mydbconnection = (MONGO *)pthread_getspecific(connection_key); - if (!mydbconnection) { - mongoc_init(); - mongoc_log_set_handler(&mongo_logger, NULL); + if (!mydbconnection) { + mongoc_init(); + mongoc_log_set_handler(&mongo_logger, NULL); - mydbconnection = (MONGO *) malloc(sizeof(MONGO)); - memset(mydbconnection, 0, sizeof(MONGO)); + mydbconnection = (MONGO *)malloc(sizeof(MONGO)); + memset(mydbconnection, 0, sizeof(MONGO)); - mydbconnection->uri = mongoc_uri_new(pud->userdb); + mydbconnection->uri = mongoc_uri_new(pud->userdb); - if (!mydbconnection->uri) { - TURN_LOG_FUNC( - TURN_LOG_LEVEL_ERROR, - "Cannot open parse MongoDB URI <%s>, connection string format error\n", - pud->userdb); - MongoFree(mydbconnection); - mydbconnection = NULL; - } else { - mydbconnection->client = mongoc_client_new_from_uri( - mydbconnection->uri); - if (!mydbconnection->client) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Cannot initialize MongoDB connection\n"); - MongoFree(mydbconnection); - mydbconnection = NULL; - } else { - mydbconnection->database = mongoc_uri_get_database( - mydbconnection->uri); - if (!mydbconnection->database) - mydbconnection->database = MONGO_DEFAULT_DB; - if(mydbconnection) { - (void) pthread_setspecific(connection_key, mydbconnection); - } - TURN_LOG_FUNC( - TURN_LOG_LEVEL_INFO, - "Opened MongoDB URI <%s>\n", - pud->userdb); - } - } - } - return mydbconnection; + if (!mydbconnection->uri) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open parse MongoDB URI <%s>, connection string format error\n", + pud->userdb); + MongoFree(mydbconnection); + mydbconnection = NULL; + } else { + mydbconnection->client = mongoc_client_new_from_uri(mydbconnection->uri); + if (!mydbconnection->client) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot initialize MongoDB connection\n"); + MongoFree(mydbconnection); + mydbconnection = NULL; + } else { + mydbconnection->database = mongoc_uri_get_database(mydbconnection->uri); + if (!mydbconnection->database) + mydbconnection->database = MONGO_DEFAULT_DB; + if (mydbconnection) { + (void)pthread_setspecific(connection_key, mydbconnection); + } + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Opened MongoDB URI <%s>\n", pud->userdb); + } + } + } + return mydbconnection; } -static mongoc_collection_t * mongo_get_collection(const char * name) { - MONGO * mc = get_mongodb_connection(); +static mongoc_collection_t *mongo_get_collection(const char *name) { + MONGO *mc = get_mongodb_connection(); - if(!mc) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error getting a connection to MongoDB\n"); - return NULL; - } - - mongoc_collection_t * collection; + if (!mc) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error getting a connection to MongoDB\n"); + return NULL; + } + + mongoc_collection_t *collection; collection = mongoc_client_get_collection(mc->client, mc->database, name); if (!collection) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MongoDB collection '%s'\n", name); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MongoDB collection '%s'\n", name); } return collection; @@ -147,11 +141,11 @@ static mongoc_collection_t * mongo_get_collection(const char * name) { /////////////////////////////////////////////////////////////////////////////////////////////////////////// static int mongo_get_auth_secrets(secrets_list_t *sl, uint8_t *realm) { - mongoc_collection_t * collection = mongo_get_collection("turn_secret"); + mongoc_collection_t *collection = mongo_get_collection("turn_secret"); - if(!collection) + if (!collection) return -1; - + bson_t query; bson_init(&query); BSON_APPEND_UTF8(&query, "realm", (const char *)realm); @@ -159,23 +153,23 @@ static int mongo_get_auth_secrets(secrets_list_t *sl, uint8_t *realm) { bson_t fields; bson_init(&fields); BSON_APPEND_INT32(&fields, "value", 1); - - mongoc_cursor_t * cursor; + + mongoc_cursor_t *cursor; cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, &fields, NULL); int ret = -1; - + if (!cursor) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'turn_secret'\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'turn_secret'\n"); } else { - const bson_t * item; + const bson_t *item; uint32_t length; bson_iter_t iter; - const char * value; - while(mongoc_cursor_next(cursor, &item)) { - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "value") && BSON_ITER_HOLDS_UTF8(&iter)) { + const char *value; + while (mongoc_cursor_next(cursor, &item)) { + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "value") && BSON_ITER_HOLDS_UTF8(&iter)) { value = bson_iter_utf8(&iter, &length); - add_to_secrets_list(sl, value); + add_to_secrets_list(sl, value); } } mongoc_cursor_destroy(cursor); @@ -187,13 +181,13 @@ static int mongo_get_auth_secrets(secrets_list_t *sl, uint8_t *realm) { bson_destroy(&fields); return ret; } - -static int mongo_get_user_key(uint8_t *usname, uint8_t *realm, hmackey_t key) { - mongoc_collection_t * collection = mongo_get_collection("turnusers_lt"); - if(!collection) +static int mongo_get_user_key(uint8_t *usname, uint8_t *realm, hmackey_t key) { + mongoc_collection_t *collection = mongo_get_collection("turnusers_lt"); + + if (!collection) return -1; - + bson_t query; bson_init(&query); BSON_APPEND_UTF8(&query, "name", (const char *)usname); @@ -202,35 +196,36 @@ static int mongo_get_user_key(uint8_t *usname, uint8_t *realm, hmackey_t key) { bson_t fields; bson_init(&fields); BSON_APPEND_INT32(&fields, "hmackey", 1); - - mongoc_cursor_t * cursor; + + mongoc_cursor_t *cursor; cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 1, 0, &query, &fields, NULL); - + int ret = -1; if (!cursor) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'turnusers_lt'\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'turnusers_lt'\n"); } else { - const bson_t * item; + const bson_t *item; uint32_t length; bson_iter_t iter; - const char * value; + const char *value; if (mongoc_cursor_next(cursor, &item)) { - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "hmackey") && BSON_ITER_HOLDS_UTF8(&iter)) { + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "hmackey") && BSON_ITER_HOLDS_UTF8(&iter)) { value = bson_iter_utf8(&iter, &length); - size_t sz = get_hmackey_size(SHATYPE_DEFAULT) * 2; - if(length < sz) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key format: string length=%d (must be %d): user %s\n", (int)length, (int)sz, usname); - } else { - char kval[sizeof(hmackey_t) + sizeof(hmackey_t) + 1]; - memcpy(kval, value, sz); - kval[sz] = 0; - if(convert_string_key_to_binary(kval, key, sz / 2) < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key: %s, user %s\n", kval, usname); - } else { - ret = 0; - } - } + size_t sz = get_hmackey_size(SHATYPE_DEFAULT) * 2; + if (length < sz) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key format: string length=%d (must be %d): user %s\n", (int)length, + (int)sz, usname); + } else { + char kval[sizeof(hmackey_t) + sizeof(hmackey_t) + 1]; + memcpy(kval, value, sz); + kval[sz] = 0; + if (convert_string_key_to_binary(kval, key, sz / 2) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key: %s, user %s\n", kval, usname); + } else { + ret = 0; + } + } } } mongoc_cursor_destroy(cursor); @@ -243,76 +238,74 @@ static int mongo_get_user_key(uint8_t *usname, uint8_t *realm, hmackey_t key) { static int mongo_get_oauth_key(const uint8_t *kid, oauth_key_data_raw *key) { - mongoc_collection_t * collection = mongo_get_collection("oauth_key"); + mongoc_collection_t *collection = mongo_get_collection("oauth_key"); - if (!collection) - return -1; - - bson_t query; - bson_init(&query); - BSON_APPEND_UTF8(&query, "kid", (const char *)kid); - - bson_t fields; - bson_init(&fields); - BSON_APPEND_INT32(&fields, "lifetime", 1); - BSON_APPEND_INT32(&fields, "timestamp", 1); - BSON_APPEND_INT32(&fields, "as_rs_alg", 1); - BSON_APPEND_INT32(&fields, "realm", 1); - BSON_APPEND_INT32(&fields, "ikm_key", 1); - - mongoc_cursor_t * cursor; - cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 1, 0, - &query, &fields, NULL); - - int ret = -1; - - memset(key, 0, sizeof(oauth_key_data_raw)); - STRCPY(key->kid,kid); - - if (!cursor) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Error querying MongoDB collection 'oauth_key'\n"); - } else { - const bson_t * item; - uint32_t length; - bson_iter_t iter; - if (mongoc_cursor_next(cursor, &item)) { - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "as_rs_alg") && BSON_ITER_HOLDS_UTF8(&iter)) { - STRCPY(key->as_rs_alg,bson_iter_utf8(&iter, &length)); - } - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") && BSON_ITER_HOLDS_UTF8(&iter)) { - STRCPY(key->realm,bson_iter_utf8(&iter, &length)); - } - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "ikm_key") && BSON_ITER_HOLDS_UTF8(&iter)) { - STRCPY(key->ikm_key,bson_iter_utf8(&iter, &length)); - } - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "timestamp") && BSON_ITER_HOLDS_INT64(&iter)) { - key->timestamp = (uint64_t)bson_iter_int64(&iter); - } - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "lifetime") && BSON_ITER_HOLDS_INT32(&iter)) { - key->lifetime = (uint32_t)bson_iter_int32(&iter); - } - ret = 0; - } - mongoc_cursor_destroy(cursor); - } - mongoc_collection_destroy(collection); - bson_destroy(&query); - bson_destroy(&fields); - return ret; -} - -static int mongo_set_user_key(uint8_t *usname, uint8_t *realm, const char *key) { - mongoc_collection_t * collection = mongo_get_collection("turnusers_lt"); - - if(!collection) + if (!collection) return -1; - + + bson_t query; + bson_init(&query); + BSON_APPEND_UTF8(&query, "kid", (const char *)kid); + + bson_t fields; + bson_init(&fields); + BSON_APPEND_INT32(&fields, "lifetime", 1); + BSON_APPEND_INT32(&fields, "timestamp", 1); + BSON_APPEND_INT32(&fields, "as_rs_alg", 1); + BSON_APPEND_INT32(&fields, "realm", 1); + BSON_APPEND_INT32(&fields, "ikm_key", 1); + + mongoc_cursor_t *cursor; + cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 1, 0, &query, &fields, NULL); + + int ret = -1; + + memset(key, 0, sizeof(oauth_key_data_raw)); + STRCPY(key->kid, kid); + + if (!cursor) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'oauth_key'\n"); + } else { + const bson_t *item; + uint32_t length; + bson_iter_t iter; + if (mongoc_cursor_next(cursor, &item)) { + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "as_rs_alg") && BSON_ITER_HOLDS_UTF8(&iter)) { + STRCPY(key->as_rs_alg, bson_iter_utf8(&iter, &length)); + } + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") && BSON_ITER_HOLDS_UTF8(&iter)) { + STRCPY(key->realm, bson_iter_utf8(&iter, &length)); + } + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "ikm_key") && BSON_ITER_HOLDS_UTF8(&iter)) { + STRCPY(key->ikm_key, bson_iter_utf8(&iter, &length)); + } + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "timestamp") && BSON_ITER_HOLDS_INT64(&iter)) { + key->timestamp = (uint64_t)bson_iter_int64(&iter); + } + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "lifetime") && BSON_ITER_HOLDS_INT32(&iter)) { + key->lifetime = (uint32_t)bson_iter_int32(&iter); + } + ret = 0; + } + mongoc_cursor_destroy(cursor); + } + mongoc_collection_destroy(collection); + bson_destroy(&query); + bson_destroy(&fields); + return ret; +} + +static int mongo_set_user_key(uint8_t *usname, uint8_t *realm, const char *key) { + mongoc_collection_t *collection = mongo_get_collection("turnusers_lt"); + + if (!collection) + return -1; + bson_t query; bson_init(&query); BSON_APPEND_UTF8(&query, "name", (const char *)usname); BSON_APPEND_UTF8(&query, "realm", (const char *)realm); - + bson_t doc; bson_init(&doc); BSON_APPEND_UTF8(&doc, "name", (const char *)usname); @@ -320,7 +313,7 @@ static int mongo_set_user_key(uint8_t *usname, uint8_t *realm, const char *key) BSON_APPEND_UTF8(&doc, "hmackey", (const char *)key); int ret = -1; - + if (!mongoc_collection_update(collection, MONGOC_UPDATE_UPSERT, &query, &doc, NULL, NULL)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating user key information\n"); } else { @@ -334,9 +327,9 @@ static int mongo_set_user_key(uint8_t *usname, uint8_t *realm, const char *key) static int mongo_set_oauth_key(oauth_key_data_raw *key) { - mongoc_collection_t * collection = mongo_get_collection("oauth_key"); + mongoc_collection_t *collection = mongo_get_collection("oauth_key"); - if(!collection) + if (!collection) return -1; bson_t query; @@ -364,19 +357,19 @@ static int mongo_set_oauth_key(oauth_key_data_raw *key) { bson_destroy(&query); return ret; } - -static int mongo_del_user(uint8_t *usname, uint8_t *realm) { - mongoc_collection_t * collection = mongo_get_collection("turnusers_lt"); - if(!collection) +static int mongo_del_user(uint8_t *usname, uint8_t *realm) { + mongoc_collection_t *collection = mongo_get_collection("turnusers_lt"); + + if (!collection) return -1; - + bson_t query; bson_init(&query); BSON_APPEND_UTF8(&query, "name", (const char *)usname); BSON_APPEND_UTF8(&query, "realm", (const char *)realm); - - int ret = -1; + + int ret = -1; if (!mongoc_collection_delete(collection, MONGOC_DELETE_SINGLE_REMOVE, &query, NULL, NULL)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error deleting user key information\n"); @@ -390,9 +383,9 @@ static int mongo_del_user(uint8_t *usname, uint8_t *realm) { static int mongo_del_oauth_key(const uint8_t *kid) { - mongoc_collection_t * collection = mongo_get_collection("oauth_key"); + mongoc_collection_t *collection = mongo_get_collection("oauth_key"); - if(!collection) + if (!collection) return -1; bson_t query; @@ -410,18 +403,18 @@ static int mongo_del_oauth_key(const uint8_t *kid) { bson_destroy(&query); return ret; } - -static int mongo_list_users(uint8_t *realm, secrets_list_t *users, secrets_list_t *realms) -{ - const char * collection_name = "turnusers_lt"; - mongoc_collection_t * collection = mongo_get_collection(collection_name); - uint8_t realm0[STUN_MAX_REALM_SIZE+1] = "\0"; - if(!realm) realm=realm0; +static int mongo_list_users(uint8_t *realm, secrets_list_t *users, secrets_list_t *realms) { + const char *collection_name = "turnusers_lt"; + mongoc_collection_t *collection = mongo_get_collection(collection_name); - if(!collection) + uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0"; + if (!realm) + realm = realm0; + + if (!collection) return -1; - + bson_t query, child; bson_init(&query); bson_append_document_begin(&query, "$orderby", -1, &child); @@ -439,41 +432,42 @@ static int mongo_list_users(uint8_t *realm, secrets_list_t *users, secrets_list_ BSON_APPEND_INT32(&fields, "name", 1); BSON_APPEND_INT32(&fields, "realm", 1); - mongoc_cursor_t * cursor; + mongoc_cursor_t *cursor; cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, &fields, NULL); int ret = -1; - + if (!cursor) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection '%s'\n", collection_name); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection '%s'\n", collection_name); } else { - const bson_t * item; + const bson_t *item; uint32_t length; bson_iter_t iter; bson_iter_t iter_realm; - const char * value; + const char *value; while (mongoc_cursor_next(cursor, &item)) { - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "name") && BSON_ITER_HOLDS_UTF8(&iter)) { - value = bson_iter_utf8(&iter, &length); - if (length) { - const char *rval = ""; - if (bson_iter_init(&iter_realm, item) && bson_iter_find(&iter_realm, "realm") && BSON_ITER_HOLDS_UTF8(&iter_realm)) { - rval = bson_iter_utf8(&iter_realm, &length); - } - if(users) { - add_to_secrets_list(users,value); - if(realms) { - if(rval && *rval) { - add_to_secrets_list(realms,rval); - } else { - add_to_secrets_list(realms,(char*)realm); - } - } - } else { - printf("%s[%s]\n", value, rval); - } - } - } + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "name") && BSON_ITER_HOLDS_UTF8(&iter)) { + value = bson_iter_utf8(&iter, &length); + if (length) { + const char *rval = ""; + if (bson_iter_init(&iter_realm, item) && bson_iter_find(&iter_realm, "realm") && + BSON_ITER_HOLDS_UTF8(&iter_realm)) { + rval = bson_iter_utf8(&iter_realm, &length); + } + if (users) { + add_to_secrets_list(users, value); + if (realms) { + if (rval && *rval) { + add_to_secrets_list(realms, rval); + } else { + add_to_secrets_list(realms, (char *)realm); + } + } + } else { + printf("%s[%s]\n", value, rval); + } + } + } } mongoc_cursor_destroy(cursor); ret = 0; @@ -484,12 +478,13 @@ static int mongo_list_users(uint8_t *realm, secrets_list_t *users, secrets_list_ return ret; } -static int mongo_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts,secrets_list_t *realms) { +static int mongo_list_oauth_keys(secrets_list_t *kids, secrets_list_t *teas, secrets_list_t *tss, secrets_list_t *lts, + secrets_list_t *realms) { - const char * collection_name = "oauth_key"; - mongoc_collection_t * collection = mongo_get_collection(collection_name); + const char *collection_name = "oauth_key"; + mongoc_collection_t *collection = mongo_get_collection(collection_name); - if(!collection) + if (!collection) return -1; bson_t query; @@ -511,59 +506,58 @@ static int mongo_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secre BSON_APPEND_INT32(&fields, "realm", 1); BSON_APPEND_INT32(&fields, "ikm_key", 1); - mongoc_cursor_t * cursor; + mongoc_cursor_t *cursor; cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, &fields, NULL); int ret = -1; if (!cursor) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection '%s'\n", collection_name); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection '%s'\n", collection_name); } else { - const bson_t * item; - oauth_key_data_raw key_; - oauth_key_data_raw *key=&key_; + const bson_t *item; + oauth_key_data_raw key_; + oauth_key_data_raw *key = &key_; uint32_t length; bson_iter_t iter; while (mongoc_cursor_next(cursor, &item)) { - memset(key, 0, sizeof(oauth_key_data_raw)); - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "kid") && BSON_ITER_HOLDS_UTF8(&iter)) { - STRCPY(key->kid,bson_iter_utf8(&iter, &length)); - } - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "as_rs_alg") && BSON_ITER_HOLDS_UTF8(&iter)) { - STRCPY(key->as_rs_alg,bson_iter_utf8(&iter, &length)); - } - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") && BSON_ITER_HOLDS_UTF8(&iter)) { - STRCPY(key->realm,bson_iter_utf8(&iter, &length)); - } - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "ikm_key") && BSON_ITER_HOLDS_UTF8(&iter)) { - STRCPY(key->ikm_key,bson_iter_utf8(&iter, &length)); - } - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "timestamp") && BSON_ITER_HOLDS_INT64(&iter)) { - key->timestamp = (uint64_t)bson_iter_int64(&iter); - } - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "lifetime") && BSON_ITER_HOLDS_INT32(&iter)) { - key->lifetime = (uint32_t)bson_iter_int32(&iter); - } - if(kids) { - add_to_secrets_list(kids,key->kid); - add_to_secrets_list(teas,key->as_rs_alg); - add_to_secrets_list(realms,key->realm); - { - char ts[256]; - snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp); - add_to_secrets_list(tss,ts); - } - { - char lt[256]; - snprintf(lt,sizeof(lt)-1,"%lu",(unsigned long)key->lifetime); - add_to_secrets_list(lts,lt); - } - } else { - printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, realm=%s\n", - key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, - key->as_rs_alg, key->realm); - } + memset(key, 0, sizeof(oauth_key_data_raw)); + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "kid") && BSON_ITER_HOLDS_UTF8(&iter)) { + STRCPY(key->kid, bson_iter_utf8(&iter, &length)); + } + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "as_rs_alg") && BSON_ITER_HOLDS_UTF8(&iter)) { + STRCPY(key->as_rs_alg, bson_iter_utf8(&iter, &length)); + } + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") && BSON_ITER_HOLDS_UTF8(&iter)) { + STRCPY(key->realm, bson_iter_utf8(&iter, &length)); + } + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "ikm_key") && BSON_ITER_HOLDS_UTF8(&iter)) { + STRCPY(key->ikm_key, bson_iter_utf8(&iter, &length)); + } + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "timestamp") && BSON_ITER_HOLDS_INT64(&iter)) { + key->timestamp = (uint64_t)bson_iter_int64(&iter); + } + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "lifetime") && BSON_ITER_HOLDS_INT32(&iter)) { + key->lifetime = (uint32_t)bson_iter_int32(&iter); + } + if (kids) { + add_to_secrets_list(kids, key->kid); + add_to_secrets_list(teas, key->as_rs_alg); + add_to_secrets_list(realms, key->realm); + { + char ts[256]; + snprintf(ts, sizeof(ts) - 1, "%llu", (unsigned long long)key->timestamp); + add_to_secrets_list(tss, ts); + } + { + char lt[256]; + snprintf(lt, sizeof(lt) - 1, "%lu", (unsigned long)key->lifetime); + add_to_secrets_list(lts, lt); + } + } else { + printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, realm=%s\n", key->kid, key->ikm_key, + (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->as_rs_alg, key->realm); + } } mongoc_cursor_destroy(cursor); ret = 0; @@ -573,89 +567,90 @@ static int mongo_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secre bson_destroy(&fields); return ret; } - -static int mongo_list_secrets(uint8_t *realm, secrets_list_t *secrets, secrets_list_t *realms) -{ - mongoc_collection_t * collection = mongo_get_collection("turn_secret"); - uint8_t realm0[STUN_MAX_REALM_SIZE+1] = "\0"; - if(!realm) realm=realm0; +static int mongo_list_secrets(uint8_t *realm, secrets_list_t *secrets, secrets_list_t *realms) { + mongoc_collection_t *collection = mongo_get_collection("turn_secret"); - if(!collection) - return -1; - - bson_t query, child; - bson_init(&query); - bson_append_document_begin(&query, "$orderby", -1, &child); - bson_append_int32(&child, "realm", -1, 1); - bson_append_int32(&child, "value", -1, 1); - bson_append_document_end(&query, &child); - bson_append_document_begin(&query, "$query", -1, &child); - if (realm && realm[0]) { - BSON_APPEND_UTF8(&child, "realm", (const char *)realm); - } - bson_append_document_end(&query, &child); + uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0"; + if (!realm) + realm = realm0; - bson_t fields; - bson_init(&fields); - BSON_APPEND_INT32(&fields, "value", 1); - BSON_APPEND_INT32(&fields, "realm", 1); - - mongoc_cursor_t * cursor; - cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, &fields, NULL); - - int ret = -1; - - if (!cursor) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'turn_secret'\n"); - } else { - const bson_t * item; - uint32_t length; - bson_iter_t iter; - bson_iter_t iter_realm; - const char * value; - while (mongoc_cursor_next(cursor, &item)) { - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "value") && BSON_ITER_HOLDS_UTF8(&iter)) { - value = bson_iter_utf8(&iter, &length); - if (length) { - const char *rval = ""; - if (bson_iter_init(&iter_realm, item) && bson_iter_find(&iter_realm, "realm") && BSON_ITER_HOLDS_UTF8(&iter_realm)) { - rval = bson_iter_utf8(&iter_realm, &length); - } - if(secrets) { - add_to_secrets_list(secrets,value); - if(realms) { - if(rval && *rval) { - add_to_secrets_list(realms,rval); - } else { - add_to_secrets_list(realms,(char*)realm); - } - } - } else { - printf("%s[%s]\n", value, rval); - } - } - } - } - mongoc_cursor_destroy(cursor); - ret = 0; - } - mongoc_collection_destroy(collection); - bson_destroy(&query); - bson_destroy(&fields); - return ret; -} - -static int mongo_del_secret(uint8_t *secret, uint8_t *realm) { - mongoc_collection_t * collection = mongo_get_collection("turn_secret"); - - if(!collection) + if (!collection) return -1; - + + bson_t query, child; + bson_init(&query); + bson_append_document_begin(&query, "$orderby", -1, &child); + bson_append_int32(&child, "realm", -1, 1); + bson_append_int32(&child, "value", -1, 1); + bson_append_document_end(&query, &child); + bson_append_document_begin(&query, "$query", -1, &child); + if (realm && realm[0]) { + BSON_APPEND_UTF8(&child, "realm", (const char *)realm); + } + bson_append_document_end(&query, &child); + + bson_t fields; + bson_init(&fields); + BSON_APPEND_INT32(&fields, "value", 1); + BSON_APPEND_INT32(&fields, "realm", 1); + + mongoc_cursor_t *cursor; + cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, &fields, NULL); + + int ret = -1; + + if (!cursor) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'turn_secret'\n"); + } else { + const bson_t *item; + uint32_t length; + bson_iter_t iter; + bson_iter_t iter_realm; + const char *value; + while (mongoc_cursor_next(cursor, &item)) { + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "value") && BSON_ITER_HOLDS_UTF8(&iter)) { + value = bson_iter_utf8(&iter, &length); + if (length) { + const char *rval = ""; + if (bson_iter_init(&iter_realm, item) && bson_iter_find(&iter_realm, "realm") && + BSON_ITER_HOLDS_UTF8(&iter_realm)) { + rval = bson_iter_utf8(&iter_realm, &length); + } + if (secrets) { + add_to_secrets_list(secrets, value); + if (realms) { + if (rval && *rval) { + add_to_secrets_list(realms, rval); + } else { + add_to_secrets_list(realms, (char *)realm); + } + } + } else { + printf("%s[%s]\n", value, rval); + } + } + } + } + mongoc_cursor_destroy(cursor); + ret = 0; + } + mongoc_collection_destroy(collection); + bson_destroy(&query); + bson_destroy(&fields); + return ret; +} + +static int mongo_del_secret(uint8_t *secret, uint8_t *realm) { + mongoc_collection_t *collection = mongo_get_collection("turn_secret"); + + if (!collection) + return -1; + bson_t query; bson_init(&query); BSON_APPEND_UTF8(&query, "realm", (const char *)realm); - if(secret && (secret[0]!=0)) { + if (secret && (secret[0] != 0)) { BSON_APPEND_UTF8(&query, "value", (const char *)secret); } @@ -664,13 +659,13 @@ static int mongo_del_secret(uint8_t *secret, uint8_t *realm) { bson_destroy(&query); return 0; } - -static int mongo_set_secret(uint8_t *secret, uint8_t *realm) { - mongoc_collection_t * collection = mongo_get_collection("turn_secret"); - if(!collection) +static int mongo_set_secret(uint8_t *secret, uint8_t *realm) { + mongoc_collection_t *collection = mongo_get_collection("turn_secret"); + + if (!collection) return -1; - + bson_t query; bson_init(&query); BSON_APPEND_UTF8(&query, "realm", (const char *)realm); @@ -688,92 +683,91 @@ static int mongo_set_secret(uint8_t *secret, uint8_t *realm) { } } -static int mongo_set_permission_ip(const char *kind, uint8_t *realm, const char* ip, int del) -{ - char sub_collection_name[129]; - snprintf(sub_collection_name,sizeof(sub_collection_name)-1,"%s_peer_ip",kind); +static int mongo_set_permission_ip(const char *kind, uint8_t *realm, const char *ip, int del) { + char sub_collection_name[129]; + snprintf(sub_collection_name, sizeof(sub_collection_name) - 1, "%s_peer_ip", kind); - mongoc_collection_t * collection = mongo_get_collection("realm"); + mongoc_collection_t *collection = mongo_get_collection("realm"); - if(!collection) - return -1; - - int ret = -1; - - uint8_t realm0[STUN_MAX_REALM_SIZE+1] = "\0"; - if(!realm) realm=realm0; - - bson_t query, doc, child; - bson_init(&query); - BSON_APPEND_UTF8(&query, "realm", (const char *)realm); - bson_init(&doc); - if(del) { - bson_append_document_begin(&doc, "$pull", -1, &child); - } else { - bson_append_document_begin(&doc, "$addToSet", -1, &child); - } - BSON_APPEND_UTF8(&child, sub_collection_name, (const char *)ip); - bson_append_document_end(&doc, &child); - - mongoc_update_flags_t flags = MONGOC_UPDATE_NONE; - - if(del) { - flags = MONGOC_UPDATE_MULTI_UPDATE; - } else { - flags = MONGOC_UPDATE_UPSERT; - } - - if (!mongoc_collection_update(collection, flags, &query, &doc, NULL, NULL)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting permission ip information\n"); - } else { - ret = 0; - } - mongoc_collection_destroy(collection); - bson_destroy(&query); - bson_destroy(&doc); - return ret; -} - -static int mongo_add_origin(uint8_t *origin, uint8_t *realm) -{ - mongoc_collection_t * collection = mongo_get_collection("realm"); - - if(!collection) - return -1; - - int ret = -1; - - uint8_t realm0[STUN_MAX_REALM_SIZE+1] = "\0"; - if(!realm) realm=realm0; - - bson_t query, doc, child; - bson_init(&query); - BSON_APPEND_UTF8(&query, "realm", (const char *)realm); - bson_init(&doc); - bson_append_document_begin(&doc, "$addToSet", -1, &child); - BSON_APPEND_UTF8(&child, "origin", (const char *)origin); - bson_append_document_end(&doc, &child); - - if (!mongoc_collection_update(collection, MONGOC_UPDATE_UPSERT, &query, &doc, NULL, NULL)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating realm origin information\n"); - } else { - ret = 0; - } - mongoc_collection_destroy(collection); - bson_destroy(&query); - bson_destroy(&doc); - return ret; -} - -static int mongo_del_origin(uint8_t *origin) -{ - mongoc_collection_t * collection = mongo_get_collection("realm"); - - if(!collection) + if (!collection) return -1; - + int ret = -1; - + + uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0"; + if (!realm) + realm = realm0; + + bson_t query, doc, child; + bson_init(&query); + BSON_APPEND_UTF8(&query, "realm", (const char *)realm); + bson_init(&doc); + if (del) { + bson_append_document_begin(&doc, "$pull", -1, &child); + } else { + bson_append_document_begin(&doc, "$addToSet", -1, &child); + } + BSON_APPEND_UTF8(&child, sub_collection_name, (const char *)ip); + bson_append_document_end(&doc, &child); + + mongoc_update_flags_t flags = MONGOC_UPDATE_NONE; + + if (del) { + flags = MONGOC_UPDATE_MULTI_UPDATE; + } else { + flags = MONGOC_UPDATE_UPSERT; + } + + if (!mongoc_collection_update(collection, flags, &query, &doc, NULL, NULL)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting permission ip information\n"); + } else { + ret = 0; + } + mongoc_collection_destroy(collection); + bson_destroy(&query); + bson_destroy(&doc); + return ret; +} + +static int mongo_add_origin(uint8_t *origin, uint8_t *realm) { + mongoc_collection_t *collection = mongo_get_collection("realm"); + + if (!collection) + return -1; + + int ret = -1; + + uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0"; + if (!realm) + realm = realm0; + + bson_t query, doc, child; + bson_init(&query); + BSON_APPEND_UTF8(&query, "realm", (const char *)realm); + bson_init(&doc); + bson_append_document_begin(&doc, "$addToSet", -1, &child); + BSON_APPEND_UTF8(&child, "origin", (const char *)origin); + bson_append_document_end(&doc, &child); + + if (!mongoc_collection_update(collection, MONGOC_UPDATE_UPSERT, &query, &doc, NULL, NULL)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating realm origin information\n"); + } else { + ret = 0; + } + mongoc_collection_destroy(collection); + bson_destroy(&query); + bson_destroy(&doc); + return ret; +} + +static int mongo_del_origin(uint8_t *origin) { + mongoc_collection_t *collection = mongo_get_collection("realm"); + + if (!collection) + return -1; + + int ret = -1; + bson_t query, doc, child; bson_init(&query); bson_init(&doc); @@ -791,101 +785,101 @@ static int mongo_del_origin(uint8_t *origin) bson_destroy(&doc); return ret; } - -static int mongo_list_origins(uint8_t *realm, secrets_list_t *origins, secrets_list_t *realms) -{ - mongoc_collection_t * collection = mongo_get_collection("realm"); - if(!collection) - return -1; +static int mongo_list_origins(uint8_t *realm, secrets_list_t *origins, secrets_list_t *realms) { + mongoc_collection_t *collection = mongo_get_collection("realm"); - uint8_t realm0[STUN_MAX_REALM_SIZE+1] = "\0"; - if(!realm) realm=realm0; - - bson_t query, child; - bson_init(&query); - bson_append_document_begin(&query, "$orderby", -1, &child); - BSON_APPEND_INT32(&child, "realm", 1); - bson_append_document_end(&query, &child); - bson_append_document_begin(&query, "$query", -1, &child); - if (realm && realm[0]) { - BSON_APPEND_UTF8(&child, "realm", (const char *)realm); - } - bson_append_document_end(&query, &child); - - bson_t fields; - bson_init(&fields); - BSON_APPEND_INT32(&fields, "origin", 1); - BSON_APPEND_INT32(&fields, "realm", 1); - - mongoc_cursor_t * cursor; - cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, &fields, NULL); - - int ret = -1; - - if (!cursor) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'realm'\n"); - } else { - const bson_t * item; - uint32_t length; - bson_iter_t iter; - - while (mongoc_cursor_next(cursor, &item)) { - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") && BSON_ITER_HOLDS_UTF8(&iter)) { - const char * _realm = bson_iter_utf8(&iter, &length); - - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "origin") && BSON_ITER_HOLDS_ARRAY(&iter)) { - const uint8_t *docbuf = NULL; - uint32_t doclen = 0; - bson_t origin_array; - bson_iter_t origin_iter; - - bson_iter_array(&iter, &doclen, &docbuf); - bson_init_static(&origin_array, docbuf, doclen); - - if (bson_iter_init(&origin_iter, &origin_array)) { - while(bson_iter_next(&origin_iter)) { - if (BSON_ITER_HOLDS_UTF8(&origin_iter)) { - const char * _origin = bson_iter_utf8(&origin_iter, &length); - if(origins) { - add_to_secrets_list(origins,_origin); - if(realms) { - add_to_secrets_list(realms,_realm); - } - } else { - printf("%s ==>> %s\n", _realm, _origin); - } - } - } - } - } - } - } - mongoc_cursor_destroy(cursor); - ret = 0; - } - mongoc_collection_destroy(collection); - bson_destroy(&query); - bson_destroy(&fields); - return ret; -} - -static int mongo_set_realm_option_one(uint8_t *realm, unsigned long value, const char* opt) { - mongoc_collection_t * collection = mongo_get_collection("realm"); - - if(!collection) + if (!collection) return -1; - + + uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0"; + if (!realm) + realm = realm0; + + bson_t query, child; + bson_init(&query); + bson_append_document_begin(&query, "$orderby", -1, &child); + BSON_APPEND_INT32(&child, "realm", 1); + bson_append_document_end(&query, &child); + bson_append_document_begin(&query, "$query", -1, &child); + if (realm && realm[0]) { + BSON_APPEND_UTF8(&child, "realm", (const char *)realm); + } + bson_append_document_end(&query, &child); + + bson_t fields; + bson_init(&fields); + BSON_APPEND_INT32(&fields, "origin", 1); + BSON_APPEND_INT32(&fields, "realm", 1); + + mongoc_cursor_t *cursor; + cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, &fields, NULL); + + int ret = -1; + + if (!cursor) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'realm'\n"); + } else { + const bson_t *item; + uint32_t length; + bson_iter_t iter; + + while (mongoc_cursor_next(cursor, &item)) { + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") && BSON_ITER_HOLDS_UTF8(&iter)) { + const char *_realm = bson_iter_utf8(&iter, &length); + + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "origin") && BSON_ITER_HOLDS_ARRAY(&iter)) { + const uint8_t *docbuf = NULL; + uint32_t doclen = 0; + bson_t origin_array; + bson_iter_t origin_iter; + + bson_iter_array(&iter, &doclen, &docbuf); + bson_init_static(&origin_array, docbuf, doclen); + + if (bson_iter_init(&origin_iter, &origin_array)) { + while (bson_iter_next(&origin_iter)) { + if (BSON_ITER_HOLDS_UTF8(&origin_iter)) { + const char *_origin = bson_iter_utf8(&origin_iter, &length); + if (origins) { + add_to_secrets_list(origins, _origin); + if (realms) { + add_to_secrets_list(realms, _realm); + } + } else { + printf("%s ==>> %s\n", _realm, _origin); + } + } + } + } + } + } + } + mongoc_cursor_destroy(cursor); + ret = 0; + } + mongoc_collection_destroy(collection); + bson_destroy(&query); + bson_destroy(&fields); + return ret; +} + +static int mongo_set_realm_option_one(uint8_t *realm, unsigned long value, const char *opt) { + mongoc_collection_t *collection = mongo_get_collection("realm"); + + if (!collection) + return -1; + bson_t query, doc, child; bson_init(&query); BSON_APPEND_UTF8(&query, "realm", (const char *)realm); bson_init(&doc); - + size_t klen = 9 + strlen(opt); - char * _k = (char *)malloc(klen); + char *_k = (char *)malloc(klen); strcpy(_k, "options."); strcat(_k, opt); - + if (value > 0) { bson_append_document_begin(&doc, "$set", -1, &child); BSON_APPEND_INT32(&child, _k, (int32_t)value); @@ -896,9 +890,9 @@ static int mongo_set_realm_option_one(uint8_t *realm, unsigned long value, const bson_append_document_end(&doc, &child); } free(_k); - + int ret = -1; - + if (!mongoc_collection_update(collection, MONGOC_UPDATE_MULTI_UPDATE, &query, &doc, NULL, NULL)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error deleting origin information\n"); } else { @@ -909,13 +903,13 @@ static int mongo_set_realm_option_one(uint8_t *realm, unsigned long value, const bson_destroy(&doc); return ret; } - -static int mongo_list_realm_options(uint8_t *realm) { - mongoc_collection_t * collection = mongo_get_collection("realm"); - if(!collection) +static int mongo_list_realm_options(uint8_t *realm) { + mongoc_collection_t *collection = mongo_get_collection("realm"); + + if (!collection) return -1; - + bson_t query, child; bson_init(&query); bson_append_document_begin(&query, "$orderby", -1, &child); @@ -931,22 +925,22 @@ static int mongo_list_realm_options(uint8_t *realm) { bson_init(&fields); BSON_APPEND_INT32(&fields, "options", 1); BSON_APPEND_INT32(&fields, "realm", 1); - - mongoc_cursor_t * cursor; + + mongoc_cursor_t *cursor; cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, &fields, NULL); int ret = -1; - + if (!cursor) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'realm'\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'realm'\n"); } else { - const bson_t * item; + const bson_t *item; uint32_t length; bson_iter_t iter; while (mongoc_cursor_next(cursor, &item)) { - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") && BSON_ITER_HOLDS_UTF8(&iter)) { - const char * _realm = bson_iter_utf8(&iter, &length); + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") && BSON_ITER_HOLDS_UTF8(&iter)) { + const char *_realm = bson_iter_utf8(&iter, &length); if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "options") && BSON_ITER_HOLDS_DOCUMENT(&iter)) { const uint8_t *docbuf = NULL; @@ -958,17 +952,17 @@ static int mongo_list_realm_options(uint8_t *realm) { bson_init_static(&options, docbuf, doclen); if (bson_iter_init(&options_iter, &options)) { - while(bson_iter_next(&options_iter)) { - const char * _k = bson_iter_key(&options_iter); + while (bson_iter_next(&options_iter)) { + const char *_k = bson_iter_key(&options_iter); if (BSON_ITER_HOLDS_DOUBLE(&options_iter)) { int32_t _v = (int32_t)bson_iter_double(&options_iter); - printf("%s[%s]=%d\n", _k, _realm, _v); + printf("%s[%s]=%d\n", _k, _realm, _v); } else if (BSON_ITER_HOLDS_INT32(&options_iter)) { int32_t _v = bson_iter_int32(&options_iter); - printf("%s[%s]=%d\n", _k, _realm, _v); + printf("%s[%s]=%d\n", _k, _realm, _v); } else if (BSON_ITER_HOLDS_INT64(&options_iter)) { int32_t _v = (int32_t)bson_iter_int64(&options_iter); - printf("%s[%s]=%d\n", _k, _realm, _v); + printf("%s[%s]=%d\n", _k, _realm, _v); } } } @@ -983,424 +977,380 @@ static int mongo_list_realm_options(uint8_t *realm) { bson_destroy(&fields); return ret; } - -static void mongo_auth_ping(void * rch) { - UNUSED_ARG(rch); + +static void mongo_auth_ping(void *rch) { + UNUSED_ARG(rch); // NOOP } -static int mongo_read_realms_ip_lists(const char *kind, ip_range_list_t * list) -{ - int ret = 0; +static int mongo_read_realms_ip_lists(const char *kind, ip_range_list_t *list) { + int ret = 0; - char field_name[129]; - sprintf(field_name, "%s_peer_ip", kind); + char field_name[129]; + sprintf(field_name, "%s_peer_ip", kind); - mongoc_collection_t * collection = mongo_get_collection("realm"); + mongoc_collection_t *collection = mongo_get_collection("realm"); - if (!collection) - return ret; + if (!collection) + return ret; - bson_t query; - bson_init(&query); + bson_t query; + bson_init(&query); - bson_t fields; - bson_init(&fields); - BSON_APPEND_INT32(&fields, "realm", 1); - BSON_APPEND_INT32(&fields, field_name, 1); + bson_t fields; + bson_init(&fields); + BSON_APPEND_INT32(&fields, "realm", 1); + BSON_APPEND_INT32(&fields, field_name, 1); - mongoc_cursor_t * cursor; - cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, - &query, &fields, NULL); + mongoc_cursor_t *cursor; + cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, &fields, NULL); - if (!cursor) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Error querying MongoDB collection 'realm'\n"); - ret = -1; - } else { - const bson_t * item; - uint32_t length; - bson_iter_t iter; - char realm[513]; + if (!cursor) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'realm'\n"); + ret = -1; + } else { + const bson_t *item; + uint32_t length; + bson_iter_t iter; + char realm[513]; - while (mongoc_cursor_next(cursor, &item)) { + while (mongoc_cursor_next(cursor, &item)) { - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") - && BSON_ITER_HOLDS_UTF8(&iter)) { + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") && BSON_ITER_HOLDS_UTF8(&iter)) { - STRCPY(realm,bson_iter_utf8(&iter, &length)); + STRCPY(realm, bson_iter_utf8(&iter, &length)); - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, - field_name) && BSON_ITER_HOLDS_ARRAY(&iter)) { - const uint8_t *docbuf = NULL; - uint32_t doclen = 0; - bson_t ip_range_array; - bson_iter_t ip_range_iter; + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, field_name) && BSON_ITER_HOLDS_ARRAY(&iter)) { + const uint8_t *docbuf = NULL; + uint32_t doclen = 0; + bson_t ip_range_array; + bson_iter_t ip_range_iter; - bson_iter_array(&iter, &doclen, &docbuf); - bson_init_static(&ip_range_array, docbuf, doclen); + bson_iter_array(&iter, &doclen, &docbuf); + bson_init_static(&ip_range_array, docbuf, doclen); - if (bson_iter_init(&ip_range_iter, &ip_range_array)) { - while (bson_iter_next(&ip_range_iter)) { - if (BSON_ITER_HOLDS_UTF8(&ip_range_iter)) { - const char* ip_range = bson_iter_utf8(&ip_range_iter, &length); - add_ip_list_range(ip_range, realm, list); - } - } - } - } - } - } - mongoc_cursor_destroy(cursor); - } - mongoc_collection_destroy(collection); - bson_destroy(&query); - bson_destroy(&fields); + if (bson_iter_init(&ip_range_iter, &ip_range_array)) { + while (bson_iter_next(&ip_range_iter)) { + if (BSON_ITER_HOLDS_UTF8(&ip_range_iter)) { + const char *ip_range = bson_iter_utf8(&ip_range_iter, &length); + add_ip_list_range(ip_range, realm, list); + } + } + } + } + } + } + mongoc_cursor_destroy(cursor); + } + mongoc_collection_destroy(collection); + bson_destroy(&query); + bson_destroy(&fields); - return ret; + return ret; } - -static int mongo_get_ip_list(const char *kind, ip_range_list_t * list) { - return mongo_read_realms_ip_lists(kind, list); -} - -static void mongo_reread_realms(secrets_list_t * realms_list) { +static int mongo_get_ip_list(const char *kind, ip_range_list_t *list) { return mongo_read_realms_ip_lists(kind, list); } - UNUSED_ARG(realms_list); +static void mongo_reread_realms(secrets_list_t *realms_list) { - mongoc_collection_t * collection = mongo_get_collection("realm"); + UNUSED_ARG(realms_list); - if (!collection) - return; + mongoc_collection_t *collection = mongo_get_collection("realm"); - bson_t query; - bson_init(&query); + if (!collection) + return; - bson_t fields; - bson_init(&fields); - BSON_APPEND_INT32(&fields, "realm", 1); - BSON_APPEND_INT32(&fields, "origin", 1); - BSON_APPEND_INT32(&fields, "options", 1); + bson_t query; + bson_init(&query); - mongoc_cursor_t * cursor; - cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, - &query, &fields, NULL); + bson_t fields; + bson_init(&fields); + BSON_APPEND_INT32(&fields, "realm", 1); + BSON_APPEND_INT32(&fields, "origin", 1); + BSON_APPEND_INT32(&fields, "options", 1); - if (!cursor) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Error querying MongoDB collection 'realm'\n"); - } else { - ur_string_map *o_to_realm_new = ur_string_map_create(free); + mongoc_cursor_t *cursor; + cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, &fields, NULL); - const bson_t * item; - uint32_t length; - bson_iter_t iter; + if (!cursor) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'realm'\n"); + } else { + ur_string_map *o_to_realm_new = ur_string_map_create(free); - while (mongoc_cursor_next(cursor, &item)) { + const bson_t *item; + uint32_t length; + bson_iter_t iter; - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") - && BSON_ITER_HOLDS_UTF8(&iter)) { + while (mongoc_cursor_next(cursor, &item)) { - char * _realm = strdup(bson_iter_utf8(&iter, &length)); + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") && BSON_ITER_HOLDS_UTF8(&iter)) { - get_realm(_realm); + char *_realm = strdup(bson_iter_utf8(&iter, &length)); - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, - "origin") && BSON_ITER_HOLDS_ARRAY(&iter)) { - const uint8_t *docbuf = NULL; - uint32_t doclen = 0; - bson_t origin_array; - bson_iter_t origin_iter; + get_realm(_realm); - bson_iter_array(&iter, &doclen, &docbuf); - bson_init_static(&origin_array, docbuf, doclen); + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "origin") && BSON_ITER_HOLDS_ARRAY(&iter)) { + const uint8_t *docbuf = NULL; + uint32_t doclen = 0; + bson_t origin_array; + bson_iter_t origin_iter; - if (bson_iter_init(&origin_iter, &origin_array)) { - while (bson_iter_next(&origin_iter)) { - if (BSON_ITER_HOLDS_UTF8(&origin_iter)) { - char* _origin = strdup(bson_iter_utf8(&origin_iter, &length)); - char *rval = strdup(_realm); - ur_string_map_value_type value = - (ur_string_map_value_type) (rval); - ur_string_map_put(o_to_realm_new, - (ur_string_map_key_type) _origin, - value); - free(_origin); - } - } - } - } + bson_iter_array(&iter, &doclen, &docbuf); + bson_init_static(&origin_array, docbuf, doclen); - realm_params_t* rp = get_realm(_realm); - lock_realms(); - rp->options.perf_options.max_bps = turn_params.max_bps; - rp->options.perf_options.total_quota = turn_params.total_quota; - rp->options.perf_options.user_quota = turn_params.user_quota; - unlock_realms(); + if (bson_iter_init(&origin_iter, &origin_array)) { + while (bson_iter_next(&origin_iter)) { + if (BSON_ITER_HOLDS_UTF8(&origin_iter)) { + char *_origin = strdup(bson_iter_utf8(&origin_iter, &length)); + char *rval = strdup(_realm); + ur_string_map_value_type value = (ur_string_map_value_type)(rval); + ur_string_map_put(o_to_realm_new, (ur_string_map_key_type)_origin, value); + free(_origin); + } + } + } + } - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, - "options") && BSON_ITER_HOLDS_DOCUMENT(&iter)) { - const uint8_t *docbuf = NULL; - uint32_t doclen = 0; - bson_t options; - bson_iter_t options_iter; + realm_params_t *rp = get_realm(_realm); + lock_realms(); + rp->options.perf_options.max_bps = turn_params.max_bps; + rp->options.perf_options.total_quota = turn_params.total_quota; + rp->options.perf_options.user_quota = turn_params.user_quota; + unlock_realms(); - bson_iter_document(&iter, &doclen, &docbuf); - bson_init_static(&options, docbuf, doclen); + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "options") && BSON_ITER_HOLDS_DOCUMENT(&iter)) { + const uint8_t *docbuf = NULL; + uint32_t doclen = 0; + bson_t options; + bson_iter_t options_iter; - if (bson_iter_init(&options_iter, &options)) { - while (bson_iter_next(&options_iter)) { - const char * _k = bson_iter_key(&options_iter); - uint64_t _v = 0; - if (BSON_ITER_HOLDS_DOUBLE(&options_iter)) { - _v = (uint64_t) bson_iter_double(&options_iter); - } else if (BSON_ITER_HOLDS_INT32(&options_iter)) { - _v = (uint64_t)bson_iter_int32(&options_iter); - } else if (BSON_ITER_HOLDS_INT64(&options_iter)) { - _v = (uint64_t) bson_iter_int64(&options_iter); - } - if (_v) { - if (!strcmp(_k, "max-bps")) - rp->options.perf_options.max_bps = (band_limit_t) _v; - else if (!strcmp(_k, "total-quota")) - rp->options.perf_options.total_quota = (vint) _v; - else if (!strcmp(_k, "user-quota")) - rp->options.perf_options.user_quota = (vint) _v; - else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Unknown realm option: %s\n", _k); - } - } - } - } - } - free(_realm); - } - } - update_o_to_realm(o_to_realm_new); - mongoc_cursor_destroy(cursor); - } - mongoc_collection_destroy(collection); - bson_destroy(&query); - bson_destroy(&fields); + bson_iter_document(&iter, &doclen, &docbuf); + bson_init_static(&options, docbuf, doclen); + + if (bson_iter_init(&options_iter, &options)) { + while (bson_iter_next(&options_iter)) { + const char *_k = bson_iter_key(&options_iter); + uint64_t _v = 0; + if (BSON_ITER_HOLDS_DOUBLE(&options_iter)) { + _v = (uint64_t)bson_iter_double(&options_iter); + } else if (BSON_ITER_HOLDS_INT32(&options_iter)) { + _v = (uint64_t)bson_iter_int32(&options_iter); + } else if (BSON_ITER_HOLDS_INT64(&options_iter)) { + _v = (uint64_t)bson_iter_int64(&options_iter); + } + if (_v) { + if (!strcmp(_k, "max-bps")) + rp->options.perf_options.max_bps = (band_limit_t)_v; + else if (!strcmp(_k, "total-quota")) + rp->options.perf_options.total_quota = (vint)_v; + else if (!strcmp(_k, "user-quota")) + rp->options.perf_options.user_quota = (vint)_v; + else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown realm option: %s\n", _k); + } + } + } + } + } + free(_realm); + } + } + update_o_to_realm(o_to_realm_new); + mongoc_cursor_destroy(cursor); + } + mongoc_collection_destroy(collection); + bson_destroy(&query); + bson_destroy(&fields); } ///////////////////////////////////////////////// -static int mongo_get_admin_user(const uint8_t *usname, uint8_t *realm, password_t pwd) -{ - mongoc_collection_t * collection = mongo_get_collection("admin_user"); +static int mongo_get_admin_user(const uint8_t *usname, uint8_t *realm, password_t pwd) { + mongoc_collection_t *collection = mongo_get_collection("admin_user"); - if(!collection) + if (!collection) return -1; - realm[0]=0; - pwd[0]=0; + realm[0] = 0; + pwd[0] = 0; - bson_t query; - bson_init(&query); - BSON_APPEND_UTF8(&query, "name", (const char *)usname); + bson_t query; + bson_init(&query); + BSON_APPEND_UTF8(&query, "name", (const char *)usname); - bson_t fields; - bson_init(&fields); - BSON_APPEND_INT32(&fields, "realm", 1); - BSON_APPEND_INT32(&fields, "password", 1); + bson_t fields; + bson_init(&fields); + BSON_APPEND_INT32(&fields, "realm", 1); + BSON_APPEND_INT32(&fields, "password", 1); - mongoc_cursor_t * cursor; - cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 1, 0, &query, &fields, NULL); + mongoc_cursor_t *cursor; + cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 1, 0, &query, &fields, NULL); - int ret = -1; + int ret = -1; - if (!cursor) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'admin_user'\n"); - } else { - const bson_t * item; - uint32_t length; - bson_iter_t iter; - if (mongoc_cursor_next(cursor, &item)) { - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") && BSON_ITER_HOLDS_UTF8(&iter)) { - strncpy((char*)realm,bson_iter_utf8(&iter, &length),STUN_MAX_REALM_SIZE); - ret = 0; - } - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "password") && BSON_ITER_HOLDS_UTF8(&iter)) { - strncpy((char*)pwd,bson_iter_utf8(&iter, &length),STUN_MAX_PWD_SIZE); - ret = 0; - } - } - mongoc_cursor_destroy(cursor); - } - mongoc_collection_destroy(collection); - bson_destroy(&query); - bson_destroy(&fields); - return ret; + if (!cursor) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'admin_user'\n"); + } else { + const bson_t *item; + uint32_t length; + bson_iter_t iter; + if (mongoc_cursor_next(cursor, &item)) { + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") && BSON_ITER_HOLDS_UTF8(&iter)) { + strncpy((char *)realm, bson_iter_utf8(&iter, &length), STUN_MAX_REALM_SIZE); + ret = 0; + } + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "password") && BSON_ITER_HOLDS_UTF8(&iter)) { + strncpy((char *)pwd, bson_iter_utf8(&iter, &length), STUN_MAX_PWD_SIZE); + ret = 0; + } + } + mongoc_cursor_destroy(cursor); + } + mongoc_collection_destroy(collection); + bson_destroy(&query); + bson_destroy(&fields); + return ret; } -static int mongo_set_admin_user(const uint8_t *usname, const uint8_t *realm, const password_t pwd) -{ - mongoc_collection_t * collection = mongo_get_collection("admin_user"); +static int mongo_set_admin_user(const uint8_t *usname, const uint8_t *realm, const password_t pwd) { + mongoc_collection_t *collection = mongo_get_collection("admin_user"); - if(!collection) + if (!collection) return -1; - bson_t query; - bson_init(&query); - BSON_APPEND_UTF8(&query, "name", (const char *)usname); + bson_t query; + bson_init(&query); + BSON_APPEND_UTF8(&query, "name", (const char *)usname); - bson_t doc; - bson_init(&doc); - BSON_APPEND_UTF8(&doc, "name", (const char *)usname); - BSON_APPEND_UTF8(&doc, "realm", (const char *)realm); - BSON_APPEND_UTF8(&doc, "password", (const char *)pwd); + bson_t doc; + bson_init(&doc); + BSON_APPEND_UTF8(&doc, "name", (const char *)usname); + BSON_APPEND_UTF8(&doc, "realm", (const char *)realm); + BSON_APPEND_UTF8(&doc, "password", (const char *)pwd); - int ret = -1; + int ret = -1; - if (!mongoc_collection_update(collection, MONGOC_UPDATE_UPSERT, &query, &doc, NULL, NULL)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating admin user information\n"); - } else { - ret = 0; - } - mongoc_collection_destroy(collection); - bson_destroy(&doc); - bson_destroy(&query); - return ret; + if (!mongoc_collection_update(collection, MONGOC_UPDATE_UPSERT, &query, &doc, NULL, NULL)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating admin user information\n"); + } else { + ret = 0; + } + mongoc_collection_destroy(collection); + bson_destroy(&doc); + bson_destroy(&query); + return ret; } -static int mongo_del_admin_user(const uint8_t *usname) -{ - mongoc_collection_t * collection = mongo_get_collection("admin_user"); +static int mongo_del_admin_user(const uint8_t *usname) { + mongoc_collection_t *collection = mongo_get_collection("admin_user"); - if(!collection) - return -1; + if (!collection) + return -1; - bson_t query; - bson_init(&query); - BSON_APPEND_UTF8(&query, "name", (const char *)usname); + bson_t query; + bson_init(&query); + BSON_APPEND_UTF8(&query, "name", (const char *)usname); - int ret = -1; + int ret = -1; - if (!mongoc_collection_delete(collection, MONGOC_DELETE_SINGLE_REMOVE, &query, NULL, NULL)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error deleting admin user information\n"); - } else { - ret = 0; - } - mongoc_collection_destroy(collection); - bson_destroy(&query); - return ret; + if (!mongoc_collection_delete(collection, MONGOC_DELETE_SINGLE_REMOVE, &query, NULL, NULL)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error deleting admin user information\n"); + } else { + ret = 0; + } + mongoc_collection_destroy(collection); + bson_destroy(&query); + return ret; } -static int mongo_list_admin_users(int no_print) -{ - const char * collection_name = "admin_user"; - mongoc_collection_t * collection = mongo_get_collection(collection_name); +static int mongo_list_admin_users(int no_print) { + const char *collection_name = "admin_user"; + mongoc_collection_t *collection = mongo_get_collection(collection_name); - if(!collection) - return -1; + if (!collection) + return -1; - bson_t query, child; - bson_init(&query); - bson_append_document_begin(&query, "$orderby", -1, &child); - bson_append_int32(&child, "name", -1, 1); - bson_append_document_end(&query, &child); - bson_append_document_begin(&query, "$query", -1, &child); - bson_append_document_end(&query, &child); + bson_t query, child; + bson_init(&query); + bson_append_document_begin(&query, "$orderby", -1, &child); + bson_append_int32(&child, "name", -1, 1); + bson_append_document_end(&query, &child); + bson_append_document_begin(&query, "$query", -1, &child); + bson_append_document_end(&query, &child); - bson_t fields; - bson_init(&fields); - BSON_APPEND_INT32(&fields, "name", 1); - BSON_APPEND_INT32(&fields, "realm", 1); + bson_t fields; + bson_init(&fields); + BSON_APPEND_INT32(&fields, "name", 1); + BSON_APPEND_INT32(&fields, "realm", 1); - mongoc_cursor_t * cursor; - cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, &fields, NULL); + mongoc_cursor_t *cursor; + cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, &fields, NULL); - int ret = -1; + int ret = -1; - if (!cursor) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection '%s'\n", collection_name); - } else { - const bson_t * item; - uint32_t length; - bson_iter_t iter; - bson_iter_t iter_realm; - const char * value; - ret = 0; - while (mongoc_cursor_next(cursor, &item)) { - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "name") && BSON_ITER_HOLDS_UTF8(&iter)) { - value = bson_iter_utf8(&iter, &length); - if (length) { - const char *realm = ""; - if (bson_iter_init(&iter_realm, item) && bson_iter_find(&iter_realm, "realm") && BSON_ITER_HOLDS_UTF8(&iter_realm)) { - realm = bson_iter_utf8(&iter_realm, &length); - } - ++ret; - if(!no_print) { - if(realm && *realm) { - printf("%s[%s]\n", value, realm); - } else { - printf("%s\n", value); - } - } - } - } - } - mongoc_cursor_destroy(cursor); - } - mongoc_collection_destroy(collection); - bson_destroy(&query); - bson_destroy(&fields); - return ret; + if (!cursor) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection '%s'\n", collection_name); + } else { + const bson_t *item; + uint32_t length; + bson_iter_t iter; + bson_iter_t iter_realm; + const char *value; + ret = 0; + while (mongoc_cursor_next(cursor, &item)) { + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "name") && BSON_ITER_HOLDS_UTF8(&iter)) { + value = bson_iter_utf8(&iter, &length); + if (length) { + const char *realm = ""; + if (bson_iter_init(&iter_realm, item) && bson_iter_find(&iter_realm, "realm") && + BSON_ITER_HOLDS_UTF8(&iter_realm)) { + realm = bson_iter_utf8(&iter_realm, &length); + } + ++ret; + if (!no_print) { + if (realm && *realm) { + printf("%s[%s]\n", value, realm); + } else { + printf("%s\n", value); + } + } + } + } + } + mongoc_cursor_destroy(cursor); + } + mongoc_collection_destroy(collection); + bson_destroy(&query); + bson_destroy(&fields); + return ret; } static void mongo_disconnect(void) { - MONGO * mongoconnection = (MONGO *) pthread_getspecific(connection_key); - if (mongoconnection) { - MongoFree(mongoconnection); - mongoconnection = NULL; - } - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MongoDB connection was closed.\n"); + MONGO *mongoconnection = (MONGO *)pthread_getspecific(connection_key); + if (mongoconnection) { + MongoFree(mongoconnection); + mongoconnection = NULL; + } + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MongoDB connection was closed.\n"); } ////////////////////////////////////////////////////////// static const turn_dbdriver_t driver = { - &mongo_get_auth_secrets, - &mongo_get_user_key, - &mongo_set_user_key, - &mongo_del_user, - &mongo_list_users, - &mongo_list_secrets, - &mongo_del_secret, - &mongo_set_secret, - &mongo_add_origin, - &mongo_del_origin, - &mongo_list_origins, - &mongo_set_realm_option_one, - &mongo_list_realm_options, - &mongo_auth_ping, - &mongo_get_ip_list, - &mongo_set_permission_ip, - &mongo_reread_realms, - &mongo_set_oauth_key, - &mongo_get_oauth_key, - &mongo_del_oauth_key, - &mongo_list_oauth_keys, - &mongo_get_admin_user, - &mongo_set_admin_user, - &mongo_del_admin_user, - &mongo_list_admin_users, - &mongo_disconnect -}; + &mongo_get_auth_secrets, &mongo_get_user_key, &mongo_set_user_key, &mongo_del_user, + &mongo_list_users, &mongo_list_secrets, &mongo_del_secret, &mongo_set_secret, + &mongo_add_origin, &mongo_del_origin, &mongo_list_origins, &mongo_set_realm_option_one, + &mongo_list_realm_options, &mongo_auth_ping, &mongo_get_ip_list, &mongo_set_permission_ip, + &mongo_reread_realms, &mongo_set_oauth_key, &mongo_get_oauth_key, &mongo_del_oauth_key, + &mongo_list_oauth_keys, &mongo_get_admin_user, &mongo_set_admin_user, &mongo_del_admin_user, + &mongo_list_admin_users, &mongo_disconnect}; -const turn_dbdriver_t * get_mongo_dbdriver(void) { - return &driver; -} +const turn_dbdriver_t *get_mongo_dbdriver(void) { return &driver; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// #else -const turn_dbdriver_t * get_mongo_dbdriver(void) { - return NULL; -} +const turn_dbdriver_t *get_mongo_dbdriver(void) { return NULL; } #endif diff --git a/src/apps/relay/dbdrivers/dbd_mongo.h b/src/apps/relay/dbdrivers/dbd_mongo.h index 862881b..1bc4da8 100644 --- a/src/apps/relay/dbdrivers/dbd_mongo.h +++ b/src/apps/relay/dbdrivers/dbd_mongo.h @@ -38,7 +38,7 @@ extern "C" { #endif -const turn_dbdriver_t * get_mongo_dbdriver(void); +const turn_dbdriver_t *get_mongo_dbdriver(void); #ifdef __cplusplus } @@ -46,4 +46,3 @@ const turn_dbdriver_t * get_mongo_dbdriver(void); #endif /// __DBD_MONGODB__/// - diff --git a/src/apps/relay/dbdrivers/dbd_mysql.c b/src/apps/relay/dbdrivers/dbd_mysql.c index 8e0e4ba..c1d2778 100644 --- a/src/apps/relay/dbdrivers/dbd_mysql.c +++ b/src/apps/relay/dbdrivers/dbd_mysql.c @@ -29,1289 +29,1281 @@ * SUCH DAMAGE. */ -#include "../mainrelay.h" #include "dbd_mysql.h" +#include "../mainrelay.h" #if !defined(TURN_NO_MYSQL) #include - /////////////////////////////////////////////////////////////////////////////////////////////////////////// static int donot_print_connection_success = 0; struct _Myconninfo { - char *host; - char *dbname; - char *user; - char *password; - unsigned int port; - unsigned int connect_timeout; - unsigned int read_timeout; - /* SSL ==>> */ - char *key; - char *ca; - char *cert; - char *capath; - char *cipher; - /* <<== SSL : see http://dev.mysql.com/doc/refman/5.0/en/mysql-ssl-set.html */ + char *host; + char *dbname; + char *user; + char *password; + unsigned int port; + unsigned int connect_timeout; + unsigned int read_timeout; + /* SSL ==>> */ + char *key; + char *ca; + char *cert; + char *capath; + char *cipher; + /* <<== SSL : see http://dev.mysql.com/doc/refman/5.0/en/mysql-ssl-set.html */ }; typedef struct _Myconninfo Myconninfo; static void MyconninfoFree(Myconninfo *co) { - if(co) { - if(co->host) free(co->host); - if(co->dbname) free(co->dbname); - if(co->user) free(co->user); - if(co->password) free(co->password); - if(co->key) free(co->key); - if(co->ca) free(co->ca); - if(co->cert) free(co->cert); - if(co->capath) free(co->capath); - if(co->cipher) free(co->cipher); - memset(co,0,sizeof(Myconninfo)); - free(co); - } + if (co) { + if (co->host) + free(co->host); + if (co->dbname) + free(co->dbname); + if (co->user) + free(co->user); + if (co->password) + free(co->password); + if (co->key) + free(co->key); + if (co->ca) + free(co->ca); + if (co->cert) + free(co->cert); + if (co->capath) + free(co->capath); + if (co->cipher) + free(co->cipher); + memset(co, 0, sizeof(Myconninfo)); + free(co); + } } -char* decryptPassword(char* in, const unsigned char* mykey){ +char *decryptPassword(char *in, const unsigned char *mykey) { - char *out; - unsigned char iv[8] = {0}; //changed - AES_KEY key; - unsigned char outdata[256]; //changed - AES_set_encrypt_key(mykey, 128, &key); - int newTotalSize=decodedTextSize(in); - int bytes_to_decode = strlen(in); - unsigned char *encryptedText = base64decode(in, bytes_to_decode); //changed - char last[1024]=""; - struct ctr_state state; - init_ctr(&state, iv); - memset(outdata,'\0', sizeof(outdata)); + char *out; + unsigned char iv[8] = {0}; // changed + AES_KEY key; + unsigned char outdata[256]; // changed + AES_set_encrypt_key(mykey, 128, &key); + int newTotalSize = decodedTextSize(in); + int bytes_to_decode = strlen(in); + unsigned char *encryptedText = base64decode(in, bytes_to_decode); // changed + char last[1024] = ""; + struct ctr_state state; + init_ctr(&state, iv); + memset(outdata, '\0', sizeof(outdata)); #if OPENSSL_VERSION_NUMBER >= 0x10100000L - CRYPTO_ctr128_encrypt(encryptedText, outdata, newTotalSize, &key, state.ivec, state.ecount, &state.num,(block128_f)AES_encrypt); + CRYPTO_ctr128_encrypt(encryptedText, outdata, newTotalSize, &key, state.ivec, state.ecount, &state.num, + (block128_f)AES_encrypt); #else - AES_ctr128_encrypt(encryptedText, outdata, newTotalSize, &key, state.ivec, state.ecount, &state.num); + AES_ctr128_encrypt(encryptedText, outdata, newTotalSize, &key, state.ivec, state.ecount, &state.num); #endif - strcat(last,(char*)outdata); - out=(char*)malloc(sizeof(char)*strlen(last)); - strcpy(out,last); - return out; + strcat(last, (char *)outdata); + out = (char *)malloc(sizeof(char) * strlen(last)); + strcpy(out, last); + return out; } - static Myconninfo *MyconninfoParse(char *userdb, char **errmsg) { - Myconninfo *co = (Myconninfo*)malloc(sizeof(Myconninfo)); - memset(co,0,sizeof(Myconninfo)); - if(userdb) { - char *s0=strdup(userdb); - char *s = s0; + Myconninfo *co = (Myconninfo *)malloc(sizeof(Myconninfo)); + memset(co, 0, sizeof(Myconninfo)); + if (userdb) { + char *s0 = strdup(userdb); + char *s = s0; - while(s && *s) { + while (s && *s) { - while(*s && (*s==' ')) ++s; - char *snext = strstr(s," "); - if(snext) { - *snext = 0; - ++snext; - } + while (*s && (*s == ' ')) + ++s; + char *snext = strstr(s, " "); + if (snext) { + *snext = 0; + ++snext; + } - char* seq = strstr(s,"="); - if(!seq) { - MyconninfoFree(co); - co = NULL; - if(errmsg) { - *errmsg = strdup(s); - } - break; - } + char *seq = strstr(s, "="); + if (!seq) { + MyconninfoFree(co); + co = NULL; + if (errmsg) { + *errmsg = strdup(s); + } + break; + } - *seq = 0; - if(!strcmp(s,"host")) - co->host = strdup(seq+1); - else if(!strcmp(s,"ip")) - co->host = strdup(seq+1); - else if(!strcmp(s,"addr")) - co->host = strdup(seq+1); - else if(!strcmp(s,"ipaddr")) - co->host = strdup(seq+1); - else if(!strcmp(s,"hostaddr")) - co->host = strdup(seq+1); - else if(!strcmp(s,"dbname")) - co->dbname = strdup(seq+1); - else if(!strcmp(s,"db")) - co->dbname = strdup(seq+1); - else if(!strcmp(s,"database")) - co->dbname = strdup(seq+1); - else if(!strcmp(s,"user")) - co->user = strdup(seq+1); - else if(!strcmp(s,"uname")) - co->user = strdup(seq+1); - else if(!strcmp(s,"name")) - co->user = strdup(seq+1); - else if(!strcmp(s,"username")) - co->user = strdup(seq+1); - else if(!strcmp(s,"password")) - co->password = strdup(seq+1); - else if(!strcmp(s,"pwd")) - co->password = strdup(seq+1); - else if(!strcmp(s,"passwd")) - co->password = strdup(seq+1); - else if(!strcmp(s,"secret")) - co->password = strdup(seq+1); - else if(!strcmp(s,"port")) - co->port = (unsigned int)atoi(seq+1); - else if(!strcmp(s,"p")) - co->port = (unsigned int)atoi(seq+1); - else if(!strcmp(s,"connect_timeout")) - co->connect_timeout = (unsigned int)atoi(seq+1); - else if(!strcmp(s,"timeout")) - co->connect_timeout = (unsigned int)atoi(seq+1); - else if(!strcmp(s,"read_timeout")) - co->read_timeout = (unsigned int)atoi(seq+1); - else if(!strcmp(s,"key")) - co->key = strdup(seq+1); - else if(!strcmp(s,"ssl-key")) - co->key = strdup(seq+1); - else if(!strcmp(s,"ca")) - co->ca = strdup(seq+1); - else if(!strcmp(s,"ssl-ca")) - co->ca = strdup(seq+1); - else if(!strcmp(s,"capath")) - co->capath = strdup(seq+1); - else if(!strcmp(s,"ssl-capath")) - co->capath = strdup(seq+1); - else if(!strcmp(s,"cert")) - co->cert = strdup(seq+1); - else if(!strcmp(s,"ssl-cert")) - co->cert = strdup(seq+1); - else if(!strcmp(s,"cipher")) - co->cipher = strdup(seq+1); - else if(!strcmp(s,"ssl-cipher")) - co->cipher = strdup(seq+1); - else { - MyconninfoFree(co); - co = NULL; - if(errmsg) { - *errmsg = strdup(s); - } - break; - } + *seq = 0; + if (!strcmp(s, "host")) + co->host = strdup(seq + 1); + else if (!strcmp(s, "ip")) + co->host = strdup(seq + 1); + else if (!strcmp(s, "addr")) + co->host = strdup(seq + 1); + else if (!strcmp(s, "ipaddr")) + co->host = strdup(seq + 1); + else if (!strcmp(s, "hostaddr")) + co->host = strdup(seq + 1); + else if (!strcmp(s, "dbname")) + co->dbname = strdup(seq + 1); + else if (!strcmp(s, "db")) + co->dbname = strdup(seq + 1); + else if (!strcmp(s, "database")) + co->dbname = strdup(seq + 1); + else if (!strcmp(s, "user")) + co->user = strdup(seq + 1); + else if (!strcmp(s, "uname")) + co->user = strdup(seq + 1); + else if (!strcmp(s, "name")) + co->user = strdup(seq + 1); + else if (!strcmp(s, "username")) + co->user = strdup(seq + 1); + else if (!strcmp(s, "password")) + co->password = strdup(seq + 1); + else if (!strcmp(s, "pwd")) + co->password = strdup(seq + 1); + else if (!strcmp(s, "passwd")) + co->password = strdup(seq + 1); + else if (!strcmp(s, "secret")) + co->password = strdup(seq + 1); + else if (!strcmp(s, "port")) + co->port = (unsigned int)atoi(seq + 1); + else if (!strcmp(s, "p")) + co->port = (unsigned int)atoi(seq + 1); + else if (!strcmp(s, "connect_timeout")) + co->connect_timeout = (unsigned int)atoi(seq + 1); + else if (!strcmp(s, "timeout")) + co->connect_timeout = (unsigned int)atoi(seq + 1); + else if (!strcmp(s, "read_timeout")) + co->read_timeout = (unsigned int)atoi(seq + 1); + else if (!strcmp(s, "key")) + co->key = strdup(seq + 1); + else if (!strcmp(s, "ssl-key")) + co->key = strdup(seq + 1); + else if (!strcmp(s, "ca")) + co->ca = strdup(seq + 1); + else if (!strcmp(s, "ssl-ca")) + co->ca = strdup(seq + 1); + else if (!strcmp(s, "capath")) + co->capath = strdup(seq + 1); + else if (!strcmp(s, "ssl-capath")) + co->capath = strdup(seq + 1); + else if (!strcmp(s, "cert")) + co->cert = strdup(seq + 1); + else if (!strcmp(s, "ssl-cert")) + co->cert = strdup(seq + 1); + else if (!strcmp(s, "cipher")) + co->cipher = strdup(seq + 1); + else if (!strcmp(s, "ssl-cipher")) + co->cipher = strdup(seq + 1); + else { + MyconninfoFree(co); + co = NULL; + if (errmsg) { + *errmsg = strdup(s); + } + break; + } - s = snext; - } + s = snext; + } - free(s0); - } + free(s0); + } - if(co) { - if(!(co->dbname)) - co->dbname=strdup("0"); - if(!(co->host)) - co->host=strdup("127.0.0.1"); - if(!(co->user)) - co->user=strdup(""); - if(!(co->password)) - co->password=strdup(""); - } + if (co) { + if (!(co->dbname)) + co->dbname = strdup("0"); + if (!(co->host)) + co->host = strdup("127.0.0.1"); + if (!(co->user)) + co->user = strdup(""); + if (!(co->password)) + co->password = strdup(""); + } - return co; + return co; } static MYSQL *get_mydb_connection(void) { - persistent_users_db_t *pud = get_persistent_users_db(); + persistent_users_db_t *pud = get_persistent_users_db(); - MYSQL *mydbconnection = (MYSQL*)pthread_getspecific(connection_key); + MYSQL *mydbconnection = (MYSQL *)pthread_getspecific(connection_key); - if(mydbconnection) { - if(mysql_ping(mydbconnection)) { - mysql_close(mydbconnection); - mydbconnection=NULL; - (void) pthread_setspecific(connection_key, mydbconnection); - } - } + if (mydbconnection) { + if (mysql_ping(mydbconnection)) { + mysql_close(mydbconnection); + mydbconnection = NULL; + (void)pthread_setspecific(connection_key, mydbconnection); + } + } - if(!mydbconnection) { - char *errmsg=NULL; - Myconninfo *co=MyconninfoParse(pud->userdb, &errmsg); - if(!co) { - if(errmsg) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open MySQL DB connection <%s>, connection string format error: %s\n",pud->userdb_sanitized,errmsg); - free(errmsg); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open MySQL DB connection <%s>, connection string format error\n",pud->userdb_sanitized); - } - } else if(errmsg) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open MySQL DB connection <%s>, connection string format error: %s\n",pud->userdb_sanitized,errmsg); - free(errmsg); - MyconninfoFree(co); - } else if(!(co->dbname)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "MySQL Database name is not provided: <%s>\n",pud->userdb_sanitized); - MyconninfoFree(co); - } else { - mydbconnection = mysql_init(NULL); - if(!mydbconnection) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot initialize MySQL DB connection\n"); - } else { - if(co->connect_timeout) - mysql_options(mydbconnection,MYSQL_OPT_CONNECT_TIMEOUT,&(co->connect_timeout)); - if(co->read_timeout) - mysql_options(mydbconnection,MYSQL_OPT_READ_TIMEOUT,&(co->read_timeout)); - if(co->ca || co->capath || co->cert || co->cipher || co->key) { - mysql_ssl_set(mydbconnection, co->key, co->cert, co->ca, co->capath, co->cipher); - } + if (!mydbconnection) { + char *errmsg = NULL; + Myconninfo *co = MyconninfoParse(pud->userdb, &errmsg); + if (!co) { + if (errmsg) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, + "Cannot open MySQL DB connection <%s>, connection string format error: %s\n", + pud->userdb_sanitized, errmsg); + free(errmsg); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open MySQL DB connection <%s>, connection string format error\n", + pud->userdb_sanitized); + } + } else if (errmsg) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open MySQL DB connection <%s>, connection string format error: %s\n", + pud->userdb_sanitized, errmsg); + free(errmsg); + MyconninfoFree(co); + } else if (!(co->dbname)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "MySQL Database name is not provided: <%s>\n", pud->userdb_sanitized); + MyconninfoFree(co); + } else { + mydbconnection = mysql_init(NULL); + if (!mydbconnection) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot initialize MySQL DB connection\n"); + } else { + if (co->connect_timeout) + mysql_options(mydbconnection, MYSQL_OPT_CONNECT_TIMEOUT, &(co->connect_timeout)); + if (co->read_timeout) + mysql_options(mydbconnection, MYSQL_OPT_READ_TIMEOUT, &(co->read_timeout)); + if (co->ca || co->capath || co->cert || co->cipher || co->key) { + mysql_ssl_set(mydbconnection, co->key, co->cert, co->ca, co->capath, co->cipher); + } - if(turn_params.secret_key_file[0]){ - co->password = decryptPassword(co->password, turn_params.secret_key); - } + if (turn_params.secret_key_file[0]) { + co->password = decryptPassword(co->password, turn_params.secret_key); + } - MYSQL *conn = mysql_real_connect(mydbconnection, co->host, co->user, co->password, co->dbname, co->port, NULL, CLIENT_IGNORE_SIGPIPE); - if(!conn) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open MySQL DB connection: <%s>, runtime error\n",pud->userdb_sanitized); - mysql_close(mydbconnection); - mydbconnection=NULL; - } else if(mysql_select_db(mydbconnection, co->dbname)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot connect to MySQL DB: %s\n",co->dbname); - mysql_close(mydbconnection); - mydbconnection=NULL; - } else if(!donot_print_connection_success) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MySQL DB connection success: %s\n",pud->userdb_sanitized); - if(turn_params.secret_key_file[0]) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Encryption with AES is activated.\n"); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Connection is secure.\n"); - } - else - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Connection is not secure.\n"); - donot_print_connection_success = 1; - } - } - MyconninfoFree(co); - } - if(mydbconnection) { - (void) pthread_setspecific(connection_key, mydbconnection); - } - } - return mydbconnection; + MYSQL *conn = mysql_real_connect(mydbconnection, co->host, co->user, co->password, co->dbname, co->port, NULL, + CLIENT_IGNORE_SIGPIPE); + if (!conn) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open MySQL DB connection: <%s>, runtime error\n", + pud->userdb_sanitized); + mysql_close(mydbconnection); + mydbconnection = NULL; + } else if (mysql_select_db(mydbconnection, co->dbname)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot connect to MySQL DB: %s\n", co->dbname); + mysql_close(mydbconnection); + mydbconnection = NULL; + } else if (!donot_print_connection_success) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MySQL DB connection success: %s\n", pud->userdb_sanitized); + if (turn_params.secret_key_file[0]) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Encryption with AES is activated.\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Connection is secure.\n"); + } else + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Connection is not secure.\n"); + donot_print_connection_success = 1; + } + } + MyconninfoFree(co); + } + if (mydbconnection) { + (void)pthread_setspecific(connection_key, mydbconnection); + } + } + return mydbconnection; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// static int mysql_get_auth_secrets(secrets_list_t *sl, uint8_t *realm) { int ret = -1; - MYSQL * myc = get_mydb_connection(); - if(myc) { - char statement[TURN_LONG_STRING_SIZE]; - snprintf(statement,sizeof(statement)-1,"select value from turn_secret where realm='%s'",realm); - int res = mysql_query(myc, statement); - if(res) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else { - MYSQL_RES *mres = mysql_store_result(myc); - if(!mres) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else if(mysql_field_count(myc)==1) { - for(;;) { - MYSQL_ROW row = mysql_fetch_row(mres); - if(!row) { - break; - } else { - if(row[0]) { - unsigned long *lengths = mysql_fetch_lengths(mres); - if(lengths) { - size_t sz = lengths[0]; - char auth_secret[TURN_LONG_STRING_SIZE]; - memcpy(auth_secret,row[0],sz); - auth_secret[sz]=0; - add_to_secrets_list(sl,auth_secret); - } - } - } - } - ret = 0; - } + MYSQL *myc = get_mydb_connection(); + if (myc) { + char statement[TURN_LONG_STRING_SIZE]; + snprintf(statement, sizeof(statement) - 1, "select value from turn_secret where realm='%s'", realm); + int res = mysql_query(myc, statement); + if (res) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else { + MYSQL_RES *mres = mysql_store_result(myc); + if (!mres) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else if (mysql_field_count(myc) == 1) { + for (;;) { + MYSQL_ROW row = mysql_fetch_row(mres); + if (!row) { + break; + } else { + if (row[0]) { + unsigned long *lengths = mysql_fetch_lengths(mres); + if (lengths) { + size_t sz = lengths[0]; + char auth_secret[TURN_LONG_STRING_SIZE]; + memcpy(auth_secret, row[0], sz); + auth_secret[sz] = 0; + add_to_secrets_list(sl, auth_secret); + } + } + } + } + ret = 0; + } - if(mres) - mysql_free_result(mres); - } - } + if (mres) + mysql_free_result(mres); + } + } return ret; } - + static int mysql_get_user_key(uint8_t *usname, uint8_t *realm, hmackey_t key) { int ret = -1; - MYSQL * myc = get_mydb_connection(); - if(myc) { - char statement[TURN_LONG_STRING_SIZE]; - /* direct user input eliminated - there is no SQL injection problem (since version 4.4.5.3) */ - snprintf(statement,sizeof(statement),"select hmackey from turnusers_lt where name='%s' and realm='%s'",usname,realm); - int res = mysql_query(myc, statement); - if(res) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else { - MYSQL_RES *mres = mysql_store_result(myc); - if(!mres) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else if(mysql_field_count(myc)!=1) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement); - } else { - MYSQL_ROW row = mysql_fetch_row(mres); - if(row && row[0]) { - unsigned long *lengths = mysql_fetch_lengths(mres); - if(lengths) { - size_t sz = get_hmackey_size(SHATYPE_DEFAULT)*2; - if(lengths[0]kid,kid); - memcpy(key->ikm_key,row[0],lengths[0]); - key->ikm_key[lengths[0]]=0; - - char stimestamp[128]; - memcpy(stimestamp,row[1],lengths[1]); - stimestamp[lengths[1]]=0; - key->timestamp = (uint64_t)strtoull(stimestamp,NULL,10); - - char slifetime[128]; - memcpy(slifetime,row[2],lengths[2]); - slifetime[lengths[2]]=0; - key->lifetime = (uint32_t)strtoul(slifetime,NULL,10); - - memcpy(key->as_rs_alg,row[3],lengths[3]); - key->as_rs_alg[lengths[3]]=0; - - memcpy(key->realm,row[4],lengths[4]); - key->realm[lengths[4]]=0; - - ret = 0; - } - } - } - - if(mres) - mysql_free_result(mres); - } - } - return ret; -} - -static int mysql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts,secrets_list_t *realms) { - - oauth_key_data_raw key_; - oauth_key_data_raw *key=&key_; - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,realm,kid from oauth_key order by kid"); - - MYSQL * myc = get_mydb_connection(); - if(myc) { - int res = mysql_query(myc, statement); - if(res) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else { - MYSQL_RES *mres = mysql_store_result(myc); - if(!mres) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else if(mysql_field_count(myc)!=6) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement); - } else { - MYSQL_ROW row = mysql_fetch_row(mres); - while(row) { - unsigned long *lengths = mysql_fetch_lengths(mres); - if(lengths) { - - memcpy(key->ikm_key,row[0],lengths[0]); - key->ikm_key[lengths[0]]=0; - - char stimestamp[128]; - memcpy(stimestamp,row[1],lengths[1]); - stimestamp[lengths[1]]=0; - key->timestamp = (uint64_t)strtoull(stimestamp,NULL,10); - - char slifetime[128]; - memcpy(slifetime,row[2],lengths[2]); - slifetime[lengths[2]]=0; - key->lifetime = (uint32_t)strtoul(slifetime,NULL,10); - - memcpy(key->as_rs_alg,row[3],lengths[3]); - key->as_rs_alg[lengths[3]]=0; - - memcpy(key->realm,row[4],lengths[4]); - key->realm[lengths[4]]=0; - - memcpy(key->kid,row[5],lengths[5]); - key->kid[lengths[5]]=0; - - if(kids) { - add_to_secrets_list(kids,key->kid); - add_to_secrets_list(teas,key->as_rs_alg); - add_to_secrets_list(realms,key->realm); - { - char ts[256]; - snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp); - add_to_secrets_list(tss,ts); - } - { - char lt[256]; - snprintf(lt,sizeof(lt)-1,"%lu",(unsigned long)key->lifetime); - add_to_secrets_list(lts,lt); - } - } else { - printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, realm=%s\n", - key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, - key->as_rs_alg,key->realm); - } - } - row = mysql_fetch_row(mres); - } - } - - if(mres) - mysql_free_result(mres); - } - } - - return ret; -} - -static int mysql_set_user_key(uint8_t *usname, uint8_t *realm, const char *key) -{ int ret = -1; char statement[TURN_LONG_STRING_SIZE]; - MYSQL * myc = get_mydb_connection(); - if(myc) { - snprintf(statement,sizeof(statement),"insert into turnusers_lt (realm,name,hmackey) values('%s','%s','%s')",realm,usname,key); - int res = mysql_query(myc, statement); - if(!res) { - ret = 0; - } else { - snprintf(statement,sizeof(statement),"update turnusers_lt set hmackey='%s' where name='%s' and realm='%s'",key,usname,realm); - res = mysql_query(myc, statement); - if(!res) { - ret = 0; - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating user key information: %s\n",mysql_error(myc)); - } - } + /* direct user input eliminated - there is no SQL injection problem (since version 4.4.5.3) */ + snprintf(statement, sizeof(statement), + "select ikm_key,timestamp,lifetime,as_rs_alg,realm from oauth_key where kid='%s'", (const char *)kid); + + MYSQL *myc = get_mydb_connection(); + if (myc) { + int res = mysql_query(myc, statement); + if (res) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else { + MYSQL_RES *mres = mysql_store_result(myc); + if (!mres) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else if (mysql_field_count(myc) != 5) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n", statement); + } else { + MYSQL_ROW row = mysql_fetch_row(mres); + if (row && row[0]) { + unsigned long *lengths = mysql_fetch_lengths(mres); + if (lengths) { + STRCPY(key->kid, kid); + memcpy(key->ikm_key, row[0], lengths[0]); + key->ikm_key[lengths[0]] = 0; + + char stimestamp[128]; + memcpy(stimestamp, row[1], lengths[1]); + stimestamp[lengths[1]] = 0; + key->timestamp = (uint64_t)strtoull(stimestamp, NULL, 10); + + char slifetime[128]; + memcpy(slifetime, row[2], lengths[2]); + slifetime[lengths[2]] = 0; + key->lifetime = (uint32_t)strtoul(slifetime, NULL, 10); + + memcpy(key->as_rs_alg, row[3], lengths[3]); + key->as_rs_alg[lengths[3]] = 0; + + memcpy(key->realm, row[4], lengths[4]); + key->realm[lengths[4]] = 0; + + ret = 0; + } + } + } + + if (mres) + mysql_free_result(mres); + } } return ret; } -static int mysql_set_oauth_key(oauth_key_data_raw *key) -{ - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - MYSQL * myc = get_mydb_connection(); - if(myc) { - snprintf(statement,sizeof(statement),"insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg,realm) values('%s','%s',%llu,%lu,'%s','%s')", - key->kid,key->ikm_key,(unsigned long long)key->timestamp,(unsigned long)key->lifetime, - key->as_rs_alg,key->realm); - int res = mysql_query(myc, statement); - if(res) { - snprintf(statement,sizeof(statement),"update oauth_key set ikm_key='%s',timestamp=%lu,lifetime=%lu, as_rs_alg='%s', realm='%s' where kid='%s'",key->ikm_key,(unsigned long)key->timestamp,(unsigned long)key->lifetime, - key->as_rs_alg,key->realm,key->kid); - res = mysql_query(myc, statement); - if(res) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating oauth key information: %s\n",mysql_error(myc)); - } else { - ret = 0; - } - } else { - ret = 0; - } - } - return ret; +static int mysql_list_oauth_keys(secrets_list_t *kids, secrets_list_t *teas, secrets_list_t *tss, secrets_list_t *lts, + secrets_list_t *realms) { + + oauth_key_data_raw key_; + oauth_key_data_raw *key = &key_; + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + snprintf(statement, sizeof(statement), + "select ikm_key,timestamp,lifetime,as_rs_alg,realm,kid from oauth_key order by kid"); + + MYSQL *myc = get_mydb_connection(); + if (myc) { + int res = mysql_query(myc, statement); + if (res) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else { + MYSQL_RES *mres = mysql_store_result(myc); + if (!mres) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else if (mysql_field_count(myc) != 6) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n", statement); + } else { + MYSQL_ROW row = mysql_fetch_row(mres); + while (row) { + unsigned long *lengths = mysql_fetch_lengths(mres); + if (lengths) { + + memcpy(key->ikm_key, row[0], lengths[0]); + key->ikm_key[lengths[0]] = 0; + + char stimestamp[128]; + memcpy(stimestamp, row[1], lengths[1]); + stimestamp[lengths[1]] = 0; + key->timestamp = (uint64_t)strtoull(stimestamp, NULL, 10); + + char slifetime[128]; + memcpy(slifetime, row[2], lengths[2]); + slifetime[lengths[2]] = 0; + key->lifetime = (uint32_t)strtoul(slifetime, NULL, 10); + + memcpy(key->as_rs_alg, row[3], lengths[3]); + key->as_rs_alg[lengths[3]] = 0; + + memcpy(key->realm, row[4], lengths[4]); + key->realm[lengths[4]] = 0; + + memcpy(key->kid, row[5], lengths[5]); + key->kid[lengths[5]] = 0; + + if (kids) { + add_to_secrets_list(kids, key->kid); + add_to_secrets_list(teas, key->as_rs_alg); + add_to_secrets_list(realms, key->realm); + { + char ts[256]; + snprintf(ts, sizeof(ts) - 1, "%llu", (unsigned long long)key->timestamp); + add_to_secrets_list(tss, ts); + } + { + char lt[256]; + snprintf(lt, sizeof(lt) - 1, "%lu", (unsigned long)key->lifetime); + add_to_secrets_list(lts, lt); + } + } else { + printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, realm=%s\n", key->kid, + key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->as_rs_alg, + key->realm); + } + } + row = mysql_fetch_row(mres); + } + } + + if (mres) + mysql_free_result(mres); + } + } + + return ret; } - + +static int mysql_set_user_key(uint8_t *usname, uint8_t *realm, const char *key) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + MYSQL *myc = get_mydb_connection(); + if (myc) { + snprintf(statement, sizeof(statement), "insert into turnusers_lt (realm,name,hmackey) values('%s','%s','%s')", + realm, usname, key); + int res = mysql_query(myc, statement); + if (!res) { + ret = 0; + } else { + snprintf(statement, sizeof(statement), "update turnusers_lt set hmackey='%s' where name='%s' and realm='%s'", key, + usname, realm); + res = mysql_query(myc, statement); + if (!res) { + ret = 0; + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating user key information: %s\n", mysql_error(myc)); + } + } + } + return ret; +} + +static int mysql_set_oauth_key(oauth_key_data_raw *key) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + MYSQL *myc = get_mydb_connection(); + if (myc) { + snprintf( + statement, sizeof(statement), + "insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg,realm) values('%s','%s',%llu,%lu,'%s','%s')", + key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->as_rs_alg, + key->realm); + int res = mysql_query(myc, statement); + if (res) { + snprintf( + statement, sizeof(statement), + "update oauth_key set ikm_key='%s',timestamp=%lu,lifetime=%lu, as_rs_alg='%s', realm='%s' where kid='%s'", + key->ikm_key, (unsigned long)key->timestamp, (unsigned long)key->lifetime, key->as_rs_alg, key->realm, + key->kid); + res = mysql_query(myc, statement); + if (res) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating oauth key information: %s\n", mysql_error(myc)); + } else { + ret = 0; + } + } else { + ret = 0; + } + } + return ret; +} + static int mysql_del_user(uint8_t *usname, uint8_t *realm) { int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - MYSQL * myc = get_mydb_connection(); - if(myc) { - snprintf(statement,sizeof(statement),"delete from turnusers_lt where name='%s' and realm='%s'",usname,realm); - int res = mysql_query(myc, statement); - if(res) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error deleting user key information: %s\n",mysql_error(myc)); - } else { - ret = 0; - } - } + char statement[TURN_LONG_STRING_SIZE]; + MYSQL *myc = get_mydb_connection(); + if (myc) { + snprintf(statement, sizeof(statement), "delete from turnusers_lt where name='%s' and realm='%s'", usname, realm); + int res = mysql_query(myc, statement); + if (res) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error deleting user key information: %s\n", mysql_error(myc)); + } else { + ret = 0; + } + } return ret; } static int mysql_del_oauth_key(const uint8_t *kid) { - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - MYSQL * myc = get_mydb_connection(); - if(myc) { - snprintf(statement,sizeof(statement),"delete from oauth_key where kid = '%s'",(const char*)kid); - int res = mysql_query(myc, statement); - if(res) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error deleting oauth key information: %s\n",mysql_error(myc)); - } else { - ret = 0; - } - } - return ret; -} - -static int mysql_list_users(uint8_t *realm, secrets_list_t *users, secrets_list_t *realms) -{ - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - - uint8_t realm0[STUN_MAX_REALM_SIZE+1] = "\0"; - if(!realm) realm=realm0; - - MYSQL * myc = get_mydb_connection(); - if(myc) { - if(realm[0]) { - snprintf(statement,sizeof(statement),"select name, realm from turnusers_lt where realm='%s' order by name",realm); - } else { - snprintf(statement,sizeof(statement),"select name, realm from turnusers_lt order by realm,name"); - } - int res = mysql_query(myc, statement); - if(res) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else { - MYSQL_RES *mres = mysql_store_result(myc); - if(!mres) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else if(mysql_field_count(myc)!=2) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement); - } else { - for(;;) { - MYSQL_ROW row = mysql_fetch_row(mres); - if(!row) { - break; - } else { - if(row[0]) { - if(users) { - add_to_secrets_list(users,row[0]); - if(realms) { - if(row[1]) { - add_to_secrets_list(realms,row[1]); - } else { - add_to_secrets_list(realms,(char*)realm); - } - } - } else { - printf("%s[%s]\n", row[0], row[1]); - } - } - } - } - ret = 0; - } - - if(mres) - mysql_free_result(mres); - } - } + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + MYSQL *myc = get_mydb_connection(); + if (myc) { + snprintf(statement, sizeof(statement), "delete from oauth_key where kid = '%s'", (const char *)kid); + int res = mysql_query(myc, statement); + if (res) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error deleting oauth key information: %s\n", mysql_error(myc)); + } else { + ret = 0; + } + } return ret; } - -static int mysql_list_secrets(uint8_t *realm, secrets_list_t *secrets, secrets_list_t *realms) -{ - int ret = -1; - uint8_t realm0[STUN_MAX_REALM_SIZE+1] = "\0"; - if(!realm) realm=realm0; +static int mysql_list_users(uint8_t *realm, secrets_list_t *users, secrets_list_t *realms) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; - char statement[TURN_LONG_STRING_SIZE]; - if (realm[0]) { - snprintf(statement, sizeof(statement), "select value,realm from turn_secret where realm='%s' order by value", realm); - } else { - snprintf(statement, sizeof(statement), "select value,realm from turn_secret order by realm,value"); - } + uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0"; + if (!realm) + realm = realm0; - donot_print_connection_success=1; + MYSQL *myc = get_mydb_connection(); + if (myc) { + if (realm[0]) { + snprintf(statement, sizeof(statement), "select name, realm from turnusers_lt where realm='%s' order by name", + realm); + } else { + snprintf(statement, sizeof(statement), "select name, realm from turnusers_lt order by realm,name"); + } + int res = mysql_query(myc, statement); + if (res) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else { + MYSQL_RES *mres = mysql_store_result(myc); + if (!mres) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else if (mysql_field_count(myc) != 2) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n", statement); + } else { + for (;;) { + MYSQL_ROW row = mysql_fetch_row(mres); + if (!row) { + break; + } else { + if (row[0]) { + if (users) { + add_to_secrets_list(users, row[0]); + if (realms) { + if (row[1]) { + add_to_secrets_list(realms, row[1]); + } else { + add_to_secrets_list(realms, (char *)realm); + } + } + } else { + printf("%s[%s]\n", row[0], row[1]); + } + } + } + } + ret = 0; + } - MYSQL * myc = get_mydb_connection(); - if(myc) { - int res = mysql_query(myc, statement); - if(res) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else { - MYSQL_RES *mres = mysql_store_result(myc); - if(!mres) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else if(mysql_field_count(myc)!=2) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement); - } else { - for(;;) { - MYSQL_ROW row = mysql_fetch_row(mres); - if(!row) { - break; - } else { - const char* kval = row[0]; - if(kval) { - const char* rval = row[1]; - if(secrets) { - add_to_secrets_list(secrets,kval); - if(realms) { - if(rval && *rval) { - add_to_secrets_list(realms,rval); - } else { - add_to_secrets_list(realms,(char*)realm); - } - } - } else { - printf("%s[%s]\n",kval,rval); - } - } - } - } - ret = 0; - } - - if(mres) - mysql_free_result(mres); - } - } - return ret; + if (mres) + mysql_free_result(mres); + } + } + return ret; } - + +static int mysql_list_secrets(uint8_t *realm, secrets_list_t *secrets, secrets_list_t *realms) { + int ret = -1; + + uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0"; + if (!realm) + realm = realm0; + + char statement[TURN_LONG_STRING_SIZE]; + if (realm[0]) { + snprintf(statement, sizeof(statement), "select value,realm from turn_secret where realm='%s' order by value", + realm); + } else { + snprintf(statement, sizeof(statement), "select value,realm from turn_secret order by realm,value"); + } + + donot_print_connection_success = 1; + + MYSQL *myc = get_mydb_connection(); + if (myc) { + int res = mysql_query(myc, statement); + if (res) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else { + MYSQL_RES *mres = mysql_store_result(myc); + if (!mres) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else if (mysql_field_count(myc) != 2) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n", statement); + } else { + for (;;) { + MYSQL_ROW row = mysql_fetch_row(mres); + if (!row) { + break; + } else { + const char *kval = row[0]; + if (kval) { + const char *rval = row[1]; + if (secrets) { + add_to_secrets_list(secrets, kval); + if (realms) { + if (rval && *rval) { + add_to_secrets_list(realms, rval); + } else { + add_to_secrets_list(realms, (char *)realm); + } + } + } else { + printf("%s[%s]\n", kval, rval); + } + } + } + } + ret = 0; + } + + if (mres) + mysql_free_result(mres); + } + } + return ret; +} + static int mysql_del_secret(uint8_t *secret, uint8_t *realm) { int ret = -1; - donot_print_connection_success=1; - char statement[TURN_LONG_STRING_SIZE]; - MYSQL * myc = get_mydb_connection(); - if (myc) { - if(!secret || (secret[0]==0)) - snprintf(statement,sizeof(statement),"delete from turn_secret where realm='%s'",realm); - else - snprintf(statement,sizeof(statement),"delete from turn_secret where value='%s' and realm='%s'",secret,realm); - mysql_query(myc, statement); + donot_print_connection_success = 1; + char statement[TURN_LONG_STRING_SIZE]; + MYSQL *myc = get_mydb_connection(); + if (myc) { + if (!secret || (secret[0] == 0)) + snprintf(statement, sizeof(statement), "delete from turn_secret where realm='%s'", realm); + else + snprintf(statement, sizeof(statement), "delete from turn_secret where value='%s' and realm='%s'", secret, realm); + mysql_query(myc, statement); ret = 0; - } + } return ret; } - + static int mysql_set_secret(uint8_t *secret, uint8_t *realm) { int ret = -1; - donot_print_connection_success = 1; - char statement[TURN_LONG_STRING_SIZE]; - MYSQL * myc = get_mydb_connection(); - if (myc) { - snprintf(statement,sizeof(statement),"insert into turn_secret (realm,value) values('%s','%s')",realm,secret); - int res = mysql_query(myc, statement); - if (res) { - TURN_LOG_FUNC( - TURN_LOG_LEVEL_ERROR, - "Error inserting/updating secret key information: %s\n", - mysql_error(myc)); - } else { - ret = 0; - } - } + donot_print_connection_success = 1; + char statement[TURN_LONG_STRING_SIZE]; + MYSQL *myc = get_mydb_connection(); + if (myc) { + snprintf(statement, sizeof(statement), "insert into turn_secret (realm,value) values('%s','%s')", realm, secret); + int res = mysql_query(myc, statement); + if (res) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating secret key information: %s\n", mysql_error(myc)); + } else { + ret = 0; + } + } return ret; } -static int mysql_set_permission_ip(const char *kind, uint8_t *realm, const char* ip, int del) -{ - int ret = -1; +static int mysql_set_permission_ip(const char *kind, uint8_t *realm, const char *ip, int del) { + int ret = -1; - uint8_t realm0[STUN_MAX_REALM_SIZE+1] = "\0"; - if(!realm) realm=realm0; + uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0"; + if (!realm) + realm = realm0; - donot_print_connection_success = 1; + donot_print_connection_success = 1; - char statement[TURN_LONG_STRING_SIZE]; + char statement[TURN_LONG_STRING_SIZE]; - MYSQL * myc = get_mydb_connection(); - if (myc) { - if(del) { - snprintf(statement, sizeof(statement), "delete from %s_peer_ip where realm = '%s' and ip_range = '%s'", kind, (char*)realm, ip); - } else { - snprintf(statement, sizeof(statement), "insert into %s_peer_ip (realm,ip_range) values('%s','%s')", kind, (char*)realm, ip); - } - int res = mysql_query(myc, statement); - if (res) { - TURN_LOG_FUNC( - TURN_LOG_LEVEL_ERROR, - "Error inserting permission ip information: %s\n", - mysql_error(myc)); - } else { - ret = 0; - } - } - return ret; + MYSQL *myc = get_mydb_connection(); + if (myc) { + if (del) { + snprintf(statement, sizeof(statement), "delete from %s_peer_ip where realm = '%s' and ip_range = '%s'", kind, + (char *)realm, ip); + } else { + snprintf(statement, sizeof(statement), "insert into %s_peer_ip (realm,ip_range) values('%s','%s')", kind, + (char *)realm, ip); + } + int res = mysql_query(myc, statement); + if (res) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting permission ip information: %s\n", mysql_error(myc)); + } else { + ret = 0; + } + } + return ret; } - + static int mysql_add_origin(uint8_t *origin, uint8_t *realm) { int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - MYSQL * myc = get_mydb_connection(); - if (myc) { - snprintf(statement,sizeof(statement),"insert into turn_origin_to_realm (origin,realm) values('%s','%s')",origin,realm); - int res = mysql_query(myc, statement); - if (res) { - TURN_LOG_FUNC( - TURN_LOG_LEVEL_ERROR, - "Error inserting origin information: %s\n", - mysql_error(myc)); - } else { - ret = 0; - } - } + char statement[TURN_LONG_STRING_SIZE]; + MYSQL *myc = get_mydb_connection(); + if (myc) { + snprintf(statement, sizeof(statement), "insert into turn_origin_to_realm (origin,realm) values('%s','%s')", origin, + realm); + int res = mysql_query(myc, statement); + if (res) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting origin information: %s\n", mysql_error(myc)); + } else { + ret = 0; + } + } return ret; } - + static int mysql_del_origin(uint8_t *origin) { int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - MYSQL * myc = get_mydb_connection(); - if (myc) { - snprintf(statement,sizeof(statement),"delete from turn_origin_to_realm where origin='%s'",origin); - int res = mysql_query(myc, statement); - if (res) { - TURN_LOG_FUNC( - TURN_LOG_LEVEL_ERROR, - "Error deleting origin information: %s\n", - mysql_error(myc)); - } else { - ret = 0; - } - } + char statement[TURN_LONG_STRING_SIZE]; + MYSQL *myc = get_mydb_connection(); + if (myc) { + snprintf(statement, sizeof(statement), "delete from turn_origin_to_realm where origin='%s'", origin); + int res = mysql_query(myc, statement); + if (res) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error deleting origin information: %s\n", mysql_error(myc)); + } else { + ret = 0; + } + } return ret; } - -static int mysql_list_origins(uint8_t *realm, secrets_list_t *origins, secrets_list_t *realms) -{ - int ret = -1; - uint8_t realm0[STUN_MAX_REALM_SIZE+1] = "\0"; - if(!realm) realm=realm0; - - donot_print_connection_success = 1; - - MYSQL * myc = get_mydb_connection(); - if(myc) { - char statement[TURN_LONG_STRING_SIZE]; - if(realm && realm[0]) { - snprintf(statement,sizeof(statement),"select origin,realm from turn_origin_to_realm where realm='%s' order by origin",realm); - } else { - snprintf(statement,sizeof(statement),"select origin,realm from turn_origin_to_realm order by realm,origin"); - } - int res = mysql_query(myc, statement); - if(res) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else { - MYSQL_RES *mres = mysql_store_result(myc); - if(!mres) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else if(mysql_field_count(myc)!=2) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement); - } else { - for(;;) { - MYSQL_ROW row = mysql_fetch_row(mres); - if(!row) { - break; - } else { - if(row[0] && row[1]) { - const char* kval = row[0]; - const char* rval = row[1]; - if(origins) { - add_to_secrets_list(origins,kval); - if(realms) { - if(rval && *rval) { - add_to_secrets_list(realms,rval); - } else { - add_to_secrets_list(realms,(char*)realm); - } - } - } else { - printf("%s ==>> %s\n",kval,rval); - } - } - } - } - ret = 0; - } - - if(mres) - mysql_free_result(mres); - } - } - return ret; -} - -static int mysql_set_realm_option_one(uint8_t *realm, unsigned long value, const char* opt) { +static int mysql_list_origins(uint8_t *realm, secrets_list_t *origins, secrets_list_t *realms) { int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - MYSQL * myc = get_mydb_connection(); - if (myc) { - { - snprintf(statement,sizeof(statement),"delete from turn_realm_option where realm='%s' and opt='%s'",realm,opt); - mysql_query(myc, statement); - } - if(value>0) { - snprintf(statement,sizeof(statement),"insert into turn_realm_option (realm,opt,value) values('%s','%s','%lu')",realm,opt,(unsigned long)value); - int res = mysql_query(myc, statement); - if (res) { - TURN_LOG_FUNC( - TURN_LOG_LEVEL_ERROR, - "Error inserting realm option information: %s\n", - mysql_error(myc)); - } else { - ret = 0; - } - } - } + + uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0"; + if (!realm) + realm = realm0; + + donot_print_connection_success = 1; + + MYSQL *myc = get_mydb_connection(); + if (myc) { + char statement[TURN_LONG_STRING_SIZE]; + if (realm && realm[0]) { + snprintf(statement, sizeof(statement), + "select origin,realm from turn_origin_to_realm where realm='%s' order by origin", realm); + } else { + snprintf(statement, sizeof(statement), "select origin,realm from turn_origin_to_realm order by realm,origin"); + } + int res = mysql_query(myc, statement); + if (res) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else { + MYSQL_RES *mres = mysql_store_result(myc); + if (!mres) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else if (mysql_field_count(myc) != 2) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n", statement); + } else { + for (;;) { + MYSQL_ROW row = mysql_fetch_row(mres); + if (!row) { + break; + } else { + if (row[0] && row[1]) { + const char *kval = row[0]; + const char *rval = row[1]; + if (origins) { + add_to_secrets_list(origins, kval); + if (realms) { + if (rval && *rval) { + add_to_secrets_list(realms, rval); + } else { + add_to_secrets_list(realms, (char *)realm); + } + } + } else { + printf("%s ==>> %s\n", kval, rval); + } + } + } + } + ret = 0; + } + + if (mres) + mysql_free_result(mres); + } + } return ret; } - + +static int mysql_set_realm_option_one(uint8_t *realm, unsigned long value, const char *opt) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + MYSQL *myc = get_mydb_connection(); + if (myc) { + { + snprintf(statement, sizeof(statement), "delete from turn_realm_option where realm='%s' and opt='%s'", realm, opt); + mysql_query(myc, statement); + } + if (value > 0) { + snprintf(statement, sizeof(statement), "insert into turn_realm_option (realm,opt,value) values('%s','%s','%lu')", + realm, opt, (unsigned long)value); + int res = mysql_query(myc, statement); + if (res) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting realm option information: %s\n", mysql_error(myc)); + } else { + ret = 0; + } + } + } + return ret; +} + static int mysql_list_realm_options(uint8_t *realm) { int ret = -1; - donot_print_connection_success = 1; - char statement[TURN_LONG_STRING_SIZE]; - MYSQL * myc = get_mydb_connection(); - if(myc) { - if(realm && realm[0]) { - snprintf(statement,sizeof(statement),"select realm,opt,value from turn_realm_option where realm='%s' order by realm,opt",realm); - } else { - snprintf(statement,sizeof(statement),"select realm,opt,value from turn_realm_option order by realm,opt"); - } - int res = mysql_query(myc, statement); - if(res) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else { - MYSQL_RES *mres = mysql_store_result(myc); - if(!mres) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else if(mysql_field_count(myc)!=3) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement); - } else { - for(;;) { - MYSQL_ROW row = mysql_fetch_row(mres); - if(!row) { - break; - } else { - if(row[0] && row[1] && row[2]) { - printf("%s[%s]=%s\n",row[1],row[0],row[2]); - } - } - } + donot_print_connection_success = 1; + char statement[TURN_LONG_STRING_SIZE]; + MYSQL *myc = get_mydb_connection(); + if (myc) { + if (realm && realm[0]) { + snprintf(statement, sizeof(statement), + "select realm,opt,value from turn_realm_option where realm='%s' order by realm,opt", realm); + } else { + snprintf(statement, sizeof(statement), "select realm,opt,value from turn_realm_option order by realm,opt"); + } + int res = mysql_query(myc, statement); + if (res) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else { + MYSQL_RES *mres = mysql_store_result(myc); + if (!mres) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else if (mysql_field_count(myc) != 3) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n", statement); + } else { + for (;;) { + MYSQL_ROW row = mysql_fetch_row(mres); + if (!row) { + break; + } else { + if (row[0] && row[1] && row[2]) { + printf("%s[%s]=%s\n", row[1], row[0], row[2]); + } + } + } ret = 0; - } + } - if(mres) - mysql_free_result(mres); - } - } + if (mres) + mysql_free_result(mres); + } + } return ret; } - -static void mysql_auth_ping(void * rch) { - UNUSED_ARG(rch); - MYSQL * myc = get_mydb_connection(); - if(myc) { - char statement[TURN_LONG_STRING_SIZE]; - STRCPY(statement,"select value from turn_secret"); - int res = mysql_query(myc, statement); - if(res) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else { - MYSQL_RES *mres = mysql_store_result(myc); - if(!mres) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else { - mysql_free_result(mres); - } - } - } + +static void mysql_auth_ping(void *rch) { + UNUSED_ARG(rch); + MYSQL *myc = get_mydb_connection(); + if (myc) { + char statement[TURN_LONG_STRING_SIZE]; + STRCPY(statement, "select value from turn_secret"); + int res = mysql_query(myc, statement); + if (res) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else { + MYSQL_RES *mres = mysql_store_result(myc); + if (!mres) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else { + mysql_free_result(mres); + } + } + } } - -static int mysql_get_ip_list(const char *kind, ip_range_list_t * list) { + +static int mysql_get_ip_list(const char *kind, ip_range_list_t *list) { int ret = -1; - MYSQL * myc = get_mydb_connection(); - if(myc) { - char statement[TURN_LONG_STRING_SIZE]; - snprintf(statement,sizeof(statement),"select ip_range,realm from %s_peer_ip",kind); - int res = mysql_query(myc, statement); + MYSQL *myc = get_mydb_connection(); + if (myc) { + char statement[TURN_LONG_STRING_SIZE]; + snprintf(statement, sizeof(statement), "select ip_range,realm from %s_peer_ip", kind); + int res = mysql_query(myc, statement); - if(res) { - static int wrong_table_reported = 0; - if(!wrong_table_reported) { - wrong_table_reported = 1; - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information; probably, the tables 'allowed_peer_ip' and/or 'denied_peer_ip' have to be upgraded to include the realm column.\n"); - } - snprintf(statement, sizeof(statement), "select ip_range,'' from %s_peer_ip", kind); - res = mysql_query(myc, statement); - } + if (res) { + static int wrong_table_reported = 0; + if (!wrong_table_reported) { + wrong_table_reported = 1; + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, + "Error retrieving MySQL DB information; probably, the tables 'allowed_peer_ip' and/or " + "'denied_peer_ip' have to be upgraded to include the realm column.\n"); + } + snprintf(statement, sizeof(statement), "select ip_range,'' from %s_peer_ip", kind); + res = mysql_query(myc, statement); + } - if(res == 0) { - MYSQL_RES *mres = mysql_store_result(myc); - if(mres && mysql_field_count(myc)==2) { - for(;;) { - MYSQL_ROW row = mysql_fetch_row(mres); - if(!row) { - break; - } else { - if(row[0]) { - unsigned long *lengths = mysql_fetch_lengths(mres); - if(lengths) { - size_t sz = lengths[0]; - char kval[TURN_LONG_STRING_SIZE]; - memcpy(kval,row[0],sz); - kval[sz]=0; - sz = lengths[1]; - char rval[TURN_LONG_STRING_SIZE]; - memcpy(rval,row[1],sz); - rval[sz]=0; - add_ip_list_range(kval,rval,list); - } - } - } - } - ret = 0; - } + if (res == 0) { + MYSQL_RES *mres = mysql_store_result(myc); + if (mres && mysql_field_count(myc) == 2) { + for (;;) { + MYSQL_ROW row = mysql_fetch_row(mres); + if (!row) { + break; + } else { + if (row[0]) { + unsigned long *lengths = mysql_fetch_lengths(mres); + if (lengths) { + size_t sz = lengths[0]; + char kval[TURN_LONG_STRING_SIZE]; + memcpy(kval, row[0], sz); + kval[sz] = 0; + sz = lengths[1]; + char rval[TURN_LONG_STRING_SIZE]; + memcpy(rval, row[1], sz); + rval[sz] = 0; + add_ip_list_range(kval, rval, list); + } + } + } + } + ret = 0; + } - if(mres) - mysql_free_result(mres); - } - } + if (mres) + mysql_free_result(mres); + } + } return ret; } - -static void mysql_reread_realms(secrets_list_t * realms_list) { - MYSQL * myc = get_mydb_connection(); - if(myc) { - char statement[TURN_LONG_STRING_SIZE]; - { - snprintf(statement,sizeof(statement),"select origin,realm from turn_origin_to_realm"); - int res = mysql_query(myc, statement); - if(res == 0) { - MYSQL_RES *mres = mysql_store_result(myc); - if(mres && mysql_field_count(myc)==2) { - ur_string_map *o_to_realm_new = ur_string_map_create(free); +static void mysql_reread_realms(secrets_list_t *realms_list) { + MYSQL *myc = get_mydb_connection(); + if (myc) { + char statement[TURN_LONG_STRING_SIZE]; + { + snprintf(statement, sizeof(statement), "select origin,realm from turn_origin_to_realm"); + int res = mysql_query(myc, statement); + if (res == 0) { + MYSQL_RES *mres = mysql_store_result(myc); + if (mres && mysql_field_count(myc) == 2) { - for(;;) { - MYSQL_ROW row = mysql_fetch_row(mres); - if(!row) { - break; - } else { - if(row[0] && row[1]) { - unsigned long *lengths = mysql_fetch_lengths(mres); - if(lengths) { - size_t sz = lengths[0]; - char oval[513]; - memcpy(oval,row[0],sz); - oval[sz]=0; - char *rval=strdup(row[1]); - get_realm(rval); - ur_string_map_value_type value = (ur_string_map_value_type)rval; - ur_string_map_put(o_to_realm_new, (ur_string_map_key_type) oval, value); - } - } - } - } + ur_string_map *o_to_realm_new = ur_string_map_create(free); - update_o_to_realm(o_to_realm_new); - } + for (;;) { + MYSQL_ROW row = mysql_fetch_row(mres); + if (!row) { + break; + } else { + if (row[0] && row[1]) { + unsigned long *lengths = mysql_fetch_lengths(mres); + if (lengths) { + size_t sz = lengths[0]; + char oval[513]; + memcpy(oval, row[0], sz); + oval[sz] = 0; + char *rval = strdup(row[1]); + get_realm(rval); + ur_string_map_value_type value = (ur_string_map_value_type)rval; + ur_string_map_put(o_to_realm_new, (ur_string_map_key_type)oval, value); + } + } + } + } - if(mres) - mysql_free_result(mres); - } - } - { - size_t i = 0; - size_t rlsz = 0; + update_o_to_realm(o_to_realm_new); + } - lock_realms(); - rlsz = realms_list->sz; - unlock_realms(); + if (mres) + mysql_free_result(mres); + } + } + { + size_t i = 0; + size_t rlsz = 0; - for (i = 0; isz; + unlock_realms(); - char *realm = realms_list->secrets[i]; + for (i = 0; i < rlsz; ++i) { - realm_params_t* rp = get_realm(realm); + char *realm = realms_list->secrets[i]; - lock_realms(); - rp->options.perf_options.max_bps = turn_params.max_bps; - unlock_realms(); + realm_params_t *rp = get_realm(realm); - lock_realms(); - rp->options.perf_options.total_quota = turn_params.total_quota; - unlock_realms(); + lock_realms(); + rp->options.perf_options.max_bps = turn_params.max_bps; + unlock_realms(); - lock_realms(); - rp->options.perf_options.user_quota = turn_params.user_quota; - unlock_realms(); + lock_realms(); + rp->options.perf_options.total_quota = turn_params.total_quota; + unlock_realms(); - } - } + lock_realms(); + rp->options.perf_options.user_quota = turn_params.user_quota; + unlock_realms(); + } + } - snprintf(statement,sizeof(statement),"select realm,opt,value from turn_realm_option"); - int res = mysql_query(myc, statement); - if(res == 0) { - MYSQL_RES *mres = mysql_store_result(myc); - if(mres && mysql_field_count(myc)==3) { + snprintf(statement, sizeof(statement), "select realm,opt,value from turn_realm_option"); + int res = mysql_query(myc, statement); + if (res == 0) { + MYSQL_RES *mres = mysql_store_result(myc); + if (mres && mysql_field_count(myc) == 3) { - for(;;) { - MYSQL_ROW row = mysql_fetch_row(mres); - if(!row) { - break; - } else { - if(row[0] && row[1] && row[2]) { - unsigned long *lengths = mysql_fetch_lengths(mres); - if(lengths) { - char rval[513]; - size_t sz = lengths[0]; - memcpy(rval,row[0],sz); - rval[sz]=0; - char oval[513]; - sz = lengths[1]; - memcpy(oval,row[1],sz); - oval[sz]=0; - char vval[513]; - sz = lengths[2]; - memcpy(vval,row[2],sz); - vval[sz]=0; - realm_params_t* rp = get_realm(rval); - if(!strcmp(oval,"max-bps")) - rp->options.perf_options.max_bps = (band_limit_t)strtoul(vval,NULL,10); - else if(!strcmp(oval,"total-quota")) - rp->options.perf_options.total_quota = (vint)atoi(vval); - else if(!strcmp(oval,"user-quota")) - rp->options.perf_options.user_quota = (vint)atoi(vval); - else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown realm option: %s\n", oval); - } - } - } - } - } - } + for (;;) { + MYSQL_ROW row = mysql_fetch_row(mres); + if (!row) { + break; + } else { + if (row[0] && row[1] && row[2]) { + unsigned long *lengths = mysql_fetch_lengths(mres); + if (lengths) { + char rval[513]; + size_t sz = lengths[0]; + memcpy(rval, row[0], sz); + rval[sz] = 0; + char oval[513]; + sz = lengths[1]; + memcpy(oval, row[1], sz); + oval[sz] = 0; + char vval[513]; + sz = lengths[2]; + memcpy(vval, row[2], sz); + vval[sz] = 0; + realm_params_t *rp = get_realm(rval); + if (!strcmp(oval, "max-bps")) + rp->options.perf_options.max_bps = (band_limit_t)strtoul(vval, NULL, 10); + else if (!strcmp(oval, "total-quota")) + rp->options.perf_options.total_quota = (vint)atoi(vval); + else if (!strcmp(oval, "user-quota")) + rp->options.perf_options.user_quota = (vint)atoi(vval); + else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown realm option: %s\n", oval); + } + } + } + } + } + } - if(mres) - mysql_free_result(mres); - } - } + if (mres) + mysql_free_result(mres); + } + } } ///////////////////////////////////////////////////// -static int mysql_get_admin_user(const uint8_t *usname, uint8_t *realm, password_t pwd) -{ +static int mysql_get_admin_user(const uint8_t *usname, uint8_t *realm, password_t pwd) { int ret = -1; - realm[0]=0; - pwd[0]=0; + realm[0] = 0; + pwd[0] = 0; - MYSQL * myc = get_mydb_connection(); - if(myc) { - char statement[TURN_LONG_STRING_SIZE]; - snprintf(statement,sizeof(statement),"select realm,password from admin_user where name='%s'",usname); - int res = mysql_query(myc, statement); - if(res) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else { - MYSQL_RES *mres = mysql_store_result(myc); - if(!mres) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else if(mysql_field_count(myc)!=2) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement); - } else { - MYSQL_ROW row = mysql_fetch_row(mres); - if(row && row[0]) { - strncpy((char*)realm,row[0],STUN_MAX_REALM_SIZE); - strncpy((char*)pwd,row[1],STUN_MAX_PWD_SIZE); - ret = 0; - } - } + MYSQL *myc = get_mydb_connection(); + if (myc) { + char statement[TURN_LONG_STRING_SIZE]; + snprintf(statement, sizeof(statement), "select realm,password from admin_user where name='%s'", usname); + int res = mysql_query(myc, statement); + if (res) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else { + MYSQL_RES *mres = mysql_store_result(myc); + if (!mres) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else if (mysql_field_count(myc) != 2) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n", statement); + } else { + MYSQL_ROW row = mysql_fetch_row(mres); + if (row && row[0]) { + strncpy((char *)realm, row[0], STUN_MAX_REALM_SIZE); + strncpy((char *)pwd, row[1], STUN_MAX_PWD_SIZE); + ret = 0; + } + } - if(mres) - mysql_free_result(mres); - } + if (mres) + mysql_free_result(mres); + } } return ret; } -static int mysql_set_admin_user(const uint8_t *usname, const uint8_t *realm, const password_t pwd) -{ +static int mysql_set_admin_user(const uint8_t *usname, const uint8_t *realm, const password_t pwd) { int ret = -1; char statement[TURN_LONG_STRING_SIZE]; - donot_print_connection_success=1; - MYSQL * myc = get_mydb_connection(); - if(myc) { - snprintf(statement,sizeof(statement),"insert into admin_user (realm,name,password) values('%s','%s','%s')",realm,usname,pwd); - int res = mysql_query(myc, statement); - if(!res) { - ret = 0; - } else { - snprintf(statement,sizeof(statement),"update admin_user set realm='%s',password='%s' where name='%s'",realm,pwd,usname); - res = mysql_query(myc, statement); - if(!res) { - ret = 0; - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating user key information: %s\n",mysql_error(myc)); - } - } + donot_print_connection_success = 1; + MYSQL *myc = get_mydb_connection(); + if (myc) { + snprintf(statement, sizeof(statement), "insert into admin_user (realm,name,password) values('%s','%s','%s')", realm, + usname, pwd); + int res = mysql_query(myc, statement); + if (!res) { + ret = 0; + } else { + snprintf(statement, sizeof(statement), "update admin_user set realm='%s',password='%s' where name='%s'", realm, + pwd, usname); + res = mysql_query(myc, statement); + if (!res) { + ret = 0; + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating user key information: %s\n", mysql_error(myc)); + } + } } return ret; } -static int mysql_del_admin_user(const uint8_t *usname) -{ - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - donot_print_connection_success=1; - MYSQL * myc = get_mydb_connection(); - if(myc) { - snprintf(statement,sizeof(statement),"delete from admin_user where name='%s'",usname); - int res = mysql_query(myc, statement); - if(res) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error deleting admin user information: %s\n",mysql_error(myc)); - } else { - ret = 0; - } - } - return ret; +static int mysql_del_admin_user(const uint8_t *usname) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + donot_print_connection_success = 1; + MYSQL *myc = get_mydb_connection(); + if (myc) { + snprintf(statement, sizeof(statement), "delete from admin_user where name='%s'", usname); + int res = mysql_query(myc, statement); + if (res) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error deleting admin user information: %s\n", mysql_error(myc)); + } else { + ret = 0; + } + } + return ret; } -static int mysql_list_admin_users(int no_print) -{ - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - donot_print_connection_success=1; - MYSQL * myc = get_mydb_connection(); - if(myc) { - snprintf(statement,sizeof(statement),"select name, realm from admin_user order by realm,name"); - int res = mysql_query(myc, statement); - if(res) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else { - MYSQL_RES *mres = mysql_store_result(myc); - if(!mres) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else if(mysql_field_count(myc)!=2) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement); - } else { - ret = 0; - for(;;) { - MYSQL_ROW row = mysql_fetch_row(mres); - if(!row) { - break; - } else { - ++ret; - if(row[0] && !no_print) { - if(row[1] && row[1][0]) { - printf("%s[%s]\n",row[0],row[1]); - } else { - printf("%s\n",row[0]); - } - } - } - } - } +static int mysql_list_admin_users(int no_print) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + donot_print_connection_success = 1; + MYSQL *myc = get_mydb_connection(); + if (myc) { + snprintf(statement, sizeof(statement), "select name, realm from admin_user order by realm,name"); + int res = mysql_query(myc, statement); + if (res) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else { + MYSQL_RES *mres = mysql_store_result(myc); + if (!mres) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n", mysql_error(myc)); + } else if (mysql_field_count(myc) != 2) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n", statement); + } else { + ret = 0; + for (;;) { + MYSQL_ROW row = mysql_fetch_row(mres); + if (!row) { + break; + } else { + ++ret; + if (row[0] && !no_print) { + if (row[1] && row[1][0]) { + printf("%s[%s]\n", row[0], row[1]); + } else { + printf("%s\n", row[0]); + } + } + } + } + } - if(mres) - mysql_free_result(mres); - } - } - return ret; + if (mres) + mysql_free_result(mres); + } + } + return ret; } static void mysql_disconnect(void) { - MYSQL *mydbconnection = (MYSQL*)pthread_getspecific(connection_key); - if (mydbconnection) { - mysql_close(mydbconnection); - mydbconnection=NULL; - } - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MySQL connection was closed.\n"); + MYSQL *mydbconnection = (MYSQL *)pthread_getspecific(connection_key); + if (mydbconnection) { + mysql_close(mydbconnection); + mydbconnection = NULL; + } + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MySQL connection was closed.\n"); } ////////////////////////////////////////////////////// static const turn_dbdriver_t driver = { - &mysql_get_auth_secrets, - &mysql_get_user_key, - &mysql_set_user_key, - &mysql_del_user, - &mysql_list_users, - &mysql_list_secrets, - &mysql_del_secret, - &mysql_set_secret, - &mysql_add_origin, - &mysql_del_origin, - &mysql_list_origins, - &mysql_set_realm_option_one, - &mysql_list_realm_options, - &mysql_auth_ping, - &mysql_get_ip_list, - &mysql_set_permission_ip, - &mysql_reread_realms, - &mysql_set_oauth_key, - &mysql_get_oauth_key, - &mysql_del_oauth_key, - &mysql_list_oauth_keys, - &mysql_get_admin_user, - &mysql_set_admin_user, - &mysql_del_admin_user, - &mysql_list_admin_users, - &mysql_disconnect -}; + &mysql_get_auth_secrets, &mysql_get_user_key, &mysql_set_user_key, &mysql_del_user, + &mysql_list_users, &mysql_list_secrets, &mysql_del_secret, &mysql_set_secret, + &mysql_add_origin, &mysql_del_origin, &mysql_list_origins, &mysql_set_realm_option_one, + &mysql_list_realm_options, &mysql_auth_ping, &mysql_get_ip_list, &mysql_set_permission_ip, + &mysql_reread_realms, &mysql_set_oauth_key, &mysql_get_oauth_key, &mysql_del_oauth_key, + &mysql_list_oauth_keys, &mysql_get_admin_user, &mysql_set_admin_user, &mysql_del_admin_user, + &mysql_list_admin_users, &mysql_disconnect}; -const turn_dbdriver_t * get_mysql_dbdriver(void) { - return &driver; -} +const turn_dbdriver_t *get_mysql_dbdriver(void) { return &driver; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// #else -const turn_dbdriver_t * get_mysql_dbdriver(void) { - return NULL; -} +const turn_dbdriver_t *get_mysql_dbdriver(void) { return NULL; } #endif diff --git a/src/apps/relay/dbdrivers/dbd_mysql.h b/src/apps/relay/dbdrivers/dbd_mysql.h index b7ba5b8..af15c70 100644 --- a/src/apps/relay/dbdrivers/dbd_mysql.h +++ b/src/apps/relay/dbdrivers/dbd_mysql.h @@ -38,7 +38,7 @@ extern "C" { #endif -const turn_dbdriver_t * get_mysql_dbdriver(void); +const turn_dbdriver_t *get_mysql_dbdriver(void); #ifdef __cplusplus } @@ -46,4 +46,3 @@ const turn_dbdriver_t * get_mysql_dbdriver(void); #endif /// __DBD_MYSQL__/// - diff --git a/src/apps/relay/dbdrivers/dbd_pgsql.c b/src/apps/relay/dbdrivers/dbd_pgsql.c index b76d703..02c6666 100644 --- a/src/apps/relay/dbdrivers/dbd_pgsql.c +++ b/src/apps/relay/dbdrivers/dbd_pgsql.c @@ -29,8 +29,8 @@ * SUCH DAMAGE. */ -#include "../mainrelay.h" #include "dbd_pgsql.h" +#include "../mainrelay.h" #if !defined(TURN_NO_PQ) #include @@ -41,234 +41,244 @@ static int donot_print_connection_success = 0; static PGconn *get_pqdb_connection(void) { - persistent_users_db_t *pud = get_persistent_users_db(); + persistent_users_db_t *pud = get_persistent_users_db(); - PGconn *pqdbconnection = (PGconn*)pthread_getspecific(connection_key); - if(pqdbconnection) { - ConnStatusType status = PQstatus(pqdbconnection); - if(status != CONNECTION_OK) { - PQfinish(pqdbconnection); - pqdbconnection = NULL; - (void) pthread_setspecific(connection_key, pqdbconnection); - } - } - if(!pqdbconnection) { - char *errmsg=NULL; - PQconninfoOption *co = PQconninfoParse(pud->userdb, &errmsg); - if(!co) { - if(errmsg) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open PostgreSQL DB connection <%s>, connection string format error: %s\n",pud->userdb_sanitized,errmsg); - free(errmsg); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open PostgreSQL DB connection: <%s>, unknown connection string format error\n",pud->userdb_sanitized); - } - } else { - PQconninfoFree(co); - if(errmsg) - free(errmsg); - pqdbconnection = PQconnectdb(pud->userdb); - if(!pqdbconnection) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open PostgreSQL DB connection: <%s>, runtime error\n",pud->userdb_sanitized); - } else { - ConnStatusType status = PQstatus(pqdbconnection); - if(status != CONNECTION_OK) { - PQfinish(pqdbconnection); - pqdbconnection = NULL; - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open PostgreSQL DB connection: <%s>, runtime error\n",pud->userdb_sanitized); - } else if(!donot_print_connection_success){ - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "PostgreSQL DB connection success: %s\n",pud->userdb); - donot_print_connection_success = 1; - } - } - } + PGconn *pqdbconnection = (PGconn *)pthread_getspecific(connection_key); + if (pqdbconnection) { + ConnStatusType status = PQstatus(pqdbconnection); + if (status != CONNECTION_OK) { + PQfinish(pqdbconnection); + pqdbconnection = NULL; + (void)pthread_setspecific(connection_key, pqdbconnection); + } + } + if (!pqdbconnection) { + char *errmsg = NULL; + PQconninfoOption *co = PQconninfoParse(pud->userdb, &errmsg); + if (!co) { + if (errmsg) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, + "Cannot open PostgreSQL DB connection <%s>, connection string format error: %s\n", + pud->userdb_sanitized, errmsg); + free(errmsg); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, + "Cannot open PostgreSQL DB connection: <%s>, unknown connection string format error\n", + pud->userdb_sanitized); + } + } else { + PQconninfoFree(co); + if (errmsg) + free(errmsg); + pqdbconnection = PQconnectdb(pud->userdb); + if (!pqdbconnection) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open PostgreSQL DB connection: <%s>, runtime error\n", + pud->userdb_sanitized); + } else { + ConnStatusType status = PQstatus(pqdbconnection); + if (status != CONNECTION_OK) { + PQfinish(pqdbconnection); + pqdbconnection = NULL; + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open PostgreSQL DB connection: <%s>, runtime error\n", + pud->userdb_sanitized); + } else if (!donot_print_connection_success) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "PostgreSQL DB connection success: %s\n", pud->userdb); + donot_print_connection_success = 1; + } + } + } - if(pqdbconnection) { - (void) pthread_setspecific(connection_key, pqdbconnection); - } - } - return pqdbconnection; + if (pqdbconnection) { + (void)pthread_setspecific(connection_key, pqdbconnection); + } + } + return pqdbconnection; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// static int pgsql_get_auth_secrets(secrets_list_t *sl, uint8_t *realm) { int ret = -1; - PGconn * pqc = get_pqdb_connection(); - if(pqc) { - char statement[TURN_LONG_STRING_SIZE]; - snprintf(statement,sizeof(statement)-1,"select value from turn_secret where realm='%s'",realm); - PGresult *res = PQexec(pqc, statement); + PGconn *pqc = get_pqdb_connection(); + if (pqc) { + char statement[TURN_LONG_STRING_SIZE]; + snprintf(statement, sizeof(statement) - 1, "select value from turn_secret where realm='%s'", realm); + PGresult *res = PQexec(pqc, statement); - if(!res || (PQresultStatus(res) != PGRES_TUPLES_OK)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving PostgreSQL DB information: %s\n",PQerrorMessage(pqc)); - } else { - int i = 0; - for(i=0;iikm_key,PQgetvalue(res,0,0)); - key->timestamp = (uint64_t)strtoll(PQgetvalue(res,0,1),NULL,10); - key->lifetime = (uint32_t)strtol(PQgetvalue(res,0,2),NULL,10); - STRCPY(key->as_rs_alg,PQgetvalue(res,0,3)); - STRCPY(key->realm,PQgetvalue(res,0,4)); - STRCPY(key->kid,kid); - ret = 0; - } + if (!res || (PQresultStatus(res) != PGRES_TUPLES_OK) || (PQntuples(res) != 1)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving PostgreSQL DB information: %s\n", PQerrorMessage(pqc)); + } else { + STRCPY(key->ikm_key, PQgetvalue(res, 0, 0)); + key->timestamp = (uint64_t)strtoll(PQgetvalue(res, 0, 1), NULL, 10); + key->lifetime = (uint32_t)strtol(PQgetvalue(res, 0, 2), NULL, 10); + STRCPY(key->as_rs_alg, PQgetvalue(res, 0, 3)); + STRCPY(key->realm, PQgetvalue(res, 0, 4)); + STRCPY(key->kid, kid); + ret = 0; + } - if(res) { - PQclear(res); - } - } + if (res) { + PQclear(res); + } + } - return ret; + return ret; } -static int pgsql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts,secrets_list_t *realms) { +static int pgsql_list_oauth_keys(secrets_list_t *kids, secrets_list_t *teas, secrets_list_t *tss, secrets_list_t *lts, + secrets_list_t *realms) { - oauth_key_data_raw key_; - oauth_key_data_raw *key=&key_; + oauth_key_data_raw key_; + oauth_key_data_raw *key = &key_; - int ret = -1; + int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,realm,kid from oauth_key order by kid"); + char statement[TURN_LONG_STRING_SIZE]; + snprintf(statement, sizeof(statement), + "select ikm_key,timestamp,lifetime,as_rs_alg,realm,kid from oauth_key order by kid"); - PGconn * pqc = get_pqdb_connection(); - if(pqc) { - PGresult *res = PQexec(pqc, statement); + PGconn *pqc = get_pqdb_connection(); + if (pqc) { + PGresult *res = PQexec(pqc, statement); - if(!res || (PQresultStatus(res) != PGRES_TUPLES_OK)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving PostgreSQL DB information: %s\n",PQerrorMessage(pqc)); - } else { - int i = 0; - for(i=0;iikm_key,PQgetvalue(res,i,0)); - key->timestamp = (uint64_t)strtoll(PQgetvalue(res,i,1),NULL,10); - key->lifetime = (uint32_t)strtol(PQgetvalue(res,i,2),NULL,10); - STRCPY(key->as_rs_alg,PQgetvalue(res,i,3)); - STRCPY(key->realm,PQgetvalue(res,i,4)); - STRCPY(key->kid,PQgetvalue(res,i,5)); + STRCPY(key->ikm_key, PQgetvalue(res, i, 0)); + key->timestamp = (uint64_t)strtoll(PQgetvalue(res, i, 1), NULL, 10); + key->lifetime = (uint32_t)strtol(PQgetvalue(res, i, 2), NULL, 10); + STRCPY(key->as_rs_alg, PQgetvalue(res, i, 3)); + STRCPY(key->realm, PQgetvalue(res, i, 4)); + STRCPY(key->kid, PQgetvalue(res, i, 5)); - if(kids) { - add_to_secrets_list(kids,key->kid); - add_to_secrets_list(teas,key->as_rs_alg); - add_to_secrets_list(realms,key->realm); - { - char ts[256]; - snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp); - add_to_secrets_list(tss,ts); - } - { - char lt[256]; - snprintf(lt,sizeof(lt)-1,"%lu",(unsigned long)key->lifetime); - add_to_secrets_list(lts,lt); - } - } else { - printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, realm=%s\n", - key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, - key->as_rs_alg,key->realm); - } + if (kids) { + add_to_secrets_list(kids, key->kid); + add_to_secrets_list(teas, key->as_rs_alg); + add_to_secrets_list(realms, key->realm); + { + char ts[256]; + snprintf(ts, sizeof(ts) - 1, "%llu", (unsigned long long)key->timestamp); + add_to_secrets_list(tss, ts); + } + { + char lt[256]; + snprintf(lt, sizeof(lt) - 1, "%lu", (unsigned long)key->lifetime); + add_to_secrets_list(lts, lt); + } + } else { + printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, realm=%s\n", key->kid, key->ikm_key, + (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->as_rs_alg, key->realm); + } - ret = 0; - } - } + ret = 0; + } + } - if(res) { - PQclear(res); - } - } + if (res) { + PQclear(res); + } + } - return ret; + return ret; } - + static int pgsql_set_user_key(uint8_t *usname, uint8_t *realm, const char *key) { int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - PGconn *pqc = get_pqdb_connection(); - if(pqc) { - snprintf(statement,sizeof(statement),"insert into turnusers_lt (realm,name,hmackey) values('%s','%s','%s')",realm,usname,key); + char statement[TURN_LONG_STRING_SIZE]; + PGconn *pqc = get_pqdb_connection(); + if (pqc) { + snprintf(statement, sizeof(statement), "insert into turnusers_lt (realm,name,hmackey) values('%s','%s','%s')", + realm, usname, key); - PGresult *res = PQexec(pqc, statement); - if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { - if(res) { - PQclear(res); - } - snprintf(statement,sizeof(statement),"update turnusers_lt set hmackey='%s' where name='%s' and realm='%s'",key,usname,realm); - res = PQexec(pqc, statement); - if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating user information: %s\n",PQerrorMessage(pqc)); - } else { - ret = 0; - } - } - if(res) { - PQclear(res); - } - } + PGresult *res = PQexec(pqc, statement); + if (!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { + if (res) { + PQclear(res); + } + snprintf(statement, sizeof(statement), "update turnusers_lt set hmackey='%s' where name='%s' and realm='%s'", key, + usname, realm); + res = PQexec(pqc, statement); + if (!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating user information: %s\n", PQerrorMessage(pqc)); + } else { + ret = 0; + } + } + if (res) { + PQclear(res); + } + } return ret; } @@ -277,47 +287,53 @@ static int pgsql_set_oauth_key(oauth_key_data_raw *key) { int ret = -1; char statement[TURN_LONG_STRING_SIZE]; PGconn *pqc = get_pqdb_connection(); - if(pqc) { - snprintf(statement,sizeof(statement),"insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg,realm) values('%s','%s',%llu,%lu,'%s','%s')", - key->kid,key->ikm_key,(unsigned long long)key->timestamp,(unsigned long)key->lifetime, - key->as_rs_alg,key->realm); + if (pqc) { + snprintf( + statement, sizeof(statement), + "insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg,realm) values('%s','%s',%llu,%lu,'%s','%s')", + key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->as_rs_alg, + key->realm); - PGresult *res = PQexec(pqc, statement); - if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { - if(res) { - PQclear(res); - } - snprintf(statement,sizeof(statement),"update oauth_key set ikm_key='%s',timestamp=%lu,lifetime=%lu, as_rs_alg='%s', realm='%s' where kid='%s'",key->ikm_key,(unsigned long)key->timestamp,(unsigned long)key->lifetime, - key->as_rs_alg,key->realm,key->kid); - res = PQexec(pqc, statement); - if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating oauth_key information: %s\n",PQerrorMessage(pqc)); - } else { - ret = 0; - } - } else { - ret = 0; - } + PGresult *res = PQexec(pqc, statement); + if (!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { + if (res) { + PQclear(res); + } + snprintf( + statement, sizeof(statement), + "update oauth_key set ikm_key='%s',timestamp=%lu,lifetime=%lu, as_rs_alg='%s', realm='%s' where kid='%s'", + key->ikm_key, (unsigned long)key->timestamp, (unsigned long)key->lifetime, key->as_rs_alg, key->realm, + key->kid); + res = PQexec(pqc, statement); + if (!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating oauth_key information: %s\n", + PQerrorMessage(pqc)); + } else { + ret = 0; + } + } else { + ret = 0; + } - if(res) { - PQclear(res); - } + if (res) { + PQclear(res); + } } return ret; } - + static int pgsql_del_user(uint8_t *usname, uint8_t *realm) { int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - PGconn *pqc = get_pqdb_connection(); - if(pqc) { - snprintf(statement,sizeof(statement),"delete from turnusers_lt where name='%s' and realm='%s'",usname,realm); - PGresult *res = PQexec(pqc, statement); - if(res) { - PQclear(res); + char statement[TURN_LONG_STRING_SIZE]; + PGconn *pqc = get_pqdb_connection(); + if (pqc) { + snprintf(statement, sizeof(statement), "delete from turnusers_lt where name='%s' and realm='%s'", usname, realm); + PGresult *res = PQexec(pqc, statement); + if (res) { + PQclear(res); ret = 0; - } - } + } + } return ret; } @@ -326,679 +342,654 @@ static int pgsql_del_oauth_key(const uint8_t *kid) { int ret = -1; char statement[TURN_LONG_STRING_SIZE]; PGconn *pqc = get_pqdb_connection(); - if(pqc) { - snprintf(statement,sizeof(statement),"delete from oauth_key where kid = '%s'",(const char*)kid); + if (pqc) { + snprintf(statement, sizeof(statement), "delete from oauth_key where kid = '%s'", (const char *)kid); - PGresult *res = PQexec(pqc, statement); - if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error deleting oauth_key information: %s\n",PQerrorMessage(pqc)); - } else { - ret = 0; - } - if(res) { - PQclear(res); - } + PGresult *res = PQexec(pqc, statement); + if (!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error deleting oauth_key information: %s\n", PQerrorMessage(pqc)); + } else { + ret = 0; + } + if (res) { + PQclear(res); + } } return ret; } - -static int pgsql_list_users(uint8_t *realm, secrets_list_t *users, secrets_list_t *realms) -{ - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - uint8_t realm0[STUN_MAX_REALM_SIZE+1] = "\0"; - if(!realm) realm=realm0; +static int pgsql_list_users(uint8_t *realm, secrets_list_t *users, secrets_list_t *realms) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; - PGconn *pqc = get_pqdb_connection(); - if(pqc) { - if(realm[0]) { - snprintf(statement,sizeof(statement),"select name,realm from turnusers_lt where realm='%s' order by name",realm); - } else { - snprintf(statement,sizeof(statement),"select name,realm from turnusers_lt order by realm,name"); - } - PGresult *res = PQexec(pqc, statement); - if(!res || (PQresultStatus(res) != PGRES_TUPLES_OK)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving PostgreSQL DB information: %s\n",PQerrorMessage(pqc)); - } else { - int i = 0; - for(i=0;i> %s\n",kval,rval); - } - } - } - } - ret = 0; - } - if(res) { - PQclear(res); - } - } - return ret; -} - -static int pgsql_set_realm_option_one(uint8_t *realm, unsigned long value, const char* opt) { +static int pgsql_list_origins(uint8_t *realm, secrets_list_t *origins, secrets_list_t *realms) { int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - PGconn *pqc = get_pqdb_connection(); - if(pqc) { - { - snprintf(statement,sizeof(statement),"delete from turn_realm_option where realm='%s' and opt='%s'",realm,opt); - PGresult *res = PQexec(pqc, statement); - if(res) { - PQclear(res); - } - } - if(value>0) { - snprintf(statement,sizeof(statement),"insert into turn_realm_option (realm,opt,value) values('%s','%s','%lu')",realm,opt,(unsigned long)value); - PGresult *res = PQexec(pqc, statement); - if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting realm option information: %s\n",PQerrorMessage(pqc)); - } else { - ret = 0; - } - if(res) { - PQclear(res); - } - } - } + + uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0"; + if (!realm) + realm = realm0; + + donot_print_connection_success = 1; + + PGconn *pqc = get_pqdb_connection(); + + if (pqc) { + + char statement[TURN_LONG_STRING_SIZE]; + + if (realm && realm[0]) { + snprintf(statement, sizeof(statement), + "select origin,realm from turn_origin_to_realm where realm='%s' order by origin", realm); + } else { + snprintf(statement, sizeof(statement), "select origin,realm from turn_origin_to_realm order by realm,origin"); + } + PGresult *res = PQexec(pqc, statement); + if (!res || (PQresultStatus(res) != PGRES_TUPLES_OK)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving PostgreSQL DB information: %s\n", PQerrorMessage(pqc)); + } else { + int i = 0; + for (i = 0; i < PQntuples(res); i++) { + char *kval = PQgetvalue(res, i, 0); + if (kval) { + char *rval = PQgetvalue(res, i, 1); + if (rval) { + if (origins) { + add_to_secrets_list(origins, kval); + if (realms) { + if (rval && *rval) { + add_to_secrets_list(realms, rval); + } else { + add_to_secrets_list(realms, (char *)realm); + } + } + } else { + printf("%s ==>> %s\n", kval, rval); + } + } + } + } + ret = 0; + } + if (res) { + PQclear(res); + } + } return ret; } - + +static int pgsql_set_realm_option_one(uint8_t *realm, unsigned long value, const char *opt) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + PGconn *pqc = get_pqdb_connection(); + if (pqc) { + { + snprintf(statement, sizeof(statement), "delete from turn_realm_option where realm='%s' and opt='%s'", realm, opt); + PGresult *res = PQexec(pqc, statement); + if (res) { + PQclear(res); + } + } + if (value > 0) { + snprintf(statement, sizeof(statement), "insert into turn_realm_option (realm,opt,value) values('%s','%s','%lu')", + realm, opt, (unsigned long)value); + PGresult *res = PQexec(pqc, statement); + if (!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting realm option information: %s\n", PQerrorMessage(pqc)); + } else { + ret = 0; + } + if (res) { + PQclear(res); + } + } + } + return ret; +} + static int pgsql_list_realm_options(uint8_t *realm) { int ret = -1; - donot_print_connection_success = 1; - char statement[TURN_LONG_STRING_SIZE]; - PGconn *pqc = get_pqdb_connection(); - if(pqc) { - if(realm && realm[0]) { - snprintf(statement,sizeof(statement),"select realm,opt,value from turn_realm_option where realm='%s' order by realm,opt",realm); - } else { - snprintf(statement,sizeof(statement),"select realm,opt,value from turn_realm_option order by realm,opt"); - } - PGresult *res = PQexec(pqc, statement); - if(!res || (PQresultStatus(res) != PGRES_TUPLES_OK)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving PostgreSQL DB information: %s\n",PQerrorMessage(pqc)); - } else { - int i = 0; - for(i=0;isz; - unlock_realms(); + lock_realms(); + rlsz = realms_list->sz; + unlock_realms(); - for (i = 0; isecrets[i]; + char *realm = realms_list->secrets[i]; - realm_params_t* rp = get_realm(realm); + realm_params_t *rp = get_realm(realm); - lock_realms(); - rp->options.perf_options.max_bps = turn_params.max_bps; - unlock_realms(); + lock_realms(); + rp->options.perf_options.max_bps = turn_params.max_bps; + unlock_realms(); - lock_realms(); - rp->options.perf_options.total_quota = turn_params.total_quota; - unlock_realms(); + lock_realms(); + rp->options.perf_options.total_quota = turn_params.total_quota; + unlock_realms(); - lock_realms(); - rp->options.perf_options.user_quota = turn_params.user_quota; - unlock_realms(); + lock_realms(); + rp->options.perf_options.user_quota = turn_params.user_quota; + unlock_realms(); + } + } - } - } + snprintf(statement, sizeof(statement), "select realm,opt,value from turn_realm_option"); + PGresult *res = PQexec(pqc, statement); - snprintf(statement,sizeof(statement),"select realm,opt,value from turn_realm_option"); - PGresult *res = PQexec(pqc, statement); + if (res && (PQresultStatus(res) == PGRES_TUPLES_OK)) { - if(res && (PQresultStatus(res) == PGRES_TUPLES_OK)) { + int i = 0; + for (i = 0; i < PQntuples(res); i++) { + char *rval = PQgetvalue(res, i, 0); + char *oval = PQgetvalue(res, i, 1); + char *vval = PQgetvalue(res, i, 2); + if (rval && oval && vval) { + realm_params_t *rp = get_realm(rval); + if (!strcmp(oval, "max-bps")) + rp->options.perf_options.max_bps = (band_limit_t)strtoul(vval, NULL, 10); + else if (!strcmp(oval, "total-quota")) + rp->options.perf_options.total_quota = (vint)atoi(vval); + else if (!strcmp(oval, "user-quota")) + rp->options.perf_options.user_quota = (vint)atoi(vval); + else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown realm option: %s\n", oval); + } + } + } + } - int i = 0; - for(i=0;ioptions.perf_options.max_bps = (band_limit_t)strtoul(vval,NULL,10); - else if(!strcmp(oval,"total-quota")) - rp->options.perf_options.total_quota = (vint)atoi(vval); - else if(!strcmp(oval,"user-quota")) - rp->options.perf_options.user_quota = (vint)atoi(vval); - else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown realm option: %s\n", oval); - } - } - } - } - - if(res) { - PQclear(res); - } - } - } + if (res) { + PQclear(res); + } + } + } } ////////////////////////////////////////////// -static int pgsql_get_admin_user(const uint8_t *usname, uint8_t *realm, password_t pwd) -{ - int ret = -1; +static int pgsql_get_admin_user(const uint8_t *usname, uint8_t *realm, password_t pwd) { + int ret = -1; - realm[0]=0; - pwd[0]=0; + realm[0] = 0; + pwd[0] = 0; - PGconn * pqc = get_pqdb_connection(); - if(pqc) { - char statement[TURN_LONG_STRING_SIZE]; - snprintf(statement,sizeof(statement),"select realm,password from admin_user where name='%s'",usname); - PGresult *res = PQexec(pqc, statement); + PGconn *pqc = get_pqdb_connection(); + if (pqc) { + char statement[TURN_LONG_STRING_SIZE]; + snprintf(statement, sizeof(statement), "select realm,password from admin_user where name='%s'", usname); + PGresult *res = PQexec(pqc, statement); - if(!res || (PQresultStatus(res) != PGRES_TUPLES_OK) || (PQntuples(res)!=1)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving PostgreSQL DB information: %s\n",PQerrorMessage(pqc)); - } else { - const char *kval = PQgetvalue(res,0,0); - if(kval) { - strncpy((char*)realm,kval,STUN_MAX_REALM_SIZE); - } - kval = (const char*) PQgetvalue(res,0,1); - if(kval) { - strncpy((char*)pwd,kval,STUN_MAX_PWD_SIZE); - } - ret = 0; - } + if (!res || (PQresultStatus(res) != PGRES_TUPLES_OK) || (PQntuples(res) != 1)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving PostgreSQL DB information: %s\n", PQerrorMessage(pqc)); + } else { + const char *kval = PQgetvalue(res, 0, 0); + if (kval) { + strncpy((char *)realm, kval, STUN_MAX_REALM_SIZE); + } + kval = (const char *)PQgetvalue(res, 0, 1); + if (kval) { + strncpy((char *)pwd, kval, STUN_MAX_PWD_SIZE); + } + ret = 0; + } - if(res) - PQclear(res); - - } - return ret; + if (res) + PQclear(res); + } + return ret; } -static int pgsql_set_admin_user(const uint8_t *usname, const uint8_t *realm, const password_t pwd) -{ - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - donot_print_connection_success=1; - PGconn *pqc = get_pqdb_connection(); - if(pqc) { - snprintf(statement,sizeof(statement),"insert into admin_user (realm,name,password) values('%s','%s','%s')",realm,usname,pwd); +static int pgsql_set_admin_user(const uint8_t *usname, const uint8_t *realm, const password_t pwd) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + donot_print_connection_success = 1; + PGconn *pqc = get_pqdb_connection(); + if (pqc) { + snprintf(statement, sizeof(statement), "insert into admin_user (realm,name,password) values('%s','%s','%s')", realm, + usname, pwd); - PGresult *res = PQexec(pqc, statement); - if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { - if(res) { - PQclear(res); - } - snprintf(statement,sizeof(statement),"update admin_user set password='%s',realm='%s' where name='%s'",pwd,realm,usname); - res = PQexec(pqc, statement); - if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating user information: %s\n",PQerrorMessage(pqc)); - } else { - ret = 0; - } - } - if(res) { - PQclear(res); - } - } - return ret; + PGresult *res = PQexec(pqc, statement); + if (!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { + if (res) { + PQclear(res); + } + snprintf(statement, sizeof(statement), "update admin_user set password='%s',realm='%s' where name='%s'", pwd, + realm, usname); + res = PQexec(pqc, statement); + if (!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating user information: %s\n", PQerrorMessage(pqc)); + } else { + ret = 0; + } + } + if (res) { + PQclear(res); + } + } + return ret; } -static int pgsql_del_admin_user(const uint8_t *usname) -{ - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - donot_print_connection_success=1; - PGconn *pqc = get_pqdb_connection(); - if(pqc) { - snprintf(statement,sizeof(statement),"delete from admin_user where name='%s'",usname); - PGresult *res = PQexec(pqc, statement); - if(res) { - PQclear(res); - ret = 0; - } - } - return ret; +static int pgsql_del_admin_user(const uint8_t *usname) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + donot_print_connection_success = 1; + PGconn *pqc = get_pqdb_connection(); + if (pqc) { + snprintf(statement, sizeof(statement), "delete from admin_user where name='%s'", usname); + PGresult *res = PQexec(pqc, statement); + if (res) { + PQclear(res); + ret = 0; + } + } + return ret; } -static int pgsql_list_admin_users(int no_print) -{ - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - donot_print_connection_success=1; - PGconn *pqc = get_pqdb_connection(); - if(pqc) { - snprintf(statement,sizeof(statement),"select name,realm,password from admin_user order by realm,name"); - } - PGresult *res = PQexec(pqc, statement); - if(!res || (PQresultStatus(res) != PGRES_TUPLES_OK)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving PostgreSQL DB information: %s\n",PQerrorMessage(pqc)); - } else { - int i = 0; - ret = 0; - for(i=0;ihost) free(co->host); - if(co->dbname) free(co->dbname); - if(co->password) free(co->password); - memset(co, 0, sizeof(Ryconninfo)); - free(co); - } + if (co) { + if (co->host) + free(co->host); + if (co->dbname) + free(co->dbname); + if (co->password) + free(co->password); + memset(co, 0, sizeof(Ryconninfo)); + free(co); + } } static Ryconninfo *RyconninfoParse(const char *userdb, char **errmsg) { - Ryconninfo *co = (Ryconninfo*) malloc(sizeof(Ryconninfo)); - memset(co, 0, sizeof(Ryconninfo)); - if (userdb) { - char *s0 = strdup(userdb); - char *s = s0; + Ryconninfo *co = (Ryconninfo *)malloc(sizeof(Ryconninfo)); + memset(co, 0, sizeof(Ryconninfo)); + if (userdb) { + char *s0 = strdup(userdb); + char *s = s0; - while (s && *s) { + while (s && *s) { - while (*s && (*s == ' ')) - ++s; - char *snext = strstr(s, " "); - if (snext) { - *snext = 0; - ++snext; - } + while (*s && (*s == ' ')) + ++s; + char *snext = strstr(s, " "); + if (snext) { + *snext = 0; + ++snext; + } - char* seq = strstr(s, "="); - if (!seq) { - RyconninfoFree(co); - co = NULL; - if (errmsg) { - *errmsg = strdup(s); - } - break; - } + char *seq = strstr(s, "="); + if (!seq) { + RyconninfoFree(co); + co = NULL; + if (errmsg) { + *errmsg = strdup(s); + } + break; + } - *seq = 0; - if (!strcmp(s, "host")) - co->host = strdup(seq + 1); - else if (!strcmp(s, "ip")) - co->host = strdup(seq + 1); - else if (!strcmp(s, "addr")) - co->host = strdup(seq + 1); - else if (!strcmp(s, "ipaddr")) - co->host = strdup(seq + 1); - else if (!strcmp(s, "hostaddr")) - co->host = strdup(seq + 1); - else if (!strcmp(s, "dbname")) - co->dbname = strdup(seq + 1); - else if (!strcmp(s, "db")) - co->dbname = strdup(seq + 1); - else if (!strcmp(s, "database")) - co->dbname = strdup(seq + 1); - else if (!strcmp(s, "user")) - ; - else if (!strcmp(s, "uname")) - ; - else if (!strcmp(s, "name")) - ; - else if (!strcmp(s, "username")) - ; - else if (!strcmp(s, "password")) - co->password = strdup(seq + 1); - else if (!strcmp(s, "pwd")) - co->password = strdup(seq + 1); - else if (!strcmp(s, "passwd")) - co->password = strdup(seq + 1); - else if (!strcmp(s, "secret")) - co->password = strdup(seq + 1); - else if (!strcmp(s, "port")) - co->port = (unsigned int) atoi(seq + 1); - else if (!strcmp(s, "p")) - co->port = (unsigned int) atoi(seq + 1); - else if (!strcmp(s, "connect_timeout")) - co->connect_timeout = (unsigned int) atoi(seq + 1); - else if (!strcmp(s, "timeout")) - co->connect_timeout = (unsigned int) atoi(seq + 1); - else { - RyconninfoFree(co); - co = NULL; - if (errmsg) { - *errmsg = strdup(s); - } - break; - } + *seq = 0; + if (!strcmp(s, "host")) + co->host = strdup(seq + 1); + else if (!strcmp(s, "ip")) + co->host = strdup(seq + 1); + else if (!strcmp(s, "addr")) + co->host = strdup(seq + 1); + else if (!strcmp(s, "ipaddr")) + co->host = strdup(seq + 1); + else if (!strcmp(s, "hostaddr")) + co->host = strdup(seq + 1); + else if (!strcmp(s, "dbname")) + co->dbname = strdup(seq + 1); + else if (!strcmp(s, "db")) + co->dbname = strdup(seq + 1); + else if (!strcmp(s, "database")) + co->dbname = strdup(seq + 1); + else if (!strcmp(s, "user")) + ; + else if (!strcmp(s, "uname")) + ; + else if (!strcmp(s, "name")) + ; + else if (!strcmp(s, "username")) + ; + else if (!strcmp(s, "password")) + co->password = strdup(seq + 1); + else if (!strcmp(s, "pwd")) + co->password = strdup(seq + 1); + else if (!strcmp(s, "passwd")) + co->password = strdup(seq + 1); + else if (!strcmp(s, "secret")) + co->password = strdup(seq + 1); + else if (!strcmp(s, "port")) + co->port = (unsigned int)atoi(seq + 1); + else if (!strcmp(s, "p")) + co->port = (unsigned int)atoi(seq + 1); + else if (!strcmp(s, "connect_timeout")) + co->connect_timeout = (unsigned int)atoi(seq + 1); + else if (!strcmp(s, "timeout")) + co->connect_timeout = (unsigned int)atoi(seq + 1); + else { + RyconninfoFree(co); + co = NULL; + if (errmsg) { + *errmsg = strdup(s); + } + break; + } - s = snext; - } + s = snext; + } - free(s0); - } + free(s0); + } - if(co) { - if(!(co->dbname)) - co->dbname=strdup("0"); - if(!(co->host)) - co->host=strdup("127.0.0.1"); - if(!(co->password)) - co->password=strdup(""); - } + if (co) { + if (!(co->dbname)) + co->dbname = strdup("0"); + if (!(co->host)) + co->host = strdup("127.0.0.1"); + if (!(co->password)) + co->password = strdup(""); + } - return co; + return co; } -redis_context_handle get_redis_async_connection(struct event_base *base, redis_stats_db_t* redis_stats_db, int delete_keys) { +redis_context_handle get_redis_async_connection(struct event_base *base, redis_stats_db_t *redis_stats_db, + int delete_keys) { - redis_context_handle ret = NULL; + redis_context_handle ret = NULL; - char *errmsg = NULL; - if(base && redis_stats_db->connection_string[0]) { - Ryconninfo *co = RyconninfoParse(redis_stats_db->connection_string_sanitized, &errmsg); - if (!co) { - if (errmsg) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open Redis DB connection <%s>, connection string format error: %s\n", redis_stats_db->connection_string_sanitized, errmsg); - free(errmsg); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open Redis DB connection <%s>, connection string format error\n", redis_stats_db->connection_string_sanitized); - } - } else if (errmsg) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open Redis DB connection <%s>, connection string format error: %s\n", redis_stats_db->connection_string_sanitized, errmsg); - free(errmsg); - RyconninfoFree(co); - } else { + char *errmsg = NULL; + if (base && redis_stats_db->connection_string[0]) { + Ryconninfo *co = RyconninfoParse(redis_stats_db->connection_string_sanitized, &errmsg); + if (!co) { + if (errmsg) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, + "Cannot open Redis DB connection <%s>, connection string format error: %s\n", + redis_stats_db->connection_string_sanitized, errmsg); + free(errmsg); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open Redis DB connection <%s>, connection string format error\n", + redis_stats_db->connection_string_sanitized); + } + } else if (errmsg) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open Redis DB connection <%s>, connection string format error: %s\n", + redis_stats_db->connection_string_sanitized, errmsg); + free(errmsg); + RyconninfoFree(co); + } else { - if(delete_keys) { + if (delete_keys) { - redisContext *rc = NULL; + redisContext *rc = NULL; - char ip[256] = "\0"; - int port = DEFAULT_REDIS_PORT; - if (co->host) - STRCPY(ip,co->host); - if (!ip[0]) - strncpy(ip,"127.0.0.1",sizeof(ip)); + char ip[256] = "\0"; + int port = DEFAULT_REDIS_PORT; + if (co->host) + STRCPY(ip, co->host); + if (!ip[0]) + strncpy(ip, "127.0.0.1", sizeof(ip)); - if (co->port) - port = (int) (co->port); + if (co->port) + port = (int)(co->port); - if (co->connect_timeout) { - struct timeval tv; - tv.tv_usec = 0; - tv.tv_sec = (time_t) (co->connect_timeout); - rc = redisConnectWithTimeout(ip, port, tv); - } else { - rc = redisConnect(ip, port); - } + if (co->connect_timeout) { + struct timeval tv; + tv.tv_usec = 0; + tv.tv_sec = (time_t)(co->connect_timeout); + rc = redisConnectWithTimeout(ip, port, tv); + } else { + rc = redisConnect(ip, port); + } - if (!rc) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot initialize Redis DB async connection\n"); - } else { - if (co->password) { - turnFreeRedisReply(redisCommand(rc, "AUTH %s", co->password)); - } - if (co->dbname) { - turnFreeRedisReply(redisCommand(rc, "select %s", co->dbname)); - } - { - redisReply *reply = (redisReply*)redisCommand(rc, "keys turn/*/allocation/*/status"); - if(reply) { - secrets_list_t keys; - size_t isz = 0; - char s[513]; + if (!rc) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot initialize Redis DB async connection\n"); + } else { + if (co->password) { + turnFreeRedisReply(redisCommand(rc, "AUTH %s", co->password)); + } + if (co->dbname) { + turnFreeRedisReply(redisCommand(rc, "select %s", co->dbname)); + } + { + redisReply *reply = (redisReply *)redisCommand(rc, "keys turn/*/allocation/*/status"); + if (reply) { + secrets_list_t keys; + size_t isz = 0; + char s[513]; - init_secrets_list(&keys); + init_secrets_list(&keys); - if (reply->type == REDIS_REPLY_ERROR) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); - } else if (reply->type != REDIS_REPLY_ARRAY) { - if (reply->type != REDIS_REPLY_NIL) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); - } else { - size_t i; - for (i = 0; i < reply->elements; ++i) { - add_to_secrets_list(&keys,reply->element[i]->str); - } - } + if (reply->type == REDIS_REPLY_ERROR) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); + } else if (reply->type != REDIS_REPLY_ARRAY) { + if (reply->type != REDIS_REPLY_NIL) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); + } else { + size_t i; + for (i = 0; i < reply->elements; ++i) { + add_to_secrets_list(&keys, reply->element[i]->str); + } + } - for(isz=0;iszhost, co->port, co->password, atoi(co->dbname)); + ret = redisLibeventAttach(base, co->host, co->port, co->password, atoi(co->dbname)); - if (!ret) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot initialize Redis DB connection\n"); - } else if (is_redis_asyncconn_good(ret) && !donot_print_connection_success) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Redis DB async connection to be used: %s\n", redis_stats_db->connection_string_sanitized); - donot_print_connection_success = 1; - } - RyconninfoFree(co); - } - } + if (!ret) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot initialize Redis DB connection\n"); + } else if (is_redis_asyncconn_good(ret) && !donot_print_connection_success) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Redis DB async connection to be used: %s\n", + redis_stats_db->connection_string_sanitized); + donot_print_connection_success = 1; + } + RyconninfoFree(co); + } + } - return ret; + return ret; } static redisContext *get_redis_connection(void) { - persistent_users_db_t *pud = get_persistent_users_db(); + persistent_users_db_t *pud = get_persistent_users_db(); - redisContext *redisconnection = (redisContext*)pthread_getspecific(connection_key); + redisContext *redisconnection = (redisContext *)pthread_getspecific(connection_key); - if(redisconnection) { - if(redisconnection->err) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot connect to redis, err=%d, flags=0x%lx\n", __FUNCTION__,(int)redisconnection->err,(unsigned long)redisconnection->flags); - redisFree(redisconnection); - redisconnection = NULL; - (void) pthread_setspecific(connection_key, redisconnection); - } - } + if (redisconnection) { + if (redisconnection->err) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot connect to redis, err=%d, flags=0x%lx\n", __FUNCTION__, + (int)redisconnection->err, (unsigned long)redisconnection->flags); + redisFree(redisconnection); + redisconnection = NULL; + (void)pthread_setspecific(connection_key, redisconnection); + } + } - if (!redisconnection) { + if (!redisconnection) { - char *errmsg = NULL; - Ryconninfo *co = RyconninfoParse(pud->userdb, &errmsg); - if (!co) { - if (errmsg) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open Redis DB connection <%s>, connection string format error: %s\n", pud->userdb, errmsg); - free(errmsg); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open Redis DB connection <%s>, connection string format error\n", pud->userdb); - } - } else if (errmsg) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open Redis DB connection <%s>, connection string format error: %s\n", pud->userdb, errmsg); - free(errmsg); - RyconninfoFree(co); - } else { - char ip[256] = "\0"; - int port = DEFAULT_REDIS_PORT; - if (co->host) - STRCPY(ip,co->host); - if (!ip[0]) - strncpy(ip,"127.0.0.1",sizeof(ip)); + char *errmsg = NULL; + Ryconninfo *co = RyconninfoParse(pud->userdb, &errmsg); + if (!co) { + if (errmsg) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, + "Cannot open Redis DB connection <%s>, connection string format error: %s\n", pud->userdb, + errmsg); + free(errmsg); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open Redis DB connection <%s>, connection string format error\n", + pud->userdb); + } + } else if (errmsg) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open Redis DB connection <%s>, connection string format error: %s\n", + pud->userdb, errmsg); + free(errmsg); + RyconninfoFree(co); + } else { + char ip[256] = "\0"; + int port = DEFAULT_REDIS_PORT; + if (co->host) + STRCPY(ip, co->host); + if (!ip[0]) + strncpy(ip, "127.0.0.1", sizeof(ip)); - if (co->port) - port = (int) (co->port); + if (co->port) + port = (int)(co->port); - if (co->connect_timeout) { - struct timeval tv; - tv.tv_usec = 0; - tv.tv_sec = (time_t) (co->connect_timeout); - redisconnection = redisConnectWithTimeout(ip, port, tv); - } else { - redisconnection = redisConnect(ip, port); - } + if (co->connect_timeout) { + struct timeval tv; + tv.tv_usec = 0; + tv.tv_sec = (time_t)(co->connect_timeout); + redisconnection = redisConnectWithTimeout(ip, port, tv); + } else { + redisconnection = redisConnect(ip, port); + } - if (redisconnection) { - if(redisconnection->err) { - if(redisconnection->errstr[0]) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Redis: %s\n",redisconnection->errstr); - } - redisFree(redisconnection); - redisconnection = NULL; - } else if (co->password) { - void *reply = redisCommand(redisconnection, "AUTH %s", co->password); - if(!reply) { - if(redisconnection->err && redisconnection->errstr[0]) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Redis: %s\n",redisconnection->errstr); - } - redisFree(redisconnection); - redisconnection = NULL; - } else { - turnFreeRedisReply(reply); - if (co->dbname) { - reply = redisCommand(redisconnection, "select %s", co->dbname); - if(!reply) { - if(redisconnection->err && redisconnection->errstr[0]) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Redis: %s\n",redisconnection->errstr); - } - redisFree(redisconnection); - redisconnection = NULL; - } else { - turnFreeRedisReply(reply); - } - } - } - } - } + if (redisconnection) { + if (redisconnection->err) { + if (redisconnection->errstr[0]) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Redis: %s\n", redisconnection->errstr); + } + redisFree(redisconnection); + redisconnection = NULL; + } else if (co->password) { + void *reply = redisCommand(redisconnection, "AUTH %s", co->password); + if (!reply) { + if (redisconnection->err && redisconnection->errstr[0]) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Redis: %s\n", redisconnection->errstr); + } + redisFree(redisconnection); + redisconnection = NULL; + } else { + turnFreeRedisReply(reply); + if (co->dbname) { + reply = redisCommand(redisconnection, "select %s", co->dbname); + if (!reply) { + if (redisconnection->err && redisconnection->errstr[0]) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Redis: %s\n", redisconnection->errstr); + } + redisFree(redisconnection); + redisconnection = NULL; + } else { + turnFreeRedisReply(reply); + } + } + } + } + } - if (!redisconnection) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot initialize Redis DB connection\n"); - } else if (!donot_print_connection_success) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Redis DB sync connection success: %s\n", pud->userdb); - donot_print_connection_success = 1; - } + if (!redisconnection) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot initialize Redis DB connection\n"); + } else if (!donot_print_connection_success) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Redis DB sync connection success: %s\n", pud->userdb); + donot_print_connection_success = 1; + } - RyconninfoFree(co); - } - if(redisconnection) { - (void) pthread_setspecific(connection_key, redisconnection); - } - } + RyconninfoFree(co); + } + if (redisconnection) { + (void)pthread_setspecific(connection_key, redisconnection); + } + } - return redisconnection; + return redisconnection; } -static int set_redis_realm_opt(char *realm, const char* key, unsigned long *value) -{ - int found = 0; +static int set_redis_realm_opt(char *realm, const char *key, unsigned long *value) { + int found = 0; - redisContext *rc = get_redis_connection(); + redisContext *rc = get_redis_connection(); - if(rc) { - redisReply *rget = NULL; + if (rc) { + redisReply *rget = NULL; - char s[1025]; + char s[1025]; - snprintf(s, sizeof(s), "get turn/realm/%s/%s", realm, key); + snprintf(s, sizeof(s), "get turn/realm/%s/%s", realm, key); - rget = (redisReply *) redisCommand(rc, s); - if (rget) { - if (rget->type == REDIS_REPLY_ERROR) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", rget->str); - else if (rget->type != REDIS_REPLY_STRING) { - if (rget->type != REDIS_REPLY_NIL) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", rget->type); - } else { - lock_realms(); - *value = (unsigned long)atol(rget->str); - unlock_realms(); - found = 1; - } - turnFreeRedisReply(rget); - } - } + rget = (redisReply *)redisCommand(rc, s); + if (rget) { + if (rget->type == REDIS_REPLY_ERROR) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", rget->str); + else if (rget->type != REDIS_REPLY_STRING) { + if (rget->type != REDIS_REPLY_NIL) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", rget->type); + } else { + lock_realms(); + *value = (unsigned long)atol(rget->str); + unlock_realms(); + found = 1; + } + turnFreeRedisReply(rget); + } + } - return found; + return found; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// -static int redis_get_auth_secrets(secrets_list_t *sl, uint8_t *realm) -{ - int ret = -1; - redisContext *rc = get_redis_connection(); - if (rc) { - redisReply *reply = (redisReply*) redisCommand(rc, "smembers turn/realm/%s/secret", (char*) realm); - if (reply) { +static int redis_get_auth_secrets(secrets_list_t *sl, uint8_t *realm) { + int ret = -1; + redisContext *rc = get_redis_connection(); + if (rc) { + redisReply *reply = (redisReply *)redisCommand(rc, "smembers turn/realm/%s/secret", (char *)realm); + if (reply) { - if (reply->type == REDIS_REPLY_ERROR) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); - else if (reply->type != REDIS_REPLY_ARRAY) { - if (reply->type != REDIS_REPLY_NIL) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); - } else { - size_t i; - for (i = 0; i < reply->elements; ++i) { - add_to_secrets_list(sl, reply->element[i]->str); - } - } + if (reply->type == REDIS_REPLY_ERROR) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); + else if (reply->type != REDIS_REPLY_ARRAY) { + if (reply->type != REDIS_REPLY_NIL) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); + } else { + size_t i; + for (i = 0; i < reply->elements; ++i) { + add_to_secrets_list(sl, reply->element[i]->str); + } + } - ret = 0; + ret = 0; - turnFreeRedisReply(reply); - } - } - return ret; + turnFreeRedisReply(reply); + } + } + return ret; } - + static int redis_get_user_key(uint8_t *usname, uint8_t *realm, hmackey_t key) { int ret = -1; - redisContext * rc = get_redis_connection(); - if(rc) { - char s[TURN_LONG_STRING_SIZE]; - snprintf(s,sizeof(s),"get turn/realm/%s/user/%s/key", (char*)realm, usname); - redisReply *rget = (redisReply *)redisCommand(rc, s); - if(rget) { - if (rget->type == REDIS_REPLY_ERROR) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", rget->str); - else if (rget->type != REDIS_REPLY_STRING) { - if (rget->type != REDIS_REPLY_NIL) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", rget->type); - } else { - size_t sz = get_hmackey_size(SHATYPE_DEFAULT); - if(strlen(rget->str)str,usname); - } else if(convert_string_key_to_binary(rget->str, key, sz)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key: %s, user %s\n",rget->str,usname); - } else { - ret = 0; - } - } - turnFreeRedisReply(rget); - } - } + redisContext *rc = get_redis_connection(); + if (rc) { + char s[TURN_LONG_STRING_SIZE]; + snprintf(s, sizeof(s), "get turn/realm/%s/user/%s/key", (char *)realm, usname); + redisReply *rget = (redisReply *)redisCommand(rc, s); + if (rget) { + if (rget->type == REDIS_REPLY_ERROR) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", rget->str); + else if (rget->type != REDIS_REPLY_STRING) { + if (rget->type != REDIS_REPLY_NIL) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", rget->type); + } else { + size_t sz = get_hmackey_size(SHATYPE_DEFAULT); + if (strlen(rget->str) < sz * 2) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key format: %s, user %s\n", rget->str, usname); + } else if (convert_string_key_to_binary(rget->str, key, sz) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key: %s, user %s\n", rget->str, usname); + } else { + ret = 0; + } + } + turnFreeRedisReply(rget); + } + } return ret; } static int redis_get_oauth_key(const uint8_t *kid, oauth_key_data_raw *key) { int ret = -1; - redisContext * rc = get_redis_connection(); - if(rc) { - char s[TURN_LONG_STRING_SIZE]; - memset(key, 0, sizeof(oauth_key_data_raw)); - STRCPY(key->kid,kid); - snprintf(s,sizeof(s),"hgetall turn/oauth/kid/%s", (const char*)kid); - redisReply *reply = (redisReply *)redisCommand(rc, s); - if(reply) { - if (reply->type == REDIS_REPLY_ERROR) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); - else if (reply->type != REDIS_REPLY_ARRAY) { - if (reply->type != REDIS_REPLY_NIL) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); - } else if(reply->elements > 1) { - size_t i; - for (i = 0; i < (reply->elements)/2; ++i) { - char *kw = reply->element[2*i]->str; - char *val = reply->element[2*i+1]->str; - if(kw) { - if(!strcmp(kw,"as_rs_alg")) { - STRCPY(key->as_rs_alg,val); - } else if(!strcmp(kw,"realm")) { - STRCPY(key->realm,val); - } else if(!strcmp(kw,"ikm_key")) { - STRCPY(key->ikm_key,val); - } else if(!strcmp(kw,"timestamp")) { - key->timestamp = (uint64_t)strtoull(val,NULL,10); - } else if(!strcmp(kw,"lifetime")) { - key->lifetime = (uint32_t)strtoul(val,NULL,10); - } - } - } - ret = 0; - } - turnFreeRedisReply(reply); - } + redisContext *rc = get_redis_connection(); + if (rc) { + char s[TURN_LONG_STRING_SIZE]; + memset(key, 0, sizeof(oauth_key_data_raw)); + STRCPY(key->kid, kid); + snprintf(s, sizeof(s), "hgetall turn/oauth/kid/%s", (const char *)kid); + redisReply *reply = (redisReply *)redisCommand(rc, s); + if (reply) { + if (reply->type == REDIS_REPLY_ERROR) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); + else if (reply->type != REDIS_REPLY_ARRAY) { + if (reply->type != REDIS_REPLY_NIL) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); + } else if (reply->elements > 1) { + size_t i; + for (i = 0; i < (reply->elements) / 2; ++i) { + char *kw = reply->element[2 * i]->str; + char *val = reply->element[2 * i + 1]->str; + if (kw) { + if (!strcmp(kw, "as_rs_alg")) { + STRCPY(key->as_rs_alg, val); + } else if (!strcmp(kw, "realm")) { + STRCPY(key->realm, val); + } else if (!strcmp(kw, "ikm_key")) { + STRCPY(key->ikm_key, val); + } else if (!strcmp(kw, "timestamp")) { + key->timestamp = (uint64_t)strtoull(val, NULL, 10); + } else if (!strcmp(kw, "lifetime")) { + key->lifetime = (uint32_t)strtoul(val, NULL, 10); + } + } + } + ret = 0; + } + turnFreeRedisReply(reply); + } } return ret; } - + static int redis_set_user_key(uint8_t *usname, uint8_t *realm, const char *key) { int ret = -1; - redisContext *rc = get_redis_connection(); - if(rc) { - char statement[TURN_LONG_STRING_SIZE]; - snprintf(statement,sizeof(statement),"set turn/realm/%s/user/%s/key %s",(char*)realm,usname,key); - turnFreeRedisReply(redisCommand(rc, statement)); - turnFreeRedisReply(redisCommand(rc, "save")); - ret = 0; - } + redisContext *rc = get_redis_connection(); + if (rc) { + char statement[TURN_LONG_STRING_SIZE]; + snprintf(statement, sizeof(statement), "set turn/realm/%s/user/%s/key %s", (char *)realm, usname, key); + turnFreeRedisReply(redisCommand(rc, statement)); + turnFreeRedisReply(redisCommand(rc, "save")); + ret = 0; + } return ret; } static int redis_set_oauth_key(oauth_key_data_raw *key) { int ret = -1; redisContext *rc = get_redis_connection(); - if(rc) { - char statement[TURN_LONG_STRING_SIZE]; - snprintf(statement,sizeof(statement),"hmset turn/oauth/kid/%s ikm_key %s as_rs_alg %s timestamp %llu lifetime %lu realm %s", - key->kid,key->ikm_key,key->as_rs_alg,(unsigned long long)key->timestamp,(unsigned long)key->lifetime,key->realm); - turnFreeRedisReply(redisCommand(rc, statement)); - turnFreeRedisReply(redisCommand(rc, "save")); + if (rc) { + char statement[TURN_LONG_STRING_SIZE]; + snprintf(statement, sizeof(statement), + "hmset turn/oauth/kid/%s ikm_key %s as_rs_alg %s timestamp %llu lifetime %lu realm %s", key->kid, + key->ikm_key, key->as_rs_alg, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, + key->realm); + turnFreeRedisReply(redisCommand(rc, statement)); + turnFreeRedisReply(redisCommand(rc, "save")); ret = 0; } return ret; } - + static int redis_del_user(uint8_t *usname, uint8_t *realm) { int ret = -1; - redisContext *rc = get_redis_connection(); - if(rc) { - char statement[TURN_LONG_STRING_SIZE]; - { - snprintf(statement,sizeof(statement),"del turn/realm/%s/user/%s/key",(char*)realm,usname); - turnFreeRedisReply(redisCommand(rc, statement)); - } + redisContext *rc = get_redis_connection(); + if (rc) { + char statement[TURN_LONG_STRING_SIZE]; + { + snprintf(statement, sizeof(statement), "del turn/realm/%s/user/%s/key", (char *)realm, usname); + turnFreeRedisReply(redisCommand(rc, statement)); + } - turnFreeRedisReply(redisCommand(rc, "save")); + turnFreeRedisReply(redisCommand(rc, "save")); ret = 0; - } + } return ret; } static int redis_del_oauth_key(const uint8_t *kid) { int ret = -1; redisContext *rc = get_redis_connection(); - if(rc) { - char statement[TURN_LONG_STRING_SIZE]; - snprintf(statement,sizeof(statement),"del turn/oauth/kid/%s",(const char*)kid); - turnFreeRedisReply(redisCommand(rc, statement)); - turnFreeRedisReply(redisCommand(rc, "save")); + if (rc) { + char statement[TURN_LONG_STRING_SIZE]; + snprintf(statement, sizeof(statement), "del turn/oauth/kid/%s", (const char *)kid); + turnFreeRedisReply(redisCommand(rc, statement)); + turnFreeRedisReply(redisCommand(rc, "save")); ret = 0; } return ret; } - -static int redis_list_users(uint8_t *realm, secrets_list_t *users, secrets_list_t *realms) -{ - int ret = -1; - redisContext *rc = get_redis_connection(); - uint8_t realm0[STUN_MAX_REALM_SIZE+1] = "\0"; - if(!realm) realm=realm0; +static int redis_list_users(uint8_t *realm, secrets_list_t *users, secrets_list_t *realms) { + int ret = -1; + redisContext *rc = get_redis_connection(); - if(rc) { - secrets_list_t keys; - size_t isz = 0; + uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0"; + if (!realm) + realm = realm0; - init_secrets_list(&keys); + if (rc) { + secrets_list_t keys; + size_t isz = 0; - redisReply *reply = NULL; + init_secrets_list(&keys); - { - if(realm && realm[0]) { - reply = (redisReply*)redisCommand(rc, "keys turn/realm/%s/user/*/key", (char*)realm); - } else { - reply = (redisReply*)redisCommand(rc, "keys turn/realm/*/user/*/key"); - } + redisReply *reply = NULL; - if(reply) { + { + if (realm && realm[0]) { + reply = (redisReply *)redisCommand(rc, "keys turn/realm/%s/user/*/key", (char *)realm); + } else { + reply = (redisReply *)redisCommand(rc, "keys turn/realm/*/user/*/key"); + } - if (reply->type == REDIS_REPLY_ERROR) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); - else if (reply->type != REDIS_REPLY_ARRAY) { - if (reply->type != REDIS_REPLY_NIL) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); - } else { - size_t i; - for (i = 0; i < reply->elements; ++i) { - add_to_secrets_list(&keys,reply->element[i]->str); - } - } - turnFreeRedisReply(reply); - } - } + if (reply) { - size_t rhsz=strlen("turn/realm/"); - size_t uhsz = strlen("user/"); + if (reply->type == REDIS_REPLY_ERROR) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); + else if (reply->type != REDIS_REPLY_ARRAY) { + if (reply->type != REDIS_REPLY_NIL) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); + } else { + size_t i; + for (i = 0; i < reply->elements; ++i) { + add_to_secrets_list(&keys, reply->element[i]->str); + } + } + turnFreeRedisReply(reply); + } + } - for(isz=0;isztype == REDIS_REPLY_ERROR) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); - } else if (reply->type != REDIS_REPLY_ARRAY) { - if (reply->type != REDIS_REPLY_NIL) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); - } - } else { - size_t i; - for (i = 0; i < reply->elements; ++i) { - add_to_secrets_list(&keys,reply->element[i]->str); - } - } - turnFreeRedisReply(reply); - } + if (reply->type == REDIS_REPLY_ERROR) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); + } else if (reply->type != REDIS_REPLY_ARRAY) { + if (reply->type != REDIS_REPLY_NIL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); + } + } else { + size_t i; + for (i = 0; i < reply->elements; ++i) { + add_to_secrets_list(&keys, reply->element[i]->str); + } + } + turnFreeRedisReply(reply); + } } - for(isz=0;iszkid); - add_to_secrets_list(teas,key->as_rs_alg); - add_to_secrets_list(realms,key->realm); - { - char ts[256]; - snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp); - add_to_secrets_list(tss,ts); - } - { - char lt[256]; - snprintf(lt,sizeof(lt)-1,"%lu",(unsigned long)key->lifetime); - add_to_secrets_list(lts,lt); - } - } else { - printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, realm=%s\n", - key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, - key->as_rs_alg,key->realm); - } - } + for (isz = 0; isz < keys.sz; ++isz) { + char *s = keys.secrets[isz]; + s += strlen("turn/oauth/kid/"); + oauth_key_data_raw key_; + oauth_key_data_raw *key = &key_; + if (redis_get_oauth_key((const uint8_t *)s, key) == 0) { + if (kids) { + add_to_secrets_list(kids, key->kid); + add_to_secrets_list(teas, key->as_rs_alg); + add_to_secrets_list(realms, key->realm); + { + char ts[256]; + snprintf(ts, sizeof(ts) - 1, "%llu", (unsigned long long)key->timestamp); + add_to_secrets_list(tss, ts); + } + { + char lt[256]; + snprintf(lt, sizeof(lt) - 1, "%lu", (unsigned long)key->lifetime); + add_to_secrets_list(lts, lt); + } + } else { + printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, realm=%s\n", key->kid, key->ikm_key, + (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->as_rs_alg, key->realm); + } + } } clean_secrets_list(&keys); @@ -695,584 +713,575 @@ static int redis_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secre return ret; } - -static int redis_list_secrets(uint8_t *realm, secrets_list_t *secrets, secrets_list_t *realms) -{ - int ret = -1; +static int redis_list_secrets(uint8_t *realm, secrets_list_t *secrets, secrets_list_t *realms) { + int ret = -1; - uint8_t realm0[STUN_MAX_REALM_SIZE+1] = "\0"; - if(!realm) realm=realm0; + uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0"; + if (!realm) + realm = realm0; - donot_print_connection_success = 1; - redisContext *rc = get_redis_connection(); - if (rc) { - redisReply *reply = NULL; - if (realm && realm[0]) { - reply = (redisReply*) redisCommand(rc, "keys turn/realm/%s/secret", (char*) realm); - } else { - reply = (redisReply*) redisCommand(rc, "keys turn/realm/*/secret"); - } - if (reply) { - secrets_list_t keys; - size_t isz = 0; - char s[257]; + donot_print_connection_success = 1; + redisContext *rc = get_redis_connection(); + if (rc) { + redisReply *reply = NULL; + if (realm && realm[0]) { + reply = (redisReply *)redisCommand(rc, "keys turn/realm/%s/secret", (char *)realm); + } else { + reply = (redisReply *)redisCommand(rc, "keys turn/realm/*/secret"); + } + if (reply) { + secrets_list_t keys; + size_t isz = 0; + char s[257]; - init_secrets_list(&keys); + init_secrets_list(&keys); - if (reply->type == REDIS_REPLY_ERROR) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); - else if (reply->type != REDIS_REPLY_ARRAY) { - if (reply->type != REDIS_REPLY_NIL) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); - } else { - size_t i; - for (i = 0; i < reply->elements; ++i) { - add_to_secrets_list(&keys, reply->element[i]->str); - } - } + if (reply->type == REDIS_REPLY_ERROR) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); + else if (reply->type != REDIS_REPLY_ARRAY) { + if (reply->type != REDIS_REPLY_NIL) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); + } else { + size_t i; + for (i = 0; i < reply->elements; ++i) { + add_to_secrets_list(&keys, reply->element[i]->str); + } + } - size_t rhsz=strlen("turn/realm/"); + size_t rhsz = strlen("turn/realm/"); - for (isz = 0; isz < keys.sz; ++isz) { - snprintf(s, sizeof(s), "smembers %s", keys.secrets[isz]); - redisReply *rget = (redisReply *) redisCommand(rc, s); - if (rget) { - if (rget->type == REDIS_REPLY_ERROR) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", rget->str); - } else if (rget->type == REDIS_REPLY_STRING) { - printf("%s\n", rget->str); - } else if (rget->type != REDIS_REPLY_ARRAY) { - if (rget->type != REDIS_REPLY_NIL) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", rget->type); - } else { + for (isz = 0; isz < keys.sz; ++isz) { + snprintf(s, sizeof(s), "smembers %s", keys.secrets[isz]); + redisReply *rget = (redisReply *)redisCommand(rc, s); + if (rget) { + if (rget->type == REDIS_REPLY_ERROR) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", rget->str); + } else if (rget->type == REDIS_REPLY_STRING) { + printf("%s\n", rget->str); + } else if (rget->type != REDIS_REPLY_ARRAY) { + if (rget->type != REDIS_REPLY_NIL) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", rget->type); + } else { - char *s = keys.secrets[isz]; + char *s = keys.secrets[isz]; - char *sh = strstr(s,"turn/realm/"); - if(sh != s) continue; - sh += rhsz; - char* st = strchr(sh,'/'); - if(!st) continue; - *st=0; - const char *rval = sh; + char *sh = strstr(s, "turn/realm/"); + if (sh != s) + continue; + sh += rhsz; + char *st = strchr(sh, '/'); + if (!st) + continue; + *st = 0; + const char *rval = sh; - size_t i; - for (i = 0; i < rget->elements; ++i) { - const char *kval = rget->element[i]->str; - if(secrets) { - add_to_secrets_list(secrets,kval); - if(realms) { - if(rval && *rval) { - add_to_secrets_list(realms,rval); - } else { - add_to_secrets_list(realms,(char*)realm); - } - } - } else { - printf("%s[%s]\n", kval, rval); - } - } - } - } - turnFreeRedisReply(rget); - } + size_t i; + for (i = 0; i < rget->elements; ++i) { + const char *kval = rget->element[i]->str; + if (secrets) { + add_to_secrets_list(secrets, kval); + if (realms) { + if (rval && *rval) { + add_to_secrets_list(realms, rval); + } else { + add_to_secrets_list(realms, (char *)realm); + } + } + } else { + printf("%s[%s]\n", kval, rval); + } + } + } + } + turnFreeRedisReply(rget); + } - clean_secrets_list(&keys); + clean_secrets_list(&keys); - turnFreeRedisReply(reply); - ret = 0; - } - } - return ret; -} - - -static int redis_del_secret(uint8_t *secret, uint8_t *realm) -{ - int ret = -1; - donot_print_connection_success = 1; - redisContext *rc = get_redis_connection(); - if (rc) { - turnFreeRedisReply(redisCommand(rc, "srem turn/realm/%s/secret %s", (char*) realm, (char*) secret)); - turnFreeRedisReply(redisCommand(rc, "save")); - ret = 0; - } - return ret; -} - - -static int redis_set_secret(uint8_t *secret, uint8_t *realm) -{ - int ret = -1; - donot_print_connection_success = 1; - redisContext *rc = get_redis_connection(); - if (rc) { - char s[TURN_LONG_STRING_SIZE]; - - redis_del_secret(secret, realm); - - snprintf(s, sizeof(s), "sadd turn/realm/%s/secret %s", (char*) realm, secret); - - turnFreeRedisReply(redisCommand(rc, s)); - turnFreeRedisReply(redisCommand(rc, "save")); - ret = 0; - } - return ret; + turnFreeRedisReply(reply); + ret = 0; + } + } + return ret; } -static int redis_set_permission_ip(const char *kind, uint8_t *realm, const char* ip, int del) -{ - int ret = -1; - - uint8_t realm0[STUN_MAX_REALM_SIZE+1] = "\0"; - if(!realm) realm=realm0; - - donot_print_connection_success = 1; - - redisContext *rc = get_redis_connection(); - if (rc) { - char s[TURN_LONG_STRING_SIZE]; - - if(del) { - snprintf(s, sizeof(s), "srem turn/realm/%s/%s-peer-ip %s", (char*) realm, kind, ip); - } else { - snprintf(s, sizeof(s), "sadd turn/realm/%s/%s-peer-ip %s", (char*) realm, kind, ip); - } - - turnFreeRedisReply(redisCommand(rc, s)); - turnFreeRedisReply(redisCommand(rc, "save")); - ret = 0; - } - return ret; +static int redis_del_secret(uint8_t *secret, uint8_t *realm) { + int ret = -1; + donot_print_connection_success = 1; + redisContext *rc = get_redis_connection(); + if (rc) { + turnFreeRedisReply(redisCommand(rc, "srem turn/realm/%s/secret %s", (char *)realm, (char *)secret)); + turnFreeRedisReply(redisCommand(rc, "save")); + ret = 0; + } + return ret; } - + +static int redis_set_secret(uint8_t *secret, uint8_t *realm) { + int ret = -1; + donot_print_connection_success = 1; + redisContext *rc = get_redis_connection(); + if (rc) { + char s[TURN_LONG_STRING_SIZE]; + + redis_del_secret(secret, realm); + + snprintf(s, sizeof(s), "sadd turn/realm/%s/secret %s", (char *)realm, secret); + + turnFreeRedisReply(redisCommand(rc, s)); + turnFreeRedisReply(redisCommand(rc, "save")); + ret = 0; + } + return ret; +} + +static int redis_set_permission_ip(const char *kind, uint8_t *realm, const char *ip, int del) { + int ret = -1; + + uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0"; + if (!realm) + realm = realm0; + + donot_print_connection_success = 1; + + redisContext *rc = get_redis_connection(); + if (rc) { + char s[TURN_LONG_STRING_SIZE]; + + if (del) { + snprintf(s, sizeof(s), "srem turn/realm/%s/%s-peer-ip %s", (char *)realm, kind, ip); + } else { + snprintf(s, sizeof(s), "sadd turn/realm/%s/%s-peer-ip %s", (char *)realm, kind, ip); + } + + turnFreeRedisReply(redisCommand(rc, s)); + turnFreeRedisReply(redisCommand(rc, "save")); + ret = 0; + } + return ret; +} + static int redis_add_origin(uint8_t *origin, uint8_t *realm) { int ret = -1; - redisContext *rc = get_redis_connection(); - if(rc) { - char s[TURN_LONG_STRING_SIZE]; + redisContext *rc = get_redis_connection(); + if (rc) { + char s[TURN_LONG_STRING_SIZE]; - snprintf(s,sizeof(s),"set turn/origin/%s %s", (char*)origin, (char*)realm); + snprintf(s, sizeof(s), "set turn/origin/%s %s", (char *)origin, (char *)realm); - turnFreeRedisReply(redisCommand(rc, s)); - turnFreeRedisReply(redisCommand(rc, "save")); + turnFreeRedisReply(redisCommand(rc, s)); + turnFreeRedisReply(redisCommand(rc, "save")); ret = 0; - } + } return ret; } - + static int redis_del_origin(uint8_t *origin) { int ret = -1; - redisContext *rc = get_redis_connection(); - if(rc) { - char s[TURN_LONG_STRING_SIZE]; + redisContext *rc = get_redis_connection(); + if (rc) { + char s[TURN_LONG_STRING_SIZE]; - snprintf(s,sizeof(s),"del turn/origin/%s", (char*)origin); + snprintf(s, sizeof(s), "del turn/origin/%s", (char *)origin); - turnFreeRedisReply(redisCommand(rc, s)); - turnFreeRedisReply(redisCommand(rc, "save")); + turnFreeRedisReply(redisCommand(rc, s)); + turnFreeRedisReply(redisCommand(rc, "save")); ret = 0; - } + } return ret; } - -static int redis_list_origins(uint8_t *realm, secrets_list_t *origins, secrets_list_t *realms) -{ - int ret = -1; - uint8_t realm0[STUN_MAX_REALM_SIZE+1] = "\0"; - if(!realm) realm=realm0; - - donot_print_connection_success = 1; - - redisContext *rc = get_redis_connection(); - if(rc) { - secrets_list_t keys; - size_t isz = 0; - - init_secrets_list(&keys); - - redisReply *reply = NULL; - - { - reply = (redisReply*)redisCommand(rc, "keys turn/origin/*"); - if(reply) { - - if (reply->type == REDIS_REPLY_ERROR) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); - else if (reply->type != REDIS_REPLY_ARRAY) { - if (reply->type != REDIS_REPLY_NIL) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); - } else { - size_t i; - size_t offset = strlen("turn/origin/"); - for (i = 0; i < reply->elements; ++i) { - add_to_secrets_list(&keys,reply->element[i]->str+offset); - } - } - turnFreeRedisReply(reply); - } - } - - for(isz=0;isztype == REDIS_REPLY_ERROR) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); - else if (reply->type != REDIS_REPLY_STRING) { - if (reply->type != REDIS_REPLY_NIL) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); - } else { - if(!(realm && realm[0] && strcmp((char*)realm,reply->str))) { - if(origins) { - add_to_secrets_list(origins,o); - if(realms) { - add_to_secrets_list(realms,reply->str); - } - } else { - printf("%s ==>> %s\n",o,reply->str); - } - } - } - turnFreeRedisReply(reply); - } - } - - clean_secrets_list(&keys); - ret = 0; - } - return ret; -} - -static int redis_set_realm_option_one(uint8_t *realm, unsigned long value, const char* opt) { +static int redis_list_origins(uint8_t *realm, secrets_list_t *origins, secrets_list_t *realms) { int ret = -1; - redisContext *rc = get_redis_connection(); - if(rc) { - char s[TURN_LONG_STRING_SIZE]; - if(value>0) - snprintf(s,sizeof(s),"set turn/realm/%s/%s %lu", (char*)realm, opt, (unsigned long)value); - else - snprintf(s,sizeof(s),"del turn/realm/%s/%s", (char*)realm, opt); + uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0"; + if (!realm) + realm = realm0; - turnFreeRedisReply(redisCommand(rc, s)); - turnFreeRedisReply(redisCommand(rc, "save")); + donot_print_connection_success = 1; + + redisContext *rc = get_redis_connection(); + if (rc) { + secrets_list_t keys; + size_t isz = 0; + + init_secrets_list(&keys); + + redisReply *reply = NULL; + + { + reply = (redisReply *)redisCommand(rc, "keys turn/origin/*"); + if (reply) { + + if (reply->type == REDIS_REPLY_ERROR) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); + else if (reply->type != REDIS_REPLY_ARRAY) { + if (reply->type != REDIS_REPLY_NIL) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); + } else { + size_t i; + size_t offset = strlen("turn/origin/"); + for (i = 0; i < reply->elements; ++i) { + add_to_secrets_list(&keys, reply->element[i]->str + offset); + } + } + turnFreeRedisReply(reply); + } + } + + for (isz = 0; isz < keys.sz; ++isz) { + + char *o = keys.secrets[isz]; + + reply = (redisReply *)redisCommand(rc, "get turn/origin/%s", o); + if (reply) { + + if (reply->type == REDIS_REPLY_ERROR) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); + else if (reply->type != REDIS_REPLY_STRING) { + if (reply->type != REDIS_REPLY_NIL) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); + } else { + if (!(realm && realm[0] && strcmp((char *)realm, reply->str))) { + if (origins) { + add_to_secrets_list(origins, o); + if (realms) { + add_to_secrets_list(realms, reply->str); + } + } else { + printf("%s ==>> %s\n", o, reply->str); + } + } + } + turnFreeRedisReply(reply); + } + } + + clean_secrets_list(&keys); ret = 0; - } + } return ret; } - + +static int redis_set_realm_option_one(uint8_t *realm, unsigned long value, const char *opt) { + int ret = -1; + redisContext *rc = get_redis_connection(); + if (rc) { + char s[TURN_LONG_STRING_SIZE]; + + if (value > 0) + snprintf(s, sizeof(s), "set turn/realm/%s/%s %lu", (char *)realm, opt, (unsigned long)value); + else + snprintf(s, sizeof(s), "del turn/realm/%s/%s", (char *)realm, opt); + + turnFreeRedisReply(redisCommand(rc, s)); + turnFreeRedisReply(redisCommand(rc, "save")); + ret = 0; + } + return ret; +} + static int redis_list_realm_options(uint8_t *realm) { int ret = -1; - donot_print_connection_success = 1; - redisContext *rc = get_redis_connection(); - if(rc) { - secrets_list_t keys; - size_t isz = 0; + donot_print_connection_success = 1; + redisContext *rc = get_redis_connection(); + if (rc) { + secrets_list_t keys; + size_t isz = 0; - init_secrets_list(&keys); + init_secrets_list(&keys); - redisReply *reply = NULL; + redisReply *reply = NULL; - { - if(realm && realm[0]) { - reply = (redisReply*)redisCommand(rc, "keys turn/realm/%s/*",realm); - } else { - reply = (redisReply*)redisCommand(rc, "keys turn/realm/*"); - } - if(reply) { + { + if (realm && realm[0]) { + reply = (redisReply *)redisCommand(rc, "keys turn/realm/%s/*", realm); + } else { + reply = (redisReply *)redisCommand(rc, "keys turn/realm/*"); + } + if (reply) { - if (reply->type == REDIS_REPLY_ERROR) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); - else if (reply->type != REDIS_REPLY_ARRAY) { - if (reply->type != REDIS_REPLY_NIL) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); - } else { - size_t i; - for (i = 0; i < reply->elements; ++i) { - if(strstr(reply->element[i]->str,"/max-bps")|| - strstr(reply->element[i]->str,"/total-quota")|| - strstr(reply->element[i]->str,"/user-quota")) { - add_to_secrets_list(&keys,reply->element[i]->str); - } - } - } - turnFreeRedisReply(reply); - } - } + if (reply->type == REDIS_REPLY_ERROR) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); + else if (reply->type != REDIS_REPLY_ARRAY) { + if (reply->type != REDIS_REPLY_NIL) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); + } else { + size_t i; + for (i = 0; i < reply->elements; ++i) { + if (strstr(reply->element[i]->str, "/max-bps") || strstr(reply->element[i]->str, "/total-quota") || + strstr(reply->element[i]->str, "/user-quota")) { + add_to_secrets_list(&keys, reply->element[i]->str); + } + } + } + turnFreeRedisReply(reply); + } + } - size_t offset = strlen("turn/realm/"); + size_t offset = strlen("turn/realm/"); - for(isz=0;isztype == REDIS_REPLY_ERROR) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); - else if (reply->type != REDIS_REPLY_STRING) { - if (reply->type != REDIS_REPLY_NIL) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); - } else { - printf("%s = %s\n",o+offset,reply->str); - } - turnFreeRedisReply(reply); - } - } + if (reply->type == REDIS_REPLY_ERROR) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); + else if (reply->type != REDIS_REPLY_STRING) { + if (reply->type != REDIS_REPLY_NIL) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); + } else { + printf("%s = %s\n", o + offset, reply->str); + } + turnFreeRedisReply(reply); + } + } - clean_secrets_list(&keys); + clean_secrets_list(&keys); ret = 0; - } + } return ret; } - -static void redis_auth_ping(void * rch) { - UNUSED_ARG(rch); - redisContext *rc = get_redis_connection(); - if(rc) { - turnFreeRedisReply(redisCommand(rc, "keys turn/origin/*")); - } + +static void redis_auth_ping(void *rch) { + UNUSED_ARG(rch); + redisContext *rc = get_redis_connection(); + if (rc) { + turnFreeRedisReply(redisCommand(rc, "keys turn/origin/*")); + } } - +static int redis_get_ip_list(const char *kind, ip_range_list_t *list) { + int ret = -1; + redisContext *rc = get_redis_connection(); + if (rc) { + char statement[TURN_LONG_STRING_SIZE]; + const char *header = "turn/realm/"; + size_t header_len = strlen(header); + snprintf(statement, sizeof(statement), "keys %s*/%s-peer-ip", header, kind); + redisReply *reply = (redisReply *)redisCommand(rc, statement); + if (reply) { + secrets_list_t keys; + size_t isz = 0; + char s[257]; -static int redis_get_ip_list(const char *kind, ip_range_list_t * list) -{ - int ret = -1; - redisContext *rc = get_redis_connection(); - if (rc) { - char statement[TURN_LONG_STRING_SIZE]; - const char* header = "turn/realm/"; - size_t header_len = strlen(header); - snprintf(statement, sizeof(statement), "keys %s*/%s-peer-ip", header,kind); - redisReply *reply = (redisReply*) redisCommand(rc, statement); - if (reply) { - secrets_list_t keys; - size_t isz = 0; - char s[257]; + init_secrets_list(&keys); - init_secrets_list(&keys); + if (reply->type == REDIS_REPLY_ERROR) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); + else if (reply->type != REDIS_REPLY_ARRAY) { + if (reply->type != REDIS_REPLY_NIL) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); + } else { + size_t i; + for (i = 0; i < reply->elements; ++i) { + add_to_secrets_list(&keys, reply->element[i]->str); + } + } - if (reply->type == REDIS_REPLY_ERROR) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); - else if (reply->type != REDIS_REPLY_ARRAY) { - if (reply->type != REDIS_REPLY_NIL) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); - } else { - size_t i; - for (i = 0; i < reply->elements; ++i) { - add_to_secrets_list(&keys, reply->element[i]->str); - } - } + for (isz = 0; isz < keys.sz; ++isz) { - for (isz = 0; isz < keys.sz; ++isz) { + char *realm = NULL; - char *realm = NULL; + snprintf(s, sizeof(s), "smembers %s", keys.secrets[isz]); - snprintf(s, sizeof(s), "smembers %s", keys.secrets[isz]); + redisReply *rget = (redisReply *)redisCommand(rc, s); - redisReply *rget = (redisReply *) redisCommand(rc, s); + char *ptr = ((char *)keys.secrets[isz]) + header_len; + char *sep = strstr(ptr, "/"); + if (sep) { + *sep = 0; + realm = ptr; + } - char *ptr = ((char*)keys.secrets[isz])+header_len; - char *sep = strstr(ptr, "/"); - if (sep) { - *sep = 0; - realm = ptr; - } + if (rget) { + if (rget->type == REDIS_REPLY_ERROR) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", rget->str); + } else if (rget->type == REDIS_REPLY_STRING) { + add_ip_list_range(rget->str, realm, list); + } else if (rget->type != REDIS_REPLY_ARRAY) { + if (rget->type != REDIS_REPLY_NIL) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", rget->type); + } else { + size_t i; + for (i = 0; i < rget->elements; ++i) { + add_ip_list_range(rget->element[i]->str, realm, list); + } + } + turnFreeRedisReply(rget); + } - if (rget) { - if (rget->type == REDIS_REPLY_ERROR) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", rget->str); - } else if (rget->type == REDIS_REPLY_STRING) { - add_ip_list_range(rget->str, realm, list); - } else if (rget->type != REDIS_REPLY_ARRAY) { - if (rget->type != REDIS_REPLY_NIL) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", rget->type); - } else { - size_t i; - for (i = 0; i < rget->elements; ++i) { - add_ip_list_range(rget->element[i]->str, realm, list); - } - } - turnFreeRedisReply(rget); - } + if (sep) { + *sep = '/'; + } + } - if(sep) { - *sep='/'; - } - } + clean_secrets_list(&keys); - clean_secrets_list(&keys); - - turnFreeRedisReply(reply); - ret = 0; - } - } - return ret; + turnFreeRedisReply(reply); + ret = 0; + } + } + return ret; } - -static void redis_reread_realms(secrets_list_t * realms_list) { - redisContext *rc = get_redis_connection(); - if (rc) { - redisReply *reply = (redisReply*) redisCommand(rc, "keys turn/origin/*"); - if (reply) { +static void redis_reread_realms(secrets_list_t *realms_list) { + redisContext *rc = get_redis_connection(); + if (rc) { - ur_string_map *o_to_realm_new = ur_string_map_create(free); + redisReply *reply = (redisReply *)redisCommand(rc, "keys turn/origin/*"); + if (reply) { - secrets_list_t keys; + ur_string_map *o_to_realm_new = ur_string_map_create(free); - init_secrets_list(&keys); + secrets_list_t keys; - size_t isz = 0; + init_secrets_list(&keys); - char s[1025]; + size_t isz = 0; - if (reply->type == REDIS_REPLY_ERROR) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); - else if (reply->type != REDIS_REPLY_ARRAY) { - if (reply->type != REDIS_REPLY_NIL) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); - } else { - size_t i; - for (i = 0; i < reply->elements; ++i) { - add_to_secrets_list(&keys, reply->element[i]->str); - } - } + char s[1025]; - size_t offset = strlen("turn/origin/"); + if (reply->type == REDIS_REPLY_ERROR) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); + else if (reply->type != REDIS_REPLY_ARRAY) { + if (reply->type != REDIS_REPLY_NIL) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); + } else { + size_t i; + for (i = 0; i < reply->elements; ++i) { + add_to_secrets_list(&keys, reply->element[i]->str); + } + } - for (isz = 0; isz < keys.sz; ++isz) { - char *origin = keys.secrets[isz] + offset; - snprintf(s, sizeof(s), "get %s", keys.secrets[isz]); - redisReply *rget = (redisReply *) redisCommand(rc, s); - if (rget) { - if (rget->type == REDIS_REPLY_ERROR) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", rget->str); - else if (rget->type != REDIS_REPLY_STRING) { - if (rget->type != REDIS_REPLY_NIL) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", rget->type); - } else { - get_realm(rget->str); - ur_string_map_value_type value = strdup(rget->str); - ur_string_map_put(o_to_realm_new, (ur_string_map_key_type) origin, value); - } - turnFreeRedisReply(rget); - } - } + size_t offset = strlen("turn/origin/"); - clean_secrets_list(&keys); + for (isz = 0; isz < keys.sz; ++isz) { + char *origin = keys.secrets[isz] + offset; + snprintf(s, sizeof(s), "get %s", keys.secrets[isz]); + redisReply *rget = (redisReply *)redisCommand(rc, s); + if (rget) { + if (rget->type == REDIS_REPLY_ERROR) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", rget->str); + else if (rget->type != REDIS_REPLY_STRING) { + if (rget->type != REDIS_REPLY_NIL) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", rget->type); + } else { + get_realm(rget->str); + ur_string_map_value_type value = strdup(rget->str); + ur_string_map_put(o_to_realm_new, (ur_string_map_key_type)origin, value); + } + turnFreeRedisReply(rget); + } + } - update_o_to_realm(o_to_realm_new); + clean_secrets_list(&keys); - turnFreeRedisReply(reply); - } + update_o_to_realm(o_to_realm_new); - { - size_t i = 0; - size_t rlsz = 0; + turnFreeRedisReply(reply); + } - lock_realms(); - rlsz = realms_list->sz; - unlock_realms(); + { + size_t i = 0; + size_t rlsz = 0; - for (i = 0; isecrets[i]; - realm_params_t* rp = get_realm(realm); - { - unsigned long value = 0; - if(!set_redis_realm_opt(realm,"max-bps",&value)) { - lock_realms(); - rp->options.perf_options.max_bps = turn_params.max_bps; - unlock_realms(); - } else { - rp->options.perf_options.max_bps = (band_limit_t)value; - } - } - { - unsigned long value = 0; - if(!set_redis_realm_opt(realm,"total-quota",&value)) { - lock_realms(); - rp->options.perf_options.total_quota = turn_params.total_quota; - unlock_realms(); - } else { - rp->options.perf_options.total_quota = (vint)value; - } - } - { - unsigned long value = 0; - if(!set_redis_realm_opt(realm,"user-quota",&value)) { - lock_realms(); - rp->options.perf_options.user_quota = turn_params.user_quota; - unlock_realms(); - } else { - rp->options.perf_options.user_quota = (vint)value; - } - } - } - } - } + lock_realms(); + rlsz = realms_list->sz; + unlock_realms(); + + for (i = 0; i < rlsz; ++i) { + char *realm = realms_list->secrets[i]; + realm_params_t *rp = get_realm(realm); + { + unsigned long value = 0; + if (!set_redis_realm_opt(realm, "max-bps", &value)) { + lock_realms(); + rp->options.perf_options.max_bps = turn_params.max_bps; + unlock_realms(); + } else { + rp->options.perf_options.max_bps = (band_limit_t)value; + } + } + { + unsigned long value = 0; + if (!set_redis_realm_opt(realm, "total-quota", &value)) { + lock_realms(); + rp->options.perf_options.total_quota = turn_params.total_quota; + unlock_realms(); + } else { + rp->options.perf_options.total_quota = (vint)value; + } + } + { + unsigned long value = 0; + if (!set_redis_realm_opt(realm, "user-quota", &value)) { + lock_realms(); + rp->options.perf_options.user_quota = turn_params.user_quota; + unlock_realms(); + } else { + rp->options.perf_options.user_quota = (vint)value; + } + } + } + } + } } ///////////////////////////////////////////////////// -static int redis_get_admin_user(const uint8_t *usname, uint8_t *realm, password_t pwd) -{ - int ret = -1; - redisContext * rc = get_redis_connection(); - if(rc) { - char s[TURN_LONG_STRING_SIZE]; - realm[0]=0; - pwd[0]=0; - snprintf(s,sizeof(s),"hgetall turn/admin_user/%s", (const char*)usname); - redisReply *reply = (redisReply *)redisCommand(rc, s); - if(reply) { - if (reply->type == REDIS_REPLY_ERROR) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); - else if (reply->type != REDIS_REPLY_ARRAY) { - if (reply->type != REDIS_REPLY_NIL) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); - } else if(reply->elements > 1) { - size_t i; - for (i = 0; i < (reply->elements)/2; ++i) { - char *kw = reply->element[2*i]->str; - char *val = reply->element[2*i+1]->str; - if(kw) { - if(!strcmp(kw,"realm")) { - strncpy((char*)realm,val,STUN_MAX_REALM_SIZE); - } else if(!strcmp(kw,"password")) { - strncpy((char*)pwd,val,STUN_MAX_PWD_SIZE); - ret = 0; - } - } - } - } - turnFreeRedisReply(reply); - } - } - return ret; +static int redis_get_admin_user(const uint8_t *usname, uint8_t *realm, password_t pwd) { + int ret = -1; + redisContext *rc = get_redis_connection(); + if (rc) { + char s[TURN_LONG_STRING_SIZE]; + realm[0] = 0; + pwd[0] = 0; + snprintf(s, sizeof(s), "hgetall turn/admin_user/%s", (const char *)usname); + redisReply *reply = (redisReply *)redisCommand(rc, s); + if (reply) { + if (reply->type == REDIS_REPLY_ERROR) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); + else if (reply->type != REDIS_REPLY_ARRAY) { + if (reply->type != REDIS_REPLY_NIL) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); + } else if (reply->elements > 1) { + size_t i; + for (i = 0; i < (reply->elements) / 2; ++i) { + char *kw = reply->element[2 * i]->str; + char *val = reply->element[2 * i + 1]->str; + if (kw) { + if (!strcmp(kw, "realm")) { + strncpy((char *)realm, val, STUN_MAX_REALM_SIZE); + } else if (!strcmp(kw, "password")) { + strncpy((char *)pwd, val, STUN_MAX_PWD_SIZE); + ret = 0; + } + } + } + } + turnFreeRedisReply(reply); + } + } + return ret; } -static int redis_set_admin_user(const uint8_t *usname, const uint8_t *realm, const password_t pwd) -{ +static int redis_set_admin_user(const uint8_t *usname, const uint8_t *realm, const password_t pwd) { int ret = -1; donot_print_connection_success = 1; redisContext *rc = get_redis_connection(); - if(rc) { - char statement[TURN_LONG_STRING_SIZE]; - if(realm[0]) { - snprintf(statement,sizeof(statement),"hmset turn/admin_user/%s realm %s password %s",usname,realm,pwd); - } else { - snprintf(statement,sizeof(statement),"hmset turn/admin_user/%s password %s",usname,pwd); - } - turnFreeRedisReply(redisCommand(rc, statement)); - turnFreeRedisReply(redisCommand(rc, "save")); + if (rc) { + char statement[TURN_LONG_STRING_SIZE]; + if (realm[0]) { + snprintf(statement, sizeof(statement), "hmset turn/admin_user/%s realm %s password %s", usname, realm, pwd); + } else { + snprintf(statement, sizeof(statement), "hmset turn/admin_user/%s password %s", usname, pwd); + } + turnFreeRedisReply(redisCommand(rc, statement)); + turnFreeRedisReply(redisCommand(rc, "save")); ret = 0; } return ret; @@ -1282,18 +1291,17 @@ static int redis_del_admin_user(const uint8_t *usname) { int ret = -1; donot_print_connection_success = 1; redisContext *rc = get_redis_connection(); - if(rc) { - char statement[TURN_LONG_STRING_SIZE]; - snprintf(statement,sizeof(statement),"del turn/admin_user/%s",(const char*)usname); - turnFreeRedisReply(redisCommand(rc, statement)); - turnFreeRedisReply(redisCommand(rc, "save")); + if (rc) { + char statement[TURN_LONG_STRING_SIZE]; + snprintf(statement, sizeof(statement), "del turn/admin_user/%s", (const char *)usname); + turnFreeRedisReply(redisCommand(rc, statement)); + turnFreeRedisReply(redisCommand(rc, "save")); ret = 0; } return ret; } -static int redis_list_admin_users(int no_print) -{ +static int redis_list_admin_users(int no_print) { int ret = -1; donot_print_connection_success = 1; redisContext *rc = get_redis_connection(); @@ -1301,45 +1309,45 @@ static int redis_list_admin_users(int no_print) size_t isz = 0; init_secrets_list(&keys); - if(rc) { + if (rc) { - redisReply *reply = NULL; + redisReply *reply = NULL; - reply = (redisReply*)redisCommand(rc, "keys turn/admin_user/*"); - if(reply) { + reply = (redisReply *)redisCommand(rc, "keys turn/admin_user/*"); + if (reply) { - if (reply->type == REDIS_REPLY_ERROR) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); - } else if (reply->type != REDIS_REPLY_ARRAY) { - if (reply->type != REDIS_REPLY_NIL) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); - } - } else { - size_t i; - for (i = 0; i < reply->elements; ++i) { - add_to_secrets_list(&keys,reply->element[i]->str); - } - } - turnFreeRedisReply(reply); - } + if (reply->type == REDIS_REPLY_ERROR) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str); + } else if (reply->type != REDIS_REPLY_ARRAY) { + if (reply->type != REDIS_REPLY_NIL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type); + } + } else { + size_t i; + for (i = 0; i < reply->elements; ++i) { + add_to_secrets_list(&keys, reply->element[i]->str); + } + } + turnFreeRedisReply(reply); + } } ret = 0; - for(isz=0;isz -#if defined(__unix__) || defined(unix) || defined(__APPLE__) \ - || defined(__DARWIN__) || defined(__MACH__) -#include -#include +#if defined(__unix__) || defined(unix) || defined(__APPLE__) || defined(__DARWIN__) || defined(__MACH__) #include +#include +#include #endif #include @@ -58,66 +57,65 @@ static pthread_t write_thread = {0}; static pthread_t write_thread = 0; #endif -static void sqlite_lock(int write) -{ - pthread_t pths = pthread_self(); +static void sqlite_lock(int write) { + pthread_t pths = pthread_self(); - int can_move = 0; - while (!can_move) { - pthread_mutex_lock(&rc_mutex); + int can_move = 0; + while (!can_move) { + pthread_mutex_lock(&rc_mutex); #if defined(WINDOWS) - pthread_t zero = { 0 }; + pthread_t zero = {0}; #endif - if (write) { - if (( + if (write) { + if (( #if defined(WINDOWS) - pthread_equal(write_thread, zero) + pthread_equal(write_thread, zero) #else - write_thread == 0 + write_thread == 0 #endif - && (read_threads < 1)) || pthread_equal(write_thread, pths)) { - can_move = 1; - ++write_level; - write_thread = pths; - } - } else { - if (( + && (read_threads < 1)) || + pthread_equal(write_thread, pths)) { + can_move = 1; + ++write_level; + write_thread = pths; + } + } else { + if (( #if defined(WINDOWS) - pthread_equal(write_thread, zero)) + pthread_equal(write_thread, zero)) #else - !write_thread) + !write_thread) #endif - || pthread_equal(write_thread, pths)) { - can_move = 1; - ++read_threads; - } - } - if (!can_move) { - pthread_cond_wait(&rc_cond, &rc_mutex); - } - pthread_mutex_unlock(&rc_mutex); - } + || pthread_equal(write_thread, pths)) { + can_move = 1; + ++read_threads; + } + } + if (!can_move) { + pthread_cond_wait(&rc_cond, &rc_mutex); + } + pthread_mutex_unlock(&rc_mutex); + } } -static void sqlite_unlock(int write) -{ - pthread_mutex_lock(&rc_mutex); - if (write) { - if (!(--write_level)) { +static void sqlite_unlock(int write) { + pthread_mutex_lock(&rc_mutex); + if (write) { + if (!(--write_level)) { #if defined(WINDOWS) - pthread_t zero = { 0 }; - write_thread = zero; + pthread_t zero = {0}; + write_thread = zero; #else - write_thread = 0; + write_thread = 0; #endif - pthread_cond_broadcast(&rc_cond); - } - } else { - if (!(--read_threads)) { - pthread_cond_broadcast(&rc_cond); - } - } - pthread_mutex_unlock(&rc_mutex); + pthread_cond_broadcast(&rc_cond); + } + } else { + if (!(--read_threads)) { + pthread_cond_broadcast(&rc_cond); + } + } + pthread_mutex_unlock(&rc_mutex); } ////////////////////////////////////////////////// @@ -125,1257 +123,1235 @@ static void sqlite_unlock(int write) static void sqlite_init_multithreaded(void) { #if defined(SQLITE_CONFIG_MULTITHREAD) - if (sqlite3_threadsafe() > 0) { - int retCode = sqlite3_config(SQLITE_CONFIG_MULTITHREAD); - if (retCode != SQLITE_OK) { - retCode = sqlite3_config(SQLITE_CONFIG_SERIALIZED); - if (retCode != SQLITE_OK) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "setting sqlite thread safe mode to serialized failed!!! return code: %d\n", retCode); - return; - } - } - sqlite3_initialize(); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Your SQLite database is not compiled to be threadsafe.\n"); - return; - } + if (sqlite3_threadsafe() > 0) { + int retCode = sqlite3_config(SQLITE_CONFIG_MULTITHREAD); + if (retCode != SQLITE_OK) { + retCode = sqlite3_config(SQLITE_CONFIG_SERIALIZED); + if (retCode != SQLITE_OK) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "setting sqlite thread safe mode to serialized failed!!! return code: %d\n", + retCode); + return; + } + } + sqlite3_initialize(); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Your SQLite database is not compiled to be threadsafe.\n"); + return; + } #endif - return; + return; } static int donot_print_connection_success = 0; static void fix_user_directory(char *dir0) { - char *dir = dir0; - while(*dir == ' ') ++dir; -#if defined(__unix__) || defined(unix) || defined(__APPLE__) \ - || defined(__DARWIN__) || defined(__MACH__) - if(*dir == '~') { - char *home=getenv("HOME"); - if(!home) { - struct passwd *pwd = getpwuid(getuid()); - if(!pwd) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot figure out the user's HOME directory (1)\n"); - } else { - home = pwd->pw_dir; - if(!home) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot figure out the user's HOME directory\n"); - return; - } - } - } - size_t szh = strlen(home); - size_t sz = strlen(dir0)+1+szh; - char* dir_fixed = (char*)malloc(sz); - strncpy(dir_fixed,home,szh); - strncpy(dir_fixed+szh,dir+1,(sz-szh-1)); - strncpy(dir0,dir_fixed,sz); - free(dir_fixed); - } + char *dir = dir0; + while (*dir == ' ') + ++dir; +#if defined(__unix__) || defined(unix) || defined(__APPLE__) || defined(__DARWIN__) || defined(__MACH__) + if (*dir == '~') { + char *home = getenv("HOME"); + if (!home) { + struct passwd *pwd = getpwuid(getuid()); + if (!pwd) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot figure out the user's HOME directory (1)\n"); + } else { + home = pwd->pw_dir; + if (!home) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot figure out the user's HOME directory\n"); + return; + } + } + } + size_t szh = strlen(home); + size_t sz = strlen(dir0) + 1 + szh; + char *dir_fixed = (char *)malloc(sz); + strncpy(dir_fixed, home, szh); + strncpy(dir_fixed + szh, dir + 1, (sz - szh - 1)); + strncpy(dir0, dir_fixed, sz); + free(dir_fixed); + } #endif } static void init_sqlite_database(sqlite3 *sqliteconnection) { - const char * statements[] = { - "CREATE TABLE turnusers_lt ( realm varchar(127) default '', name varchar(512), hmackey char(128), PRIMARY KEY (realm,name))", - "CREATE TABLE turn_secret (realm varchar(127) default '', value varchar(127), primary key (realm,value))", - "CREATE TABLE allowed_peer_ip (realm varchar(127) default '', ip_range varchar(256), primary key (realm,ip_range))", - "CREATE TABLE denied_peer_ip (realm varchar(127) default '', ip_range varchar(256), primary key (realm,ip_range))", - "CREATE TABLE turn_origin_to_realm (origin varchar(127),realm varchar(127),primary key (origin))", - "CREATE TABLE turn_realm_option (realm varchar(127) default '', opt varchar(32), value varchar(128), primary key (realm,opt))", - "CREATE TABLE oauth_key (kid varchar(128),ikm_key varchar(256),timestamp bigint default 0,lifetime integer default 0,as_rs_alg varchar(64) default '',realm varchar(127) default '',primary key (kid))", - "CREATE TABLE admin_user (name varchar(32), realm varchar(127), password varchar(127), primary key (name))", - NULL - }; + const char *statements[] = { + "CREATE TABLE turnusers_lt ( realm varchar(127) default '', name varchar(512), hmackey char(128), PRIMARY KEY " + "(realm,name))", + "CREATE TABLE turn_secret (realm varchar(127) default '', value varchar(127), primary key (realm,value))", + "CREATE TABLE allowed_peer_ip (realm varchar(127) default '', ip_range varchar(256), primary key " + "(realm,ip_range))", + "CREATE TABLE denied_peer_ip (realm varchar(127) default '', ip_range varchar(256), primary key " + "(realm,ip_range))", + "CREATE TABLE turn_origin_to_realm (origin varchar(127),realm varchar(127),primary key (origin))", + "CREATE TABLE turn_realm_option (realm varchar(127) default '', opt varchar(32), value " + "varchar(128), primary key (realm,opt))", + "CREATE TABLE oauth_key (kid varchar(128),ikm_key varchar(256),timestamp bigint default 0,lifetime integer " + "default 0,as_rs_alg varchar(64) default '',realm varchar(127) default '',primary key (kid))", + "CREATE TABLE admin_user (name varchar(32), realm varchar(127), password varchar(127), primary key (name))", + NULL}; - int i = 0; - while(statements[i]) { - sqlite3_stmt *statement = NULL; - int rc = 0; - if ((rc = sqlite3_prepare(sqliteconnection, statements[i], -1, &statement, 0)) == SQLITE_OK) { - sqlite3_step(statement); - } - sqlite3_finalize(statement); - ++i; - } + int i = 0; + while (statements[i]) { + sqlite3_stmt *statement = NULL; + int rc = 0; + if ((rc = sqlite3_prepare(sqliteconnection, statements[i], -1, &statement, 0)) == SQLITE_OK) { + sqlite3_step(statement); + } + sqlite3_finalize(statement); + ++i; + } } -static sqlite3 * get_sqlite_connection(void) { - static pthread_once_t sqlite_init_once = PTHREAD_ONCE_INIT; +static sqlite3 *get_sqlite_connection(void) { + static pthread_once_t sqlite_init_once = PTHREAD_ONCE_INIT; - persistent_users_db_t *pud = get_persistent_users_db(); + persistent_users_db_t *pud = get_persistent_users_db(); - sqlite3 *sqliteconnection = (sqlite3 *)pthread_getspecific(connection_key); - if(!sqliteconnection) { + sqlite3 *sqliteconnection = (sqlite3 *)pthread_getspecific(connection_key); + if (!sqliteconnection) { - fix_user_directory(pud->userdb); - (void) pthread_once(&sqlite_init_once, sqlite_init_multithreaded); - int rc = sqlite3_open(pud->userdb, &sqliteconnection); - if(!sqliteconnection || (rc != SQLITE_OK)) { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open SQLite DB connection: <%s>, runtime error:\n %s\n (If your intention is to use an SQLite database for the TURN server, then\n check and fix, if necessary, the effective permissions of the TURN server\n process and of the DB directory and then re-start the TURN server)\n",pud->userdb_sanitized,errmsg); - if(sqliteconnection) { - sqlite3_close(sqliteconnection); - sqliteconnection=NULL; - } - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_UNKNOWN; - } else { - init_sqlite_database(sqliteconnection); - if(!donot_print_connection_success){ - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SQLite DB connection success: %s\n",pud->userdb_sanitized); - donot_print_connection_success = 1; - } - } - if(sqliteconnection) { - (void) pthread_setspecific(connection_key, sqliteconnection); - } - } - return sqliteconnection; + fix_user_directory(pud->userdb); + (void)pthread_once(&sqlite_init_once, sqlite_init_multithreaded); + int rc = sqlite3_open(pud->userdb, &sqliteconnection); + if (!sqliteconnection || (rc != SQLITE_OK)) { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC( + TURN_LOG_LEVEL_ERROR, + "Cannot open SQLite DB connection: <%s>, runtime error:\n %s\n (If your intention is to use an SQLite " + "database for the TURN server, then\n check and fix, if necessary, the effective permissions of the TURN " + "server\n process and of the DB directory and then re-start the TURN server)\n", + pud->userdb_sanitized, errmsg); + if (sqliteconnection) { + sqlite3_close(sqliteconnection); + sqliteconnection = NULL; + } + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_UNKNOWN; + } else { + init_sqlite_database(sqliteconnection); + if (!donot_print_connection_success) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SQLite DB connection success: %s\n", pud->userdb_sanitized); + donot_print_connection_success = 1; + } + } + if (sqliteconnection) { + (void)pthread_setspecific(connection_key, sqliteconnection); + } + } + return sqliteconnection; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// -static int sqlite_get_auth_secrets(secrets_list_t *sl, uint8_t *realm) -{ - int ret = -1; - sqlite3 *sqliteconnection = get_sqlite_connection(); - if (sqliteconnection) { - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; - snprintf(statement, sizeof(statement) - 1, "select value from turn_secret where realm='%s'", realm); +static int sqlite_get_auth_secrets(secrets_list_t *sl, uint8_t *realm) { + int ret = -1; + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; + snprintf(statement, sizeof(statement) - 1, "select value from turn_secret where realm='%s'", realm); - sqlite_lock(0); + sqlite_lock(0); - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - int ctotal = sqlite3_column_count(st); - ret = 0; + int ctotal = sqlite3_column_count(st); + ret = 0; - while (ctotal > 0) { + while (ctotal > 0) { - int res = sqlite3_step(st); - if (res == SQLITE_ROW) { + int res = sqlite3_step(st); + if (res == SQLITE_ROW) { - int type = sqlite3_column_type(st, 0); - if (type != SQLITE_NULL) - add_to_secrets_list(sl, (const char*) sqlite3_column_text(st, 0)); + int type = sqlite3_column_type(st, 0); + if (type != SQLITE_NULL) + add_to_secrets_list(sl, (const char *)sqlite3_column_text(st, 0)); - } else if (res == SQLITE_DONE) { - break; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - ret = -1; - break; - } - } - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); + } else if (res == SQLITE_DONE) { + break; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + ret = -1; + break; + } + } + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); - sqlite_unlock(0); - } - return ret; + sqlite_unlock(0); + } + return ret; } -static int sqlite_get_user_key(uint8_t *usname, uint8_t *realm, hmackey_t key) -{ - int ret = -1; - sqlite3 *sqliteconnection = get_sqlite_connection(); - if (sqliteconnection) { - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; - /* direct user input eliminated - there is no SQL injection problem (since version 4.4.5.3) */ - snprintf(statement, sizeof(statement), "select hmackey from turnusers_lt where name='%s' and realm='%s'", usname, realm); +static int sqlite_get_user_key(uint8_t *usname, uint8_t *realm, hmackey_t key) { + int ret = -1; + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; + /* direct user input eliminated - there is no SQL injection problem (since version 4.4.5.3) */ + snprintf(statement, sizeof(statement), "select hmackey from turnusers_lt where name='%s' and realm='%s'", usname, + realm); - sqlite_lock(0); + sqlite_lock(0); - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - int res = sqlite3_step(st); - if (res == SQLITE_ROW) { - char *kval = strdup((const char*) sqlite3_column_text(st, 0)); - size_t sz = get_hmackey_size(SHATYPE_DEFAULT); - if (convert_string_key_to_binary(kval, key, sz) < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key: %s, user %s\n", kval, usname); - } else { - ret = 0; - } - free(kval); - } - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + int res = sqlite3_step(st); + if (res == SQLITE_ROW) { + char *kval = strdup((const char *)sqlite3_column_text(st, 0)); + size_t sz = get_hmackey_size(SHATYPE_DEFAULT); + if (convert_string_key_to_binary(kval, key, sz) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key: %s, user %s\n", kval, usname); + } else { + ret = 0; + } + free(kval); + } + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } - sqlite3_finalize(st); + sqlite3_finalize(st); - sqlite_unlock(0); - } - return ret; + sqlite_unlock(0); + } + return ret; } static int sqlite_get_oauth_key(const uint8_t *kid, oauth_key_data_raw *key) { - int ret = -1; + int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; - /* direct user input eliminated - there is no SQL injection problem (since version 4.4.5.3) */ - snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,realm from oauth_key where kid='%s'",(const char*)kid); + /* direct user input eliminated - there is no SQL injection problem (since version 4.4.5.3) */ + snprintf(statement, sizeof(statement), + "select ikm_key,timestamp,lifetime,as_rs_alg,realm from oauth_key where kid='%s'", (const char *)kid); - sqlite3 *sqliteconnection = get_sqlite_connection(); - if(sqliteconnection) { + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { - sqlite_lock(0); + sqlite_lock(0); - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - int res = sqlite3_step(st); - if (res == SQLITE_ROW) { + int res = sqlite3_step(st); + if (res == SQLITE_ROW) { - STRCPY(key->ikm_key,sqlite3_column_text(st, 0)); - key->timestamp = (uint64_t)strtoll((const char*)sqlite3_column_text(st, 1),NULL,10); - key->lifetime = (uint32_t)strtol((const char*)sqlite3_column_text(st, 2),NULL,10); - STRCPY(key->as_rs_alg,sqlite3_column_text(st, 3)); - STRCPY(key->realm,sqlite3_column_text(st, 4)); - STRCPY(key->kid,kid); - ret = 0; - } - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } + STRCPY(key->ikm_key, sqlite3_column_text(st, 0)); + key->timestamp = (uint64_t)strtoll((const char *)sqlite3_column_text(st, 1), NULL, 10); + key->lifetime = (uint32_t)strtol((const char *)sqlite3_column_text(st, 2), NULL, 10); + STRCPY(key->as_rs_alg, sqlite3_column_text(st, 3)); + STRCPY(key->realm, sqlite3_column_text(st, 4)); + STRCPY(key->kid, kid); + ret = 0; + } + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } - sqlite3_finalize(st); + sqlite3_finalize(st); - sqlite_unlock(0); - } + sqlite_unlock(0); + } - return ret; + return ret; } -static int sqlite_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts,secrets_list_t *realms) { +static int sqlite_list_oauth_keys(secrets_list_t *kids, secrets_list_t *teas, secrets_list_t *tss, secrets_list_t *lts, + secrets_list_t *realms) { - oauth_key_data_raw key_; - oauth_key_data_raw *key=&key_; + oauth_key_data_raw key_; + oauth_key_data_raw *key = &key_; - donot_print_connection_success=1; + donot_print_connection_success = 1; - int ret = -1; + int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; - snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,realm,kid from oauth_key order by kid"); + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; + snprintf(statement, sizeof(statement), + "select ikm_key,timestamp,lifetime,as_rs_alg,realm,kid from oauth_key order by kid"); - sqlite3 *sqliteconnection = get_sqlite_connection(); - if(sqliteconnection) { + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { - sqlite_lock(0); + sqlite_lock(0); - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - ret = 0; - while (1) { - int res = sqlite3_step(st); - if (res == SQLITE_ROW) { + ret = 0; + while (1) { + int res = sqlite3_step(st); + if (res == SQLITE_ROW) { - STRCPY(key->ikm_key,sqlite3_column_text(st, 0)); - key->timestamp = (uint64_t)strtoll((const char*)sqlite3_column_text(st, 1),NULL,10); - key->lifetime = (uint32_t)strtol((const char*)sqlite3_column_text(st, 2),NULL,10); - STRCPY(key->as_rs_alg,sqlite3_column_text(st, 3)); - STRCPY(key->realm,sqlite3_column_text(st, 4)); - STRCPY(key->kid,sqlite3_column_text(st, 5)); + STRCPY(key->ikm_key, sqlite3_column_text(st, 0)); + key->timestamp = (uint64_t)strtoll((const char *)sqlite3_column_text(st, 1), NULL, 10); + key->lifetime = (uint32_t)strtol((const char *)sqlite3_column_text(st, 2), NULL, 10); + STRCPY(key->as_rs_alg, sqlite3_column_text(st, 3)); + STRCPY(key->realm, sqlite3_column_text(st, 4)); + STRCPY(key->kid, sqlite3_column_text(st, 5)); - if(kids) { - add_to_secrets_list(kids,key->kid); - add_to_secrets_list(teas,key->as_rs_alg); - add_to_secrets_list(realms,key->realm); - { - char ts[256]; - snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp); - add_to_secrets_list(tss,ts); - } - { - char lt[256]; - snprintf(lt,sizeof(lt)-1,"%lu",(unsigned long)key->lifetime); - add_to_secrets_list(lts,lt); - } - } else { - printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s\n", - key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, - key->as_rs_alg); - } + if (kids) { + add_to_secrets_list(kids, key->kid); + add_to_secrets_list(teas, key->as_rs_alg); + add_to_secrets_list(realms, key->realm); + { + char ts[256]; + snprintf(ts, sizeof(ts) - 1, "%llu", (unsigned long long)key->timestamp); + add_to_secrets_list(tss, ts); + } + { + char lt[256]; + snprintf(lt, sizeof(lt) - 1, "%lu", (unsigned long)key->lifetime); + add_to_secrets_list(lts, lt); + } + } else { + printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s\n", key->kid, key->ikm_key, + (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->as_rs_alg); + } - } else if (res == SQLITE_DONE) { - break; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - ret = -1; - break; - } - } - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } + } else if (res == SQLITE_DONE) { + break; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + ret = -1; + break; + } + } + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } - sqlite3_finalize(st); + sqlite3_finalize(st); - sqlite_unlock(0); - } + sqlite_unlock(0); + } - return ret; + return ret; } -static int sqlite_set_user_key(uint8_t *usname, uint8_t *realm, const char *key) -{ - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; +static int sqlite_set_user_key(uint8_t *usname, uint8_t *realm, const char *key) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; - donot_print_connection_success=1; + donot_print_connection_success = 1; - sqlite3 *sqliteconnection = get_sqlite_connection(); - if (sqliteconnection) { + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { - sqlite_lock(1); + sqlite_lock(1); - snprintf(statement, sizeof(statement), "insert or replace into turnusers_lt (realm,name,hmackey) values('%s','%s','%s')", realm, usname, key); + snprintf(statement, sizeof(statement), + "insert or replace into turnusers_lt (realm,name,hmackey) values('%s','%s','%s')", realm, usname, key); - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - sqlite3_step(st); - ret = 0; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite3_step(st); + ret = 0; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); - sqlite_unlock(1); - } - return ret; + sqlite_unlock(1); + } + return ret; } -static int sqlite_set_oauth_key(oauth_key_data_raw *key) -{ +static int sqlite_set_oauth_key(oauth_key_data_raw *key) { - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; - donot_print_connection_success=1; + donot_print_connection_success = 1; - sqlite3 *sqliteconnection = get_sqlite_connection(); - if (sqliteconnection) { - snprintf( - statement, - sizeof(statement), - "insert or replace into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg,realm) values('%s','%s',%llu,%lu,'%s','%s')", - key->kid, key->ikm_key, (unsigned long long) key->timestamp, (unsigned long) key->lifetime, key->as_rs_alg, key->realm); + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + snprintf(statement, sizeof(statement), + "insert or replace into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg,realm) " + "values('%s','%s',%llu,%lu,'%s','%s')", + key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->as_rs_alg, + key->realm); - sqlite_lock(1); + sqlite_lock(1); - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - sqlite3_step(st); - ret = 0; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error updating SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite3_step(st); + ret = 0; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error updating SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); - sqlite_unlock(1); - } - return ret; + sqlite_unlock(1); + } + return ret; } -static int sqlite_del_user(uint8_t *usname, uint8_t *realm) -{ - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; +static int sqlite_del_user(uint8_t *usname, uint8_t *realm) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; - donot_print_connection_success=1; + donot_print_connection_success = 1; - sqlite3 *sqliteconnection = get_sqlite_connection(); - if (sqliteconnection) { - snprintf(statement, sizeof(statement), "delete from turnusers_lt where name='%s' and realm='%s'", usname, realm); + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + snprintf(statement, sizeof(statement), "delete from turnusers_lt where name='%s' and realm='%s'", usname, realm); - sqlite_lock(1); + sqlite_lock(1); - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - sqlite3_step(st); - ret = 0; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite3_step(st); + ret = 0; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); - sqlite_unlock(1); - } - return ret; + sqlite_unlock(1); + } + return ret; } -static int sqlite_del_oauth_key(const uint8_t *kid) -{ - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; +static int sqlite_del_oauth_key(const uint8_t *kid) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; - donot_print_connection_success=1; + donot_print_connection_success = 1; - sqlite3 *sqliteconnection = get_sqlite_connection(); - if (sqliteconnection) { + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { - snprintf(statement, sizeof(statement), "delete from oauth_key where kid = '%s'", (const char*) kid); + snprintf(statement, sizeof(statement), "delete from oauth_key where kid = '%s'", (const char *)kid); - sqlite_lock(1); + sqlite_lock(1); - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - sqlite3_step(st); - ret = 0; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite3_step(st); + ret = 0; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); - sqlite_unlock(1); - } - return ret; + sqlite_unlock(1); + } + return ret; } +static int sqlite_list_users(uint8_t *realm, secrets_list_t *users, secrets_list_t *realms) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; -static int sqlite_list_users(uint8_t *realm, secrets_list_t *users, secrets_list_t *realms) -{ - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; + uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0"; + if (!realm) + realm = realm0; - uint8_t realm0[STUN_MAX_REALM_SIZE+1] = "\0"; - if(!realm) realm=realm0; + donot_print_connection_success = 1; - donot_print_connection_success=1; + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + if (realm[0]) { + snprintf(statement, sizeof(statement), "select name,realm from turnusers_lt where realm='%s' order by name", + realm); + } else { + snprintf(statement, sizeof(statement), "select name,realm from turnusers_lt order by realm,name"); + } - sqlite3 *sqliteconnection = get_sqlite_connection(); - if (sqliteconnection) { - if (realm[0]) { - snprintf(statement, sizeof(statement), "select name,realm from turnusers_lt where realm='%s' order by name", realm); - } else { - snprintf(statement, sizeof(statement), "select name,realm from turnusers_lt order by realm,name"); - } + sqlite_lock(0); - sqlite_lock(0); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + ret = 0; + while (1) { + int res = sqlite3_step(st); + if (res == SQLITE_ROW) { - ret = 0; - while (1) { - int res = sqlite3_step(st); - if (res == SQLITE_ROW) { + const char *kval = (const char *)sqlite3_column_text(st, 0); + const char *rval = (const char *)sqlite3_column_text(st, 1); - const char* kval = (const char*) sqlite3_column_text(st, 0); - const char* rval = (const char*) sqlite3_column_text(st, 1); + if (users) { + add_to_secrets_list(users, kval); + if (realms) { + if (rval && *rval) { + add_to_secrets_list(realms, rval); + } else { + add_to_secrets_list(realms, (char *)realm); + } + } + } else { + printf("%s[%s]\n", kval, rval); + } - if(users) { - add_to_secrets_list(users,kval); - if(realms) { - if(rval && *rval) { - add_to_secrets_list(realms,rval); - } else { - add_to_secrets_list(realms,(char*)realm); - } - } - } else { - printf("%s[%s]\n", kval, rval); - } + } else if (res == SQLITE_DONE) { + break; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + ret = -1; + break; + } + } + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); - } else if (res == SQLITE_DONE) { - break; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - ret = -1; - break; - } - } - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); - - sqlite_unlock(0); - } - return ret; + sqlite_unlock(0); + } + return ret; } -static int sqlite_list_secrets(uint8_t *realm, secrets_list_t *secrets, secrets_list_t *realms) -{ - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; +static int sqlite_list_secrets(uint8_t *realm, secrets_list_t *secrets, secrets_list_t *realms) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; - uint8_t realm0[STUN_MAX_REALM_SIZE+1] = "\0"; - if(!realm) realm=realm0; + uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0"; + if (!realm) + realm = realm0; - sqlite3_stmt *st = NULL; - int rc = 0; + sqlite3_stmt *st = NULL; + int rc = 0; - if (realm[0]) { - snprintf(statement, sizeof(statement), "select value,realm from turn_secret where realm='%s' order by value", realm); - } else { - snprintf(statement, sizeof(statement), "select value,realm from turn_secret order by realm,value"); - } + if (realm[0]) { + snprintf(statement, sizeof(statement), "select value,realm from turn_secret where realm='%s' order by value", + realm); + } else { + snprintf(statement, sizeof(statement), "select value,realm from turn_secret order by realm,value"); + } - donot_print_connection_success=1; + donot_print_connection_success = 1; - sqlite3 *sqliteconnection = get_sqlite_connection(); - if(sqliteconnection) { + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { - sqlite_lock(0); + sqlite_lock(0); - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - int res = 0; - while(1) { - res = sqlite3_step(st); - if (res == SQLITE_ROW) { - ret = 0; - const char* kval = (const char*) sqlite3_column_text(st, 0); - if(kval) { - const char* rval = (const char*) sqlite3_column_text(st, 1); - if(secrets) { - add_to_secrets_list(secrets,kval); - if(realms) { - if(rval && *rval) { - add_to_secrets_list(realms,rval); - } else { - add_to_secrets_list(realms,(char*)realm); - } - } - } else { - printf("%s[%s]\n",kval,rval); - } - } - } else if (res == SQLITE_DONE) { - break; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - ret = -1; - break; - } - } - } - sqlite3_finalize(st); + int res = 0; + while (1) { + res = sqlite3_step(st); + if (res == SQLITE_ROW) { + ret = 0; + const char *kval = (const char *)sqlite3_column_text(st, 0); + if (kval) { + const char *rval = (const char *)sqlite3_column_text(st, 1); + if (secrets) { + add_to_secrets_list(secrets, kval); + if (realms) { + if (rval && *rval) { + add_to_secrets_list(realms, rval); + } else { + add_to_secrets_list(realms, (char *)realm); + } + } + } else { + printf("%s[%s]\n", kval, rval); + } + } + } else if (res == SQLITE_DONE) { + break; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + ret = -1; + break; + } + } + } + sqlite3_finalize(st); - sqlite_unlock(0); - } - return ret; -} - -static int sqlite_del_secret(uint8_t *secret, uint8_t *realm) -{ - int ret = -1; - donot_print_connection_success=1; - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; - - sqlite3 *sqliteconnection = get_sqlite_connection(); - if (sqliteconnection) { - if(!secret || (secret[0]==0)) - snprintf(statement,sizeof(statement),"delete from turn_secret where realm='%s'",realm); - else - snprintf(statement,sizeof(statement),"delete from turn_secret where value='%s' and realm='%s'",secret,realm); - - sqlite_lock(1); - - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - sqlite3_step(st); - ret = 0; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); - - sqlite_unlock(1); - } - return ret; -} - -static int sqlite_set_secret(uint8_t *secret, uint8_t *realm) -{ - int ret = -1; - donot_print_connection_success = 1; - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; - - sqlite3 *sqliteconnection = get_sqlite_connection(); - if (sqliteconnection) { - - snprintf(statement,sizeof(statement),"insert or replace into turn_secret (realm,value) values('%s','%s')",realm,secret); - - sqlite_lock(1); - - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - sqlite3_step(st); - ret = 0; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); - - sqlite_unlock(1); - } - return ret; -} - -static int sqlite_add_origin(uint8_t *origin, uint8_t *realm) -{ - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; - donot_print_connection_success=1; - - sqlite3 *sqliteconnection = get_sqlite_connection(); - if(sqliteconnection) { - snprintf(statement,sizeof(statement),"insert or replace into turn_origin_to_realm (origin,realm) values('%s','%s')",origin,realm); - - sqlite_lock(1); - - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - sqlite3_step(st); - ret = 0; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); - - sqlite_unlock(1); - } - return ret; -} - -static int sqlite_del_origin(uint8_t *origin) -{ - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; - donot_print_connection_success=1; - - sqlite3 *sqliteconnection = get_sqlite_connection(); - if(sqliteconnection) { - snprintf(statement,sizeof(statement),"delete from turn_origin_to_realm where origin='%s'",origin); - - sqlite_lock(1); - - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - sqlite3_step(st); - ret = 0; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); - - sqlite_unlock(1); - } - return ret; + sqlite_unlock(0); + } + return ret; } -static int sqlite_list_origins(uint8_t *realm, secrets_list_t *origins, secrets_list_t *realms) -{ - int ret = -1; +static int sqlite_del_secret(uint8_t *secret, uint8_t *realm) { + int ret = -1; + donot_print_connection_success = 1; + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; - uint8_t realm0[STUN_MAX_REALM_SIZE+1] = "\0"; - if(!realm) realm=realm0; + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + if (!secret || (secret[0] == 0)) + snprintf(statement, sizeof(statement), "delete from turn_secret where realm='%s'", realm); + else + snprintf(statement, sizeof(statement), "delete from turn_secret where value='%s' and realm='%s'", secret, realm); - donot_print_connection_success = 1; + sqlite_lock(1); - sqlite3_stmt *st = NULL; - int rc = 0; + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite3_step(st); + ret = 0; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); - sqlite3 *sqliteconnection = get_sqlite_connection(); - if (sqliteconnection) { - char statement[TURN_LONG_STRING_SIZE]; - if (realm && realm[0]) { - snprintf(statement, sizeof(statement), "select origin,realm from turn_origin_to_realm where realm='%s' order by origin", realm); - } else { - snprintf(statement, sizeof(statement), "select origin,realm from turn_origin_to_realm order by realm,origin"); - } - - sqlite_lock(0); - - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - - ret = 0; - while (1) { - int res = sqlite3_step(st); - if (res == SQLITE_ROW) { - - const char* kval = (const char*) sqlite3_column_text(st, 0); - const char* rval = (const char*) sqlite3_column_text(st, 1); - - if(origins) { - add_to_secrets_list(origins,kval); - if(realms) { - if(rval && *rval) { - add_to_secrets_list(realms,rval); - } else { - add_to_secrets_list(realms,(char*)realm); - } - } - } else { - printf("%s ==>> %s\n",kval,rval); - } - } else if (res == SQLITE_DONE) { - break; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - ret = -1; - break; - } - } - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); - - sqlite_unlock(0); - } - return ret; -} - -static int sqlite_set_realm_option_one(uint8_t *realm, unsigned long value, const char* opt) -{ - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; - donot_print_connection_success=1; - - sqlite3 *sqliteconnection = get_sqlite_connection(); - if(sqliteconnection) { - if(value>0) { - snprintf(statement,sizeof(statement),"insert or replace into turn_realm_option (realm,opt,value) values('%s','%s','%lu')",realm,opt,(unsigned long)value); - - sqlite_lock(1); - - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - sqlite3_step(st); - ret = 0; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); - - sqlite_unlock(1); - } - } - return ret; -} - -static int sqlite_list_realm_options(uint8_t *realm) -{ - int ret = -1; - donot_print_connection_success = 1; - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; - - sqlite3 *sqliteconnection = get_sqlite_connection(); - if (sqliteconnection) { - if (realm && realm[0]) { - snprintf(statement, sizeof(statement), "select realm,opt,value from turn_realm_option where realm='%s' order by realm,opt", realm); - } else { - snprintf(statement, sizeof(statement), "select realm,opt,value from turn_realm_option order by realm,opt"); - } - - sqlite_lock(0); - - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - - ret = 0; - - while (1) { - int res = sqlite3_step(st); - if (res == SQLITE_ROW) { - - const char* rval = (const char*) sqlite3_column_text(st, 0); - const char* oval = (const char*) sqlite3_column_text(st, 1); - const char* vval = (const char*) sqlite3_column_text(st, 2); - - printf("%s[%s]=%s\n",oval,rval,vval); - - } else if (res == SQLITE_DONE) { - break; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - ret = -1; - break; - } - } - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); - - sqlite_unlock(0); - } - return ret; -} - -static void sqlite_auth_ping(void * rch) -{ - UNUSED_ARG(rch); + sqlite_unlock(1); + } + return ret; } -static int sqlite_get_ip_list(const char *kind, ip_range_list_t * list) -{ - int ret = -1; +static int sqlite_set_secret(uint8_t *secret, uint8_t *realm) { + int ret = -1; + donot_print_connection_success = 1; + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; - sqlite3 *sqliteconnection = get_sqlite_connection(); - if (sqliteconnection) { - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; - snprintf(statement, sizeof(statement), "select ip_range,realm from %s_peer_ip", kind); + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { - sqlite_lock(0); + snprintf(statement, sizeof(statement), "insert or replace into turn_secret (realm,value) values('%s','%s')", realm, + secret); - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite_lock(1); - ret = 0; + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite3_step(st); + ret = 0; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); - while (1) { - int res = sqlite3_step(st); - if (res == SQLITE_ROW) { - - const char* kval = (const char*) sqlite3_column_text(st, 0); - const char* rval = (const char*) sqlite3_column_text(st, 1); - - add_ip_list_range(kval, rval, list); - - } else if (res == SQLITE_DONE) { - break; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - ret = -1; - break; - } - } - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); - - sqlite_unlock(0); - } - return ret; + sqlite_unlock(1); + } + return ret; } -static int sqlite_set_permission_ip(const char *kind, uint8_t *realm, const char* ip, int del) -{ - int ret = -1; +static int sqlite_add_origin(uint8_t *origin, uint8_t *realm) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; + donot_print_connection_success = 1; - uint8_t realm0[STUN_MAX_REALM_SIZE+1] = "\0"; - if(!realm) realm=realm0; + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + snprintf(statement, sizeof(statement), + "insert or replace into turn_origin_to_realm (origin,realm) values('%s','%s')", origin, realm); - char statement[TURN_LONG_STRING_SIZE]; + sqlite_lock(1); - sqlite3_stmt *st = NULL; - int rc = 0; + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite3_step(st); + ret = 0; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); - donot_print_connection_success=1; - - sqlite3 *sqliteconnection = get_sqlite_connection(); - if (sqliteconnection) { - - sqlite_lock(1); - - if(del) { - snprintf(statement, sizeof(statement), "delete from %s_peer_ip where realm = '%s' and ip_range = '%s'", kind, (char*)realm, ip); - } else { - snprintf(statement, sizeof(statement), "insert or replace into %s_peer_ip (realm,ip_range) values('%s','%s')", kind, (char*)realm, ip); - } - - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - sqlite3_step(st); - ret = 0; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error updating SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); - - sqlite_unlock(1); - } - return ret; + sqlite_unlock(1); + } + return ret; } -static void sqlite_reread_realms(secrets_list_t * realms_list) -{ - sqlite3 *sqliteconnection = get_sqlite_connection(); - if(sqliteconnection) { - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; - { - snprintf(statement,sizeof(statement),"select origin,realm from turn_origin_to_realm"); +static int sqlite_del_origin(uint8_t *origin) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; + donot_print_connection_success = 1; - sqlite_lock(0); + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + snprintf(statement, sizeof(statement), "delete from turn_origin_to_realm where origin='%s'", origin); - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite_lock(1); - ur_string_map *o_to_realm_new = ur_string_map_create(free); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite3_step(st); + ret = 0; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); - while (1) { - int res = sqlite3_step(st); - if (res == SQLITE_ROW) { + sqlite_unlock(1); + } + return ret; +} - char* oval = strdup((const char*) sqlite3_column_text(st, 0)); - char* rval = strdup((const char*) sqlite3_column_text(st, 1)); +static int sqlite_list_origins(uint8_t *realm, secrets_list_t *origins, secrets_list_t *realms) { + int ret = -1; - get_realm(rval); - ur_string_map_value_type value = rval; - ur_string_map_put(o_to_realm_new, (ur_string_map_key_type) oval, value); + uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0"; + if (!realm) + realm = realm0; - free(oval); + donot_print_connection_success = 1; - } else if (res == SQLITE_DONE) { - break; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - break; - } - } + sqlite3_stmt *st = NULL; + int rc = 0; - update_o_to_realm(o_to_realm_new); + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + char statement[TURN_LONG_STRING_SIZE]; + if (realm && realm[0]) { + snprintf(statement, sizeof(statement), + "select origin,realm from turn_origin_to_realm where realm='%s' order by origin", realm); + } else { + snprintf(statement, sizeof(statement), "select origin,realm from turn_origin_to_realm order by realm,origin"); + } - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); + sqlite_lock(0); - sqlite_unlock(0); - } + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - { - { - size_t i = 0; - size_t rlsz = 0; + ret = 0; + while (1) { + int res = sqlite3_step(st); + if (res == SQLITE_ROW) { - lock_realms(); - rlsz = realms_list->sz; - unlock_realms(); + const char *kval = (const char *)sqlite3_column_text(st, 0); + const char *rval = (const char *)sqlite3_column_text(st, 1); - for (i = 0; i> %s\n", kval, rval); + } + } else if (res == SQLITE_DONE) { + break; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + ret = -1; + break; + } + } + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); - char *realm = realms_list->secrets[i]; + sqlite_unlock(0); + } + return ret; +} - realm_params_t* rp = get_realm(realm); +static int sqlite_set_realm_option_one(uint8_t *realm, unsigned long value, const char *opt) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; + donot_print_connection_success = 1; - lock_realms(); - rp->options.perf_options.max_bps = turn_params.max_bps; - unlock_realms(); + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + if (value > 0) { + snprintf(statement, sizeof(statement), + "insert or replace into turn_realm_option (realm,opt,value) values('%s','%s','%lu')", realm, opt, + (unsigned long)value); - lock_realms(); - rp->options.perf_options.total_quota = turn_params.total_quota; - unlock_realms(); + sqlite_lock(1); - lock_realms(); - rp->options.perf_options.user_quota = turn_params.user_quota; - unlock_realms(); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite3_step(st); + ret = 0; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); - } - } + sqlite_unlock(1); + } + } + return ret; +} - sqlite_lock(0); +static int sqlite_list_realm_options(uint8_t *realm) { + int ret = -1; + donot_print_connection_success = 1; + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; - snprintf(statement,sizeof(statement),"select realm,opt,value from turn_realm_option"); - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + if (realm && realm[0]) { + snprintf(statement, sizeof(statement), + "select realm,opt,value from turn_realm_option where realm='%s' order by realm,opt", realm); + } else { + snprintf(statement, sizeof(statement), "select realm,opt,value from turn_realm_option order by realm,opt"); + } - while (1) { - int res = sqlite3_step(st); - if (res == SQLITE_ROW) { + sqlite_lock(0); - char* rval = strdup((const char*) sqlite3_column_text(st, 0)); - const char* oval = (const char*) sqlite3_column_text(st, 1); - const char* vval = (const char*) sqlite3_column_text(st, 2); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - realm_params_t* rp = get_realm(rval); - if(!strcmp(oval,"max-bps")) - rp->options.perf_options.max_bps = (band_limit_t)strtoul(vval,NULL,10); - else if(!strcmp(oval,"total-quota")) - rp->options.perf_options.total_quota = (vint)atoi(vval); - else if(!strcmp(oval,"user-quota")) - rp->options.perf_options.user_quota = (vint)atoi(vval); - else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown realm option: %s\n", oval); - } + ret = 0; - free(rval); + while (1) { + int res = sqlite3_step(st); + if (res == SQLITE_ROW) { - } else if (res == SQLITE_DONE) { - break; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - break; - } - } - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); + const char *rval = (const char *)sqlite3_column_text(st, 0); + const char *oval = (const char *)sqlite3_column_text(st, 1); + const char *vval = (const char *)sqlite3_column_text(st, 2); - sqlite_unlock(0); - } - } + printf("%s[%s]=%s\n", oval, rval, vval); + + } else if (res == SQLITE_DONE) { + break; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + ret = -1; + break; + } + } + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); + + sqlite_unlock(0); + } + return ret; +} + +static void sqlite_auth_ping(void *rch) { UNUSED_ARG(rch); } + +static int sqlite_get_ip_list(const char *kind, ip_range_list_t *list) { + int ret = -1; + + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; + snprintf(statement, sizeof(statement), "select ip_range,realm from %s_peer_ip", kind); + + sqlite_lock(0); + + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + + ret = 0; + + while (1) { + int res = sqlite3_step(st); + if (res == SQLITE_ROW) { + + const char *kval = (const char *)sqlite3_column_text(st, 0); + const char *rval = (const char *)sqlite3_column_text(st, 1); + + add_ip_list_range(kval, rval, list); + + } else if (res == SQLITE_DONE) { + break; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + ret = -1; + break; + } + } + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); + + sqlite_unlock(0); + } + return ret; +} + +static int sqlite_set_permission_ip(const char *kind, uint8_t *realm, const char *ip, int del) { + int ret = -1; + + uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0"; + if (!realm) + realm = realm0; + + char statement[TURN_LONG_STRING_SIZE]; + + sqlite3_stmt *st = NULL; + int rc = 0; + + donot_print_connection_success = 1; + + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + + sqlite_lock(1); + + if (del) { + snprintf(statement, sizeof(statement), "delete from %s_peer_ip where realm = '%s' and ip_range = '%s'", kind, + (char *)realm, ip); + } else { + snprintf(statement, sizeof(statement), "insert or replace into %s_peer_ip (realm,ip_range) values('%s','%s')", + kind, (char *)realm, ip); + } + + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite3_step(st); + ret = 0; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error updating SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); + + sqlite_unlock(1); + } + return ret; +} + +static void sqlite_reread_realms(secrets_list_t *realms_list) { + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; + { + snprintf(statement, sizeof(statement), "select origin,realm from turn_origin_to_realm"); + + sqlite_lock(0); + + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + + ur_string_map *o_to_realm_new = ur_string_map_create(free); + + while (1) { + int res = sqlite3_step(st); + if (res == SQLITE_ROW) { + + char *oval = strdup((const char *)sqlite3_column_text(st, 0)); + char *rval = strdup((const char *)sqlite3_column_text(st, 1)); + + get_realm(rval); + ur_string_map_value_type value = rval; + ur_string_map_put(o_to_realm_new, (ur_string_map_key_type)oval, value); + + free(oval); + + } else if (res == SQLITE_DONE) { + break; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + break; + } + } + + update_o_to_realm(o_to_realm_new); + + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); + + sqlite_unlock(0); + } + + { + { + size_t i = 0; + size_t rlsz = 0; + + lock_realms(); + rlsz = realms_list->sz; + unlock_realms(); + + for (i = 0; i < rlsz; ++i) { + + char *realm = realms_list->secrets[i]; + + realm_params_t *rp = get_realm(realm); + + lock_realms(); + rp->options.perf_options.max_bps = turn_params.max_bps; + unlock_realms(); + + lock_realms(); + rp->options.perf_options.total_quota = turn_params.total_quota; + unlock_realms(); + + lock_realms(); + rp->options.perf_options.user_quota = turn_params.user_quota; + unlock_realms(); + } + } + + sqlite_lock(0); + + snprintf(statement, sizeof(statement), "select realm,opt,value from turn_realm_option"); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + + while (1) { + int res = sqlite3_step(st); + if (res == SQLITE_ROW) { + + char *rval = strdup((const char *)sqlite3_column_text(st, 0)); + const char *oval = (const char *)sqlite3_column_text(st, 1); + const char *vval = (const char *)sqlite3_column_text(st, 2); + + realm_params_t *rp = get_realm(rval); + if (!strcmp(oval, "max-bps")) + rp->options.perf_options.max_bps = (band_limit_t)strtoul(vval, NULL, 10); + else if (!strcmp(oval, "total-quota")) + rp->options.perf_options.total_quota = (vint)atoi(vval); + else if (!strcmp(oval, "user-quota")) + rp->options.perf_options.user_quota = (vint)atoi(vval); + else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown realm option: %s\n", oval); + } + + free(rval); + + } else if (res == SQLITE_DONE) { + break; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + break; + } + } + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); + + sqlite_unlock(0); + } + } } //////////////////////////////////////////////////// -static int sqlite_get_admin_user(const uint8_t *usname, uint8_t *realm, password_t pwd) -{ - int ret = -1; +static int sqlite_get_admin_user(const uint8_t *usname, uint8_t *realm, password_t pwd) { + int ret = -1; - realm[0]=0; - pwd[0]=0; + realm[0] = 0; + pwd[0] = 0; - sqlite3 *sqliteconnection = get_sqlite_connection(); - if (sqliteconnection) { - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; - snprintf(statement, sizeof(statement), "select realm,password from admin_user where name='%s'", usname); + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; + snprintf(statement, sizeof(statement), "select realm,password from admin_user where name='%s'", usname); - sqlite_lock(0); + sqlite_lock(0); - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - int res = sqlite3_step(st); - if (res == SQLITE_ROW) { - const char *kval = (const char*) sqlite3_column_text(st, 0); - if(kval) { - strncpy((char*)realm,kval,STUN_MAX_REALM_SIZE); - } - kval = (const char*) sqlite3_column_text(st, 1); - if(kval) { - strncpy((char*)pwd,kval,STUN_MAX_PWD_SIZE); - } - ret = 0; - } - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + int res = sqlite3_step(st); + if (res == SQLITE_ROW) { + const char *kval = (const char *)sqlite3_column_text(st, 0); + if (kval) { + strncpy((char *)realm, kval, STUN_MAX_REALM_SIZE); + } + kval = (const char *)sqlite3_column_text(st, 1); + if (kval) { + strncpy((char *)pwd, kval, STUN_MAX_PWD_SIZE); + } + ret = 0; + } + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } - sqlite3_finalize(st); + sqlite3_finalize(st); - sqlite_unlock(0); - } - return ret; + sqlite_unlock(0); + } + return ret; } -static int sqlite_set_admin_user(const uint8_t *usname, const uint8_t *realm, const password_t pwd) -{ - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; +static int sqlite_set_admin_user(const uint8_t *usname, const uint8_t *realm, const password_t pwd) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; - donot_print_connection_success=1; + donot_print_connection_success = 1; - sqlite3 *sqliteconnection = get_sqlite_connection(); - if (sqliteconnection) { + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { - sqlite_lock(1); + sqlite_lock(1); - snprintf(statement, sizeof(statement), "insert or replace into admin_user (realm,name,password) values('%s','%s','%s')", realm, usname, pwd); + snprintf(statement, sizeof(statement), + "insert or replace into admin_user (realm,name,password) values('%s','%s','%s')", realm, usname, pwd); - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - sqlite3_step(st); - ret = 0; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite3_step(st); + ret = 0; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); - sqlite_unlock(1); - } - return ret; + sqlite_unlock(1); + } + return ret; } -static int sqlite_del_admin_user(const uint8_t *usname) -{ - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; +static int sqlite_del_admin_user(const uint8_t *usname) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; - donot_print_connection_success=1; + donot_print_connection_success = 1; - sqlite3 *sqliteconnection = get_sqlite_connection(); - if (sqliteconnection) { - snprintf(statement, sizeof(statement), "delete from admin_user where name='%s'", usname); + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + snprintf(statement, sizeof(statement), "delete from admin_user where name='%s'", usname); - sqlite_lock(1); + sqlite_lock(1); - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - sqlite3_step(st); - ret = 0; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite3_step(st); + ret = 0; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); - sqlite_unlock(1); - } - return ret; + sqlite_unlock(1); + } + return ret; } -static int sqlite_list_admin_users(int no_print) -{ - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - sqlite3_stmt *st = NULL; - int rc = 0; +static int sqlite_list_admin_users(int no_print) { + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; - donot_print_connection_success=1; + donot_print_connection_success = 1; - sqlite3 *sqliteconnection = get_sqlite_connection(); - if (sqliteconnection) { - snprintf(statement, sizeof(statement), "select name,realm from admin_user order by realm,name"); + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + snprintf(statement, sizeof(statement), "select name,realm from admin_user order by realm,name"); - sqlite_lock(0); + sqlite_lock(0); - if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - ret = 0; - while (1) { - int res = sqlite3_step(st); - if (res == SQLITE_ROW) { + ret = 0; + while (1) { + int res = sqlite3_step(st); + if (res == SQLITE_ROW) { - const char* kval = (const char*) sqlite3_column_text(st, 0); - const char* rval = (const char*) sqlite3_column_text(st, 1); + const char *kval = (const char *)sqlite3_column_text(st, 0); + const char *rval = (const char *)sqlite3_column_text(st, 1); - if(!no_print) { - if (rval && *rval) { - printf("%s[%s]\n", kval, rval); - } else { - printf("%s\n", kval); - } - } + if (!no_print) { + if (rval && *rval) { + printf("%s[%s]\n", kval, rval); + } else { + printf("%s\n", kval); + } + } - ++ret; + ++ret; - } else if (res == SQLITE_DONE) { - break; - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - ret = -1; - break; - } - } - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); - } - sqlite3_finalize(st); + } else if (res == SQLITE_DONE) { + break; + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + ret = -1; + break; + } + } + } else { + const char *errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + } + sqlite3_finalize(st); - sqlite_unlock(0); - } - return ret; + sqlite_unlock(0); + } + return ret; } static void sqlite_disconnect(void) { - sqlite3 *sqliteconnection = (sqlite3 *)pthread_getspecific(connection_key); - if (sqliteconnection) { - sqlite3_close(sqliteconnection); - sqliteconnection=NULL; - } - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SQLite connection was closed.\n"); + sqlite3 *sqliteconnection = (sqlite3 *)pthread_getspecific(connection_key); + if (sqliteconnection) { + sqlite3_close(sqliteconnection); + sqliteconnection = NULL; + } + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SQLite connection was closed.\n"); } /////////////////////////////////////////////////////// static const turn_dbdriver_t driver = { - &sqlite_get_auth_secrets, - &sqlite_get_user_key, - &sqlite_set_user_key, - &sqlite_del_user, - &sqlite_list_users, - &sqlite_list_secrets, - &sqlite_del_secret, - &sqlite_set_secret, - &sqlite_add_origin, - &sqlite_del_origin, - &sqlite_list_origins, - &sqlite_set_realm_option_one, - &sqlite_list_realm_options, - &sqlite_auth_ping, - &sqlite_get_ip_list, - &sqlite_set_permission_ip, - &sqlite_reread_realms, - &sqlite_set_oauth_key, - &sqlite_get_oauth_key, - &sqlite_del_oauth_key, - &sqlite_list_oauth_keys, - &sqlite_get_admin_user, - &sqlite_set_admin_user, - &sqlite_del_admin_user, - &sqlite_list_admin_users, - &sqlite_disconnect -}; + &sqlite_get_auth_secrets, &sqlite_get_user_key, &sqlite_set_user_key, &sqlite_del_user, + &sqlite_list_users, &sqlite_list_secrets, &sqlite_del_secret, &sqlite_set_secret, + &sqlite_add_origin, &sqlite_del_origin, &sqlite_list_origins, &sqlite_set_realm_option_one, + &sqlite_list_realm_options, &sqlite_auth_ping, &sqlite_get_ip_list, &sqlite_set_permission_ip, + &sqlite_reread_realms, &sqlite_set_oauth_key, &sqlite_get_oauth_key, &sqlite_del_oauth_key, + &sqlite_list_oauth_keys, &sqlite_get_admin_user, &sqlite_set_admin_user, &sqlite_del_admin_user, + &sqlite_list_admin_users, &sqlite_disconnect}; ////////////////////////////////////////////////// -const turn_dbdriver_t * get_sqlite_dbdriver(void) { - return &driver; -} +const turn_dbdriver_t *get_sqlite_dbdriver(void) { return &driver; } ////////////////////////////////////////////////// #else -const turn_dbdriver_t * get_sqlite_dbdriver(void) { - return NULL; -} +const turn_dbdriver_t *get_sqlite_dbdriver(void) { return NULL; } #endif diff --git a/src/apps/relay/dbdrivers/dbd_sqlite.h b/src/apps/relay/dbdrivers/dbd_sqlite.h index 69d4269..cc238c0 100644 --- a/src/apps/relay/dbdrivers/dbd_sqlite.h +++ b/src/apps/relay/dbdrivers/dbd_sqlite.h @@ -38,7 +38,7 @@ extern "C" { #endif -const turn_dbdriver_t * get_sqlite_dbdriver(void); +const turn_dbdriver_t *get_sqlite_dbdriver(void); #ifdef __cplusplus } @@ -46,4 +46,3 @@ const turn_dbdriver_t * get_sqlite_dbdriver(void); #endif /// __DBD_SQLITE__/// - diff --git a/src/apps/relay/dbdrivers/dbdriver.c b/src/apps/relay/dbdrivers/dbdriver.c index af010d9..5c567fe 100644 --- a/src/apps/relay/dbdrivers/dbdriver.c +++ b/src/apps/relay/dbdrivers/dbdriver.c @@ -33,115 +33,102 @@ #include "apputils.h" -#include "dbdriver.h" -#include "dbd_sqlite.h" -#include "dbd_pgsql.h" -#include "dbd_mysql.h" #include "dbd_mongo.h" +#include "dbd_mysql.h" +#include "dbd_pgsql.h" #include "dbd_redis.h" +#include "dbd_sqlite.h" +#include "dbdriver.h" -static void make_connection_key(void) -{ - (void) pthread_key_create(&connection_key, NULL); -} - +static void make_connection_key(void) { (void)pthread_key_create(&connection_key, NULL); } pthread_key_t connection_key; pthread_once_t connection_key_once = PTHREAD_ONCE_INIT; -int convert_string_key_to_binary(char* keysource, hmackey_t key, size_t sz) { - char is[3]; - size_t i; - unsigned int v; - is[2]=0; - for(i=0;iverbose)) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s:%d:start\n",__FUNCTION__,__LINE__) -#define FUNCEND if(server && eve(server->verbose)) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s:%d:end\n",__FUNCTION__,__LINE__) +#define FUNCSTART \ + if (server && eve(server->verbose)) \ + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s:%d:start\n", __FUNCTION__, __LINE__) +#define FUNCEND \ + if (server && eve(server->verbose)) \ + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s:%d:end\n", __FUNCTION__, __LINE__) #define COOKIE_SECRET_LENGTH (32) @@ -70,83 +74,82 @@ struct dtls_listener_relay_server_info { ///////////// forward declarations //////// -static int create_server_socket(dtls_listener_relay_server_type* server, int report_creation); -static int clean_server(dtls_listener_relay_server_type* server); -static int reopen_server_socket(dtls_listener_relay_server_type* server, evutil_socket_t fd); +static int create_server_socket(dtls_listener_relay_server_type *server, int report_creation); +static int clean_server(dtls_listener_relay_server_type *server); +static int reopen_server_socket(dtls_listener_relay_server_type *server, evutil_socket_t fd); ///////////// dtls message types ////////// -int is_dtls_handshake_message(const unsigned char* buf, int len); -int is_dtls_data_message(const unsigned char* buf, int len); -int is_dtls_alert_message(const unsigned char* buf, int len); -int is_dtls_cipher_change_message(const unsigned char* buf, int len); -int get_dtls_version(const unsigned char* buf, int len); +int is_dtls_handshake_message(const unsigned char *buf, int len); +int is_dtls_data_message(const unsigned char *buf, int len); +int is_dtls_alert_message(const unsigned char *buf, int len); +int is_dtls_cipher_change_message(const unsigned char *buf, int len); +int get_dtls_version(const unsigned char *buf, int len); -int is_dtls_message(const unsigned char* buf, int len); +int is_dtls_message(const unsigned char *buf, int len); -int is_dtls_handshake_message(const unsigned char* buf, int len) { - return (buf && len>3 && buf[0]==0x16 && buf[1]==0xfe && ((buf[2]==0xff)||(buf[2]==0xfd))); +int is_dtls_handshake_message(const unsigned char *buf, int len) { + return (buf && len > 3 && buf[0] == 0x16 && buf[1] == 0xfe && ((buf[2] == 0xff) || (buf[2] == 0xfd))); } -int is_dtls_data_message(const unsigned char* buf, int len) { - return (buf && len>3 && buf[0]==0x17 && buf[1]==0xfe && ((buf[2]==0xff)||(buf[2]==0xfd))); +int is_dtls_data_message(const unsigned char *buf, int len) { + return (buf && len > 3 && buf[0] == 0x17 && buf[1] == 0xfe && ((buf[2] == 0xff) || (buf[2] == 0xfd))); } -int is_dtls_alert_message(const unsigned char* buf, int len) { - return (buf && len>3 && buf[0]==0x15 && buf[1]==0xfe && ((buf[2]==0xff)||(buf[2]==0xfd))); +int is_dtls_alert_message(const unsigned char *buf, int len) { + return (buf && len > 3 && buf[0] == 0x15 && buf[1] == 0xfe && ((buf[2] == 0xff) || (buf[2] == 0xfd))); } -int is_dtls_cipher_change_message(const unsigned char* buf, int len) { - return (buf && len>3 && buf[0]==0x14 && buf[1]==0xfe && ((buf[2]==0xff)||(buf[2]==0xfd))); +int is_dtls_cipher_change_message(const unsigned char *buf, int len) { + return (buf && len > 3 && buf[0] == 0x14 && buf[1] == 0xfe && ((buf[2] == 0xff) || (buf[2] == 0xfd))); } -int is_dtls_message(const unsigned char* buf, int len) { - if(buf && (len>3) && (buf[1])==0xfe && ((buf[2]==0xff)||(buf[2]==0xfd))) { - switch (buf[0]) { - case 0x14: - case 0x15: - case 0x16: - case 0x17: - return 1; - default: - ; - } +int is_dtls_message(const unsigned char *buf, int len) { + if (buf && (len > 3) && (buf[1]) == 0xfe && ((buf[2] == 0xff) || (buf[2] == 0xfd))) { + switch (buf[0]) { + case 0x14: + case 0x15: + case 0x16: + case 0x17: + return 1; + default:; + } } return 0; } /* 0 - 1.0, 1 - 1.2 */ -int get_dtls_version(const unsigned char* buf, int len) { - if(buf && (len>3) && (buf[2] == 0xfd)) - return 1; - return 0; +int get_dtls_version(const unsigned char *buf, int len) { + if (buf && (len > 3) && (buf[2] == 0xfd)) + return 1; + return 0; } ///////////// utils ///////////////////// #if DTLS_SUPPORTED -static void calculate_cookie(SSL* ssl, unsigned char *cookie_secret, unsigned int cookie_length) { - long rv=(long)ssl; - long inum=(cookie_length-(((long)cookie_secret)%sizeof(long)))/sizeof(long); - long i=0; - long *ip=(long*)cookie_secret; - for(i=0;i= 0x10100000L - const + const #endif - unsigned char *cookie, unsigned int cookie_len) -{ - unsigned int resultlength=0; + unsigned char *cookie, + unsigned int cookie_len) { + unsigned int resultlength = 0; unsigned char result[COOKIE_SECRET_LENGTH]; generate_cookie(ssl, result, &resultlength); - + if (cookie_len == resultlength && memcmp(result, cookie, resultlength) == 0) { - //TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s: cookies are OK, length=%u\n",__FUNCTION__,cookie_len); - return 1; + // TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s: cookies are OK, length=%u\n",__FUNCTION__,cookie_len); + return 1; } else { - //TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s: cookies are OK, length=%u\n",__FUNCTION__,cookie_len); - return 0; + // TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s: cookies are OK, length=%u\n",__FUNCTION__,cookie_len); + return 0; } } /////////////// io handlers /////////////////// -static ioa_socket_handle dtls_accept_client_connection( - dtls_listener_relay_server_type* server, - ioa_socket_handle sock, - SSL *ssl, - ioa_addr *remote_addr, ioa_addr *local_addr, - ioa_network_buffer_handle nbh) -{ - FUNCSTART; +static ioa_socket_handle dtls_accept_client_connection(dtls_listener_relay_server_type *server, ioa_socket_handle sock, + SSL *ssl, ioa_addr *remote_addr, ioa_addr *local_addr, + ioa_network_buffer_handle nbh) { + FUNCSTART; - if (!ssl) - return NULL; + if (!ssl) + return NULL; - int rc = ssl_read(sock->fd, ssl, nbh, server->verbose); + int rc = ssl_read(sock->fd, ssl, nbh, server->verbose); - if (rc < 0) - return NULL; + if (rc < 0) + return NULL; - addr_debug_print(server->verbose, remote_addr, "Accepted connection from"); + addr_debug_print(server->verbose, remote_addr, "Accepted connection from"); - ioa_socket_handle ioas = create_ioa_socket_from_ssl(server->e, sock, ssl, DTLS_SOCKET, CLIENT_SOCKET, remote_addr, local_addr); - if(ioas) { - addr_cpy(&(server->sm.m.sm.nd.src_addr),remote_addr); - server->sm.m.sm.nd.recv_ttl = TTL_IGNORE; - server->sm.m.sm.nd.recv_tos = TOS_IGNORE; - server->sm.m.sm.s = ioas; - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot create ioa_socket from SSL\n"); - } + ioa_socket_handle ioas = + create_ioa_socket_from_ssl(server->e, sock, ssl, DTLS_SOCKET, CLIENT_SOCKET, remote_addr, local_addr); + if (ioas) { + addr_cpy(&(server->sm.m.sm.nd.src_addr), remote_addr); + server->sm.m.sm.nd.recv_ttl = TTL_IGNORE; + server->sm.m.sm.nd.recv_tos = TOS_IGNORE; + server->sm.m.sm.s = ioas; + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot create ioa_socket from SSL\n"); + } - FUNCEND ; + FUNCEND; - return ioas; + return ioas; } -static ioa_socket_handle dtls_server_input_handler(dtls_listener_relay_server_type* server, - ioa_socket_handle s, - ioa_network_buffer_handle nbh) -{ - FUNCSTART; +static ioa_socket_handle dtls_server_input_handler(dtls_listener_relay_server_type *server, ioa_socket_handle s, + ioa_network_buffer_handle nbh) { + FUNCSTART; - if (!server || !nbh) { - return NULL; - } + if (!server || !nbh) { + return NULL; + } - SSL* connecting_ssl = NULL; + SSL *connecting_ssl = NULL; - BIO *wbio = NULL; - struct timeval timeout; + BIO *wbio = NULL; + struct timeval timeout; - /* Create BIO */ - wbio = BIO_new_dgram(s->fd, BIO_NOCLOSE); - (void)BIO_dgram_set_peer(wbio, (struct sockaddr*) &(server->sm.m.sm.nd.src_addr)); + /* Create BIO */ + wbio = BIO_new_dgram(s->fd, BIO_NOCLOSE); + (void)BIO_dgram_set_peer(wbio, (struct sockaddr *)&(server->sm.m.sm.nd.src_addr)); - /* Set and activate timeouts */ - timeout.tv_sec = DTLS_MAX_RECV_TIMEOUT; - timeout.tv_usec = 0; - BIO_ctrl(wbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); + /* Set and activate timeouts */ + timeout.tv_sec = DTLS_MAX_RECV_TIMEOUT; + timeout.tv_usec = 0; + BIO_ctrl(wbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); - connecting_ssl = SSL_new(server->e->dtls_ctx); + connecting_ssl = SSL_new(server->e->dtls_ctx); - SSL_set_accept_state(connecting_ssl); + SSL_set_accept_state(connecting_ssl); - SSL_set_bio(connecting_ssl, NULL, wbio); - SSL_set_options(connecting_ssl, SSL_OP_COOKIE_EXCHANGE + SSL_set_bio(connecting_ssl, NULL, wbio); + SSL_set_options(connecting_ssl, SSL_OP_COOKIE_EXCHANGE #if OPENSSL_VERSION_NUMBER < 0x10100000L #if defined(SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) - | SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS + | SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS #endif #else #if defined(SSL_OP_NO_RENEGOTIATION) - | SSL_OP_NO_RENEGOTIATION + | SSL_OP_NO_RENEGOTIATION #endif #endif - ); - SSL_set_max_cert_list(connecting_ssl, 655350); + ); + SSL_set_max_cert_list(connecting_ssl, 655350); - ioa_socket_handle rc = dtls_accept_client_connection(server, s, connecting_ssl, - &(server->sm.m.sm.nd.src_addr), - &(server->addr), - nbh); + ioa_socket_handle rc = + dtls_accept_client_connection(server, s, connecting_ssl, &(server->sm.m.sm.nd.src_addr), &(server->addr), nbh); - if (!rc) { - if (!(SSL_get_shutdown(connecting_ssl) & SSL_SENT_SHUTDOWN)) { - SSL_set_shutdown(connecting_ssl, SSL_RECEIVED_SHUTDOWN); - SSL_shutdown(connecting_ssl); - } - SSL_free(connecting_ssl); - } + if (!rc) { + if (!(SSL_get_shutdown(connecting_ssl) & SSL_SENT_SHUTDOWN)) { + SSL_set_shutdown(connecting_ssl, SSL_RECEIVED_SHUTDOWN); + SSL_shutdown(connecting_ssl); + } + SSL_free(connecting_ssl); + } - return rc; + return rc; } #endif -static int handle_udp_packet(dtls_listener_relay_server_type *server, - struct message_to_relay *sm, - ioa_engine_handle ioa_eng, turn_turnserver *ts) -{ - int verbose = ioa_eng->verbose; - ioa_socket_handle s = sm->m.sm.s; +static int handle_udp_packet(dtls_listener_relay_server_type *server, struct message_to_relay *sm, + ioa_engine_handle ioa_eng, turn_turnserver *ts) { + int verbose = ioa_eng->verbose; + ioa_socket_handle s = sm->m.sm.s; - ur_addr_map_value_type mvt = 0; - if(!(server->children_ss)) { - server->children_ss = (ur_addr_map*)allocate_super_memory_engine(server->e, sizeof(ur_addr_map)); - ur_addr_map_init(server->children_ss); - } - ur_addr_map *amap = server->children_ss; + ur_addr_map_value_type mvt = 0; + if (!(server->children_ss)) { + server->children_ss = (ur_addr_map *)allocate_super_memory_engine(server->e, sizeof(ur_addr_map)); + ur_addr_map_init(server->children_ss); + } + ur_addr_map *amap = server->children_ss; - ioa_socket_handle chs = NULL; - if ((ur_addr_map_get(amap, &(sm->m.sm.nd.src_addr), &mvt) > 0) && mvt) { - chs = (ioa_socket_handle) mvt; - } + ioa_socket_handle chs = NULL; + if ((ur_addr_map_get(amap, &(sm->m.sm.nd.src_addr), &mvt) > 0) && mvt) { + chs = (ioa_socket_handle)mvt; + } - if (chs && !ioa_socket_tobeclosed(chs) - && (chs->sockets_container == amap) - && (chs->magic == SOCKET_MAGIC)) { - s = chs; - sm->m.sm.s = s; - if(s->ssl) { - int sslret = ssl_read(s->fd, s->ssl, sm->m.sm.nd.nbh, verbose); - if(sslret < 0) { - ioa_network_buffer_delete(ioa_eng, sm->m.sm.nd.nbh); - sm->m.sm.nd.nbh = NULL; - ts_ur_super_session *ss = (ts_ur_super_session *) s->session; - if (ss) { - turn_turnserver *server = (turn_turnserver *) ss->server; - if (server) { - shutdown_client_connection(server, ss, 0, "SSL read error"); - } - } else { - close_ioa_socket(s); - } - ur_addr_map_del(amap, &(sm->m.sm.nd.src_addr), NULL); - sm->m.sm.s = NULL; - s = NULL; - chs = NULL; - } else if(ioa_network_buffer_get_size(sm->m.sm.nd.nbh)>0) { - ; - } else { - ioa_network_buffer_delete(ioa_eng, sm->m.sm.nd.nbh); - sm->m.sm.nd.nbh = NULL; - } - } + if (chs && !ioa_socket_tobeclosed(chs) && (chs->sockets_container == amap) && (chs->magic == SOCKET_MAGIC)) { + s = chs; + sm->m.sm.s = s; + if (s->ssl) { + int sslret = ssl_read(s->fd, s->ssl, sm->m.sm.nd.nbh, verbose); + if (sslret < 0) { + ioa_network_buffer_delete(ioa_eng, sm->m.sm.nd.nbh); + sm->m.sm.nd.nbh = NULL; + ts_ur_super_session *ss = (ts_ur_super_session *)s->session; + if (ss) { + turn_turnserver *server = (turn_turnserver *)ss->server; + if (server) { + shutdown_client_connection(server, ss, 0, "SSL read error"); + } + } else { + close_ioa_socket(s); + } + ur_addr_map_del(amap, &(sm->m.sm.nd.src_addr), NULL); + sm->m.sm.s = NULL; + s = NULL; + chs = NULL; + } else if (ioa_network_buffer_get_size(sm->m.sm.nd.nbh) > 0) { + ; + } else { + ioa_network_buffer_delete(ioa_eng, sm->m.sm.nd.nbh); + sm->m.sm.nd.nbh = NULL; + } + } - if(s && ioa_socket_check_bandwidth(s,sm->m.sm.nd.nbh,1)) { - s->e = ioa_eng; - if (s && s->read_cb && sm->m.sm.nd.nbh) { - s->read_cb(s, IOA_EV_READ, &(sm->m.sm.nd), s->read_ctx, 1); - ioa_network_buffer_delete(ioa_eng, sm->m.sm.nd.nbh); - sm->m.sm.nd.nbh = NULL; + if (s && ioa_socket_check_bandwidth(s, sm->m.sm.nd.nbh, 1)) { + s->e = ioa_eng; + if (s && s->read_cb && sm->m.sm.nd.nbh) { + s->read_cb(s, IOA_EV_READ, &(sm->m.sm.nd), s->read_ctx, 1); + ioa_network_buffer_delete(ioa_eng, sm->m.sm.nd.nbh); + sm->m.sm.nd.nbh = NULL; - if (ioa_socket_tobeclosed(s)) { - ts_ur_super_session *ss = (ts_ur_super_session *) s->session; - if (ss) { - turn_turnserver *server = (turn_turnserver *) ss->server; - if (server) { - shutdown_client_connection(server, ss, 0, "UDP packet processing error"); - } - } - } - } - } - } else { - if (chs && ioa_socket_tobeclosed(chs)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: socket to be closed\n", __FUNCTION__); - { - uint8_t saddr[129]; - uint8_t rsaddr[129]; - addr_to_string(get_local_addr_from_ioa_socket(chs),saddr); - addr_to_string(get_remote_addr_from_ioa_socket(chs),rsaddr); - long thrid = 0; + if (ioa_socket_tobeclosed(s)) { + ts_ur_super_session *ss = (ts_ur_super_session *)s->session; + if (ss) { + turn_turnserver *server = (turn_turnserver *)ss->server; + if (server) { + shutdown_client_connection(server, ss, 0, "UDP packet processing error"); + } + } + } + } + } + } else { + if (chs && ioa_socket_tobeclosed(chs)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: socket to be closed\n", __FUNCTION__); + { + uint8_t saddr[129]; + uint8_t rsaddr[129]; + addr_to_string(get_local_addr_from_ioa_socket(chs), saddr); + addr_to_string(get_remote_addr_from_ioa_socket(chs), rsaddr); + long thrid = 0; #ifdef WINDOWS - thrid = GetCurrentThreadId(); + thrid = GetCurrentThreadId(); #else - thrid = (long)pthread_self(); + thrid = (long)pthread_self(); #endif - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: 111.111: thrid=0x%lx: Amap = 0x%lx, socket container=0x%lx, local addr %s, remote addr %s, s=0x%lx, done=%d, tbc=%d\n", - __FUNCTION__, thrid, (long)amap, - (long)(chs->sockets_container), (char*)saddr, - (char*)rsaddr, (long)s, (int)(chs->done), - (int)(chs->tobeclosed)); - } - } + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, + "%s: 111.111: thrid=0x%lx: Amap = 0x%lx, socket container=0x%lx, local addr %s, remote addr %s, " + "s=0x%lx, done=%d, tbc=%d\n", + __FUNCTION__, thrid, (long)amap, (long)(chs->sockets_container), (char *)saddr, (char *)rsaddr, + (long)s, (int)(chs->done), (int)(chs->tobeclosed)); + } + } - if (chs && (chs->magic != SOCKET_MAGIC)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: wrong socket magic\n", __FUNCTION__); - } + if (chs && (chs->magic != SOCKET_MAGIC)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: wrong socket magic\n", __FUNCTION__); + } - if (chs && (chs->sockets_container != amap)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: wrong socket container\n", __FUNCTION__); - { - uint8_t saddr[129]; - uint8_t rsaddr[129]; + if (chs && (chs->sockets_container != amap)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: wrong socket container\n", __FUNCTION__); + { + uint8_t saddr[129]; + uint8_t rsaddr[129]; - addr_to_string(get_local_addr_from_ioa_socket(chs),saddr); - addr_to_string(get_remote_addr_from_ioa_socket(chs),rsaddr); - long thrid = 0; + addr_to_string(get_local_addr_from_ioa_socket(chs), saddr); + addr_to_string(get_remote_addr_from_ioa_socket(chs), rsaddr); + long thrid = 0; #ifdef WINDOWS - thrid = GetCurrentThreadId(); + thrid = GetCurrentThreadId(); #else - thrid = (long)pthread_self(); + thrid = (long)pthread_self(); #endif - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: 111.222: thrid=0x%lx: Amap = 0x%lx, socket container=0x%lx, local addr %s, remote addr %s, s=0x%lx, done=%d, tbc=%d, st=%d, sat=%d\n", - __FUNCTION__, thrid, (long)amap, - (long)(chs->sockets_container), (char*)saddr, - (char*)rsaddr, (long)chs, (int)(chs->done), - (int)(chs->tobeclosed), (int)(chs->st), - (int)(chs->sat)); - } - } + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, + "%s: 111.222: thrid=0x%lx: Amap = 0x%lx, socket container=0x%lx, local addr %s, remote addr %s, " + "s=0x%lx, done=%d, tbc=%d, st=%d, sat=%d\n", + __FUNCTION__, thrid, (long)amap, (long)(chs->sockets_container), (char *)saddr, (char *)rsaddr, + (long)chs, (int)(chs->done), (int)(chs->tobeclosed), (int)(chs->st), (int)(chs->sat)); + } + } - chs = NULL; + chs = NULL; #if DTLS_SUPPORTED - if (!turn_params.no_dtls && - is_dtls_handshake_message(ioa_network_buffer_data(sm->m.sm.nd.nbh), - (int)ioa_network_buffer_get_size(sm->m.sm.nd.nbh))) { - chs = dtls_server_input_handler(server,s, sm->m.sm.nd.nbh); - ioa_network_buffer_delete(server->e, sm->m.sm.nd.nbh); - sm->m.sm.nd.nbh = NULL; - } + if (!turn_params.no_dtls && is_dtls_handshake_message(ioa_network_buffer_data(sm->m.sm.nd.nbh), + (int)ioa_network_buffer_get_size(sm->m.sm.nd.nbh))) { + chs = dtls_server_input_handler(server, s, sm->m.sm.nd.nbh); + ioa_network_buffer_delete(server->e, sm->m.sm.nd.nbh); + sm->m.sm.nd.nbh = NULL; + } #endif - if(!chs) { - // Disallow raw UDP if no_udp is enabled - if(turn_params.no_udp) { - return -1; - } - chs = create_ioa_socket_from_fd(ioa_eng, s->fd, s, - UDP_SOCKET, CLIENT_SOCKET, &(sm->m.sm.nd.src_addr), - get_local_addr_from_ioa_socket(s)); - } + if (!chs) { + // Disallow raw UDP if no_udp is enabled + if (turn_params.no_udp) { + return -1; + } + chs = create_ioa_socket_from_fd(ioa_eng, s->fd, s, UDP_SOCKET, CLIENT_SOCKET, &(sm->m.sm.nd.src_addr), + get_local_addr_from_ioa_socket(s)); + } - s = chs; - sm->m.sm.s = s; + s = chs; + sm->m.sm.s = s; - if (s) { - if(verbose && turn_params.log_binding) { - uint8_t saddr[129]; - uint8_t rsaddr[129]; - addr_to_string(get_local_addr_from_ioa_socket(s),saddr); - addr_to_string(get_remote_addr_from_ioa_socket(s),rsaddr); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: New UDP endpoint: local addr %s, remote addr %s\n", - __FUNCTION__, (char*) saddr,(char*) rsaddr); - } - s->e = ioa_eng; - add_socket_to_map(s, amap); - if(open_client_connection_session(ts, &(sm->m.sm))<0) { - return -1; - } - } - } + if (s) { + if (verbose && turn_params.log_binding) { + uint8_t saddr[129]; + uint8_t rsaddr[129]; + addr_to_string(get_local_addr_from_ioa_socket(s), saddr); + addr_to_string(get_remote_addr_from_ioa_socket(s), rsaddr); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: New UDP endpoint: local addr %s, remote addr %s\n", __FUNCTION__, + (char *)saddr, (char *)rsaddr); + } + s->e = ioa_eng; + add_socket_to_map(s, amap); + if (open_client_connection_session(ts, &(sm->m.sm)) < 0) { + return -1; + } + } + } - return 0; + return 0; } -static int create_new_connected_udp_socket( - dtls_listener_relay_server_type* server, ioa_socket_handle s) -{ +static int create_new_connected_udp_socket(dtls_listener_relay_server_type *server, ioa_socket_handle s) { - evutil_socket_t udp_fd = socket(s->local_addr.ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL); - if (udp_fd < 0) { - perror("socket"); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot allocate new socket\n", - __FUNCTION__); - return -1; - } + evutil_socket_t udp_fd = socket(s->local_addr.ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL); + if (udp_fd < 0) { + perror("socket"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot allocate new socket\n", __FUNCTION__); + return -1; + } - if (sock_bind_to_device(udp_fd, (unsigned char*) (s->e->relay_ifname)) - < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Cannot bind udp server socket to device %s\n", - (char*) (s->e->relay_ifname)); - } + if (sock_bind_to_device(udp_fd, (unsigned char *)(s->e->relay_ifname)) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot bind udp server socket to device %s\n", (char *)(s->e->relay_ifname)); + } - ioa_socket_handle ret = (ioa_socket*) malloc(sizeof(ioa_socket)); - if (!ret) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: Cannot allocate new socket structure\n", __FUNCTION__); - close(udp_fd); - return -1; - } + ioa_socket_handle ret = (ioa_socket *)malloc(sizeof(ioa_socket)); + if (!ret) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot allocate new socket structure\n", __FUNCTION__); + close(udp_fd); + return -1; + } - memset(ret, 0, sizeof(ioa_socket)); + memset(ret, 0, sizeof(ioa_socket)); - ret->magic = SOCKET_MAGIC; + ret->magic = SOCKET_MAGIC; - ret->fd = udp_fd; + ret->fd = udp_fd; - ret->family = s->family; - ret->st = s->st; - ret->sat = CLIENT_SOCKET; - ret->local_addr_known = 1; - addr_cpy(&(ret->local_addr), &(s->local_addr)); + ret->family = s->family; + ret->st = s->st; + ret->sat = CLIENT_SOCKET; + ret->local_addr_known = 1; + addr_cpy(&(ret->local_addr), &(s->local_addr)); - if (addr_bind(udp_fd,&(s->local_addr),1,1,UDP_SOCKET) < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Cannot bind new detached udp server socket to local addr\n"); - IOA_CLOSE_SOCKET(ret); - return -1; - } - ret->bound = 1; + if (addr_bind(udp_fd, &(s->local_addr), 1, 1, UDP_SOCKET) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot bind new detached udp server socket to local addr\n"); + IOA_CLOSE_SOCKET(ret); + return -1; + } + ret->bound = 1; - { - int connect_err = 0; - if (addr_connect(udp_fd, &(server->sm.m.sm.nd.src_addr), &connect_err) < 0) { - char sl[129]; - char sr[129]; - addr_to_string(&(ret->local_addr),(uint8_t*)sl); - addr_to_string(&(server->sm.m.sm.nd.src_addr),(uint8_t*)sr); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Cannot connect new detached udp client socket from local addr %s to remote addr %s\n",sl,sr); - IOA_CLOSE_SOCKET(ret); - return -1; - } - } - ret->connected = 1; - addr_cpy(&(ret->remote_addr), &(server->sm.m.sm.nd.src_addr)); + { + int connect_err = 0; + if (addr_connect(udp_fd, &(server->sm.m.sm.nd.src_addr), &connect_err) < 0) { + char sl[129]; + char sr[129]; + addr_to_string(&(ret->local_addr), (uint8_t *)sl); + addr_to_string(&(server->sm.m.sm.nd.src_addr), (uint8_t *)sr); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, + "Cannot connect new detached udp client socket from local addr %s to remote addr %s\n", sl, sr); + IOA_CLOSE_SOCKET(ret); + return -1; + } + } + ret->connected = 1; + addr_cpy(&(ret->remote_addr), &(server->sm.m.sm.nd.src_addr)); - set_socket_options(ret); + set_socket_options(ret); - ret->current_ttl = s->current_ttl; - ret->default_ttl = s->default_ttl; + ret->current_ttl = s->current_ttl; + ret->default_ttl = s->default_ttl; - ret->current_tos = s->current_tos; - ret->default_tos = s->default_tos; + ret->current_tos = s->current_tos; + ret->default_tos = s->default_tos; #if DTLS_SUPPORTED - if (!turn_params.no_dtls - && is_dtls_handshake_message( - ioa_network_buffer_data(server->sm.m.sm.nd.nbh), - (int) ioa_network_buffer_get_size( - server->sm.m.sm.nd.nbh))) { + if (!turn_params.no_dtls && is_dtls_handshake_message(ioa_network_buffer_data(server->sm.m.sm.nd.nbh), + (int)ioa_network_buffer_get_size(server->sm.m.sm.nd.nbh))) { - SSL* connecting_ssl = NULL; + SSL *connecting_ssl = NULL; - BIO *wbio = NULL; - struct timeval timeout; + BIO *wbio = NULL; + struct timeval timeout; - /* Create BIO */ - wbio = BIO_new_dgram(ret->fd, BIO_NOCLOSE); - (void) BIO_dgram_set_peer(wbio, (struct sockaddr*) &(server->sm.m.sm.nd.src_addr)); + /* Create BIO */ + wbio = BIO_new_dgram(ret->fd, BIO_NOCLOSE); + (void)BIO_dgram_set_peer(wbio, (struct sockaddr *)&(server->sm.m.sm.nd.src_addr)); - BIO_ctrl(wbio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &(server->sm.m.sm.nd.src_addr)); + BIO_ctrl(wbio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &(server->sm.m.sm.nd.src_addr)); - /* Set and activate timeouts */ - timeout.tv_sec = DTLS_MAX_RECV_TIMEOUT; - timeout.tv_usec = 0; - BIO_ctrl(wbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); + /* Set and activate timeouts */ + timeout.tv_sec = DTLS_MAX_RECV_TIMEOUT; + timeout.tv_usec = 0; + BIO_ctrl(wbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); - connecting_ssl = SSL_new(server->e->dtls_ctx); + connecting_ssl = SSL_new(server->e->dtls_ctx); - SSL_set_accept_state(connecting_ssl); + SSL_set_accept_state(connecting_ssl); - SSL_set_bio(connecting_ssl, NULL, wbio); + SSL_set_bio(connecting_ssl, NULL, wbio); - SSL_set_options(connecting_ssl, SSL_OP_COOKIE_EXCHANGE + SSL_set_options(connecting_ssl, SSL_OP_COOKIE_EXCHANGE #if OPENSSL_VERSION_NUMBER < 0x10100000L #if defined(SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) - | SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS + | SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS #endif #else #if defined(SSL_OP_NO_RENEGOTIATION) - | SSL_OP_NO_RENEGOTIATION + | SSL_OP_NO_RENEGOTIATION #endif #endif - ); + ); - SSL_set_max_cert_list(connecting_ssl, 655350); - int rc = ssl_read(ret->fd, connecting_ssl, server->sm.m.sm.nd.nbh, - server->verbose); + SSL_set_max_cert_list(connecting_ssl, 655350); + int rc = ssl_read(ret->fd, connecting_ssl, server->sm.m.sm.nd.nbh, server->verbose); - if (rc < 0) { - if (!(SSL_get_shutdown(connecting_ssl) & SSL_SENT_SHUTDOWN)) { - SSL_set_shutdown(connecting_ssl, SSL_RECEIVED_SHUTDOWN); - SSL_shutdown(connecting_ssl); - } - SSL_free(connecting_ssl); - IOA_CLOSE_SOCKET(ret); - return -1; - } + if (rc < 0) { + if (!(SSL_get_shutdown(connecting_ssl) & SSL_SENT_SHUTDOWN)) { + SSL_set_shutdown(connecting_ssl, SSL_RECEIVED_SHUTDOWN); + SSL_shutdown(connecting_ssl); + } + SSL_free(connecting_ssl); + IOA_CLOSE_SOCKET(ret); + return -1; + } - addr_debug_print(server->verbose, &(server->sm.m.sm.nd.src_addr), - "Accepted DTLS connection from"); + addr_debug_print(server->verbose, &(server->sm.m.sm.nd.src_addr), "Accepted DTLS connection from"); - ret->ssl = connecting_ssl; + ret->ssl = connecting_ssl; - ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh); - server->sm.m.sm.nd.nbh = NULL; + ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh); + server->sm.m.sm.nd.nbh = NULL; - ret->st = DTLS_SOCKET; - } + ret->st = DTLS_SOCKET; + } #endif - server->sm.m.sm.s = ret; - return server->connect_cb(server->e, &(server->sm)); + server->sm.m.sm.s = ret; + return server->connect_cb(server->e, &(server->sm)); } -static void udp_server_input_handler(evutil_socket_t fd, short what, void* arg) -{ - int cycle = 0; +static void udp_server_input_handler(evutil_socket_t fd, short what, void *arg) { + int cycle = 0; - dtls_listener_relay_server_type* server = (dtls_listener_relay_server_type*)arg; - ioa_socket_handle s = server->udp_listen_s; + dtls_listener_relay_server_type *server = (dtls_listener_relay_server_type *)arg; + ioa_socket_handle s = server->udp_listen_s; - FUNCSTART; + FUNCSTART; - if (!(what & EV_READ)) { - return; - } + if (!(what & EV_READ)) { + return; + } - //printf_server_socket(server, fd); + // printf_server_socket(server, fd); - ioa_network_buffer_handle *elem = NULL; + ioa_network_buffer_handle *elem = NULL; - start_udp_cycle: +start_udp_cycle: - elem = (ioa_network_buffer_handle *)ioa_network_buffer_allocate(server->e); + elem = (ioa_network_buffer_handle *)ioa_network_buffer_allocate(server->e); - server->sm.m.sm.nd.nbh = elem; - server->sm.m.sm.nd.recv_ttl = TTL_IGNORE; - server->sm.m.sm.nd.recv_tos = TOS_IGNORE; - server->sm.m.sm.can_resume = 1; + server->sm.m.sm.nd.nbh = elem; + server->sm.m.sm.nd.recv_ttl = TTL_IGNORE; + server->sm.m.sm.nd.recv_tos = TOS_IGNORE; + server->sm.m.sm.can_resume = 1; - addr_set_any(&(server->sm.m.sm.nd.src_addr)); + addr_set_any(&(server->sm.m.sm.nd.src_addr)); - ssize_t bsize = 0; + ssize_t bsize = 0; #if defined(WINDOWS) - //TODO: implement it!!! - int flags = 0; + // TODO: implement it!!! + int flags = 0; #else - int flags = MSG_DONTWAIT; + int flags = MSG_DONTWAIT; #endif - bsize = udp_recvfrom(fd, &(server->sm.m.sm.nd.src_addr), &(server->addr), - (char*)ioa_network_buffer_data(elem), (int)ioa_network_buffer_get_capacity_udp(), - &(server->sm.m.sm.nd.recv_ttl), &(server->sm.m.sm.nd.recv_tos), - server->e->cmsg, flags, NULL); + bsize = udp_recvfrom(fd, &(server->sm.m.sm.nd.src_addr), &(server->addr), (char *)ioa_network_buffer_data(elem), + (int)ioa_network_buffer_get_capacity_udp(), &(server->sm.m.sm.nd.recv_ttl), + &(server->sm.m.sm.nd.recv_tos), server->e->cmsg, flags, NULL); - int conn_reset = is_connreset(); - int to_block = would_block(); + int conn_reset = is_connreset(); + int to_block = would_block(); - if (bsize < 0) { + if (bsize < 0) { - if(to_block) { - ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh); - server->sm.m.sm.nd.nbh = NULL; - FUNCEND; - return; - } + if (to_block) { + ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh); + server->sm.m.sm.nd.nbh = NULL; + FUNCEND; + return; + } - #if defined(MSG_ERRQUEUE) +#if defined(MSG_ERRQUEUE) #if defined(WINDOWS) - //TODO: implement it!!! - int eflags = MSG_ERRQUEUE; + // TODO: implement it!!! + int eflags = MSG_ERRQUEUE; #else - //Linux - int eflags = MSG_ERRQUEUE | MSG_DONTWAIT; + // Linux + int eflags = MSG_ERRQUEUE | MSG_DONTWAIT; #endif - static char buffer[65535]; - uint32_t errcode = 0; - ioa_addr orig_addr; - int ttl = 0; - int tos = 0; - int slen = server->slen0; - udp_recvfrom(fd, &orig_addr, &(server->addr), buffer, - (int) sizeof(buffer), &ttl, &tos, server->e->cmsg, eflags, - &errcode); - //try again... - do { - bsize = recvfrom(fd, ioa_network_buffer_data(elem), ioa_network_buffer_get_capacity_udp(), flags, (struct sockaddr*) &(server->sm.m.sm.nd.src_addr), (socklen_t*) &slen); - } while (bsize < 0 && (errno == EINTR)); + static char buffer[65535]; + uint32_t errcode = 0; + ioa_addr orig_addr; + int ttl = 0; + int tos = 0; + int slen = server->slen0; + udp_recvfrom(fd, &orig_addr, &(server->addr), buffer, (int)sizeof(buffer), &ttl, &tos, server->e->cmsg, eflags, + &errcode); + // try again... + do { + bsize = recvfrom(fd, ioa_network_buffer_data(elem), ioa_network_buffer_get_capacity_udp(), flags, + (struct sockaddr *)&(server->sm.m.sm.nd.src_addr), (socklen_t *)&slen); + } while (bsize < 0 && (errno == EINTR)); - conn_reset = is_connreset(); - to_block = would_block(); + conn_reset = is_connreset(); + to_block = would_block(); - #endif +#endif - if(conn_reset) { - ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh); - server->sm.m.sm.nd.nbh = NULL; - reopen_server_socket(server,fd); - FUNCEND; - return; - } - } + if (conn_reset) { + ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh); + server->sm.m.sm.nd.nbh = NULL; + reopen_server_socket(server, fd); + FUNCEND; + return; + } + } - if(bsize<0) { - if(!to_block && !conn_reset) { - int ern=errno; - perror(__FUNCTION__); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: recvfrom error %d\n",__FUNCTION__,ern); - } - ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh); - server->sm.m.sm.nd.nbh = NULL; - FUNCEND; - return; - } + if (bsize < 0) { + if (!to_block && !conn_reset) { + int ern = errno; + perror(__FUNCTION__); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: recvfrom error %d\n", __FUNCTION__, ern); + } + ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh); + server->sm.m.sm.nd.nbh = NULL; + FUNCEND; + return; + } - if (bsize > 0) { + if (bsize > 0) { - int rc = 0; - ioa_network_buffer_set_size(elem, (size_t)bsize); + int rc = 0; + ioa_network_buffer_set_size(elem, (size_t)bsize); - if(server->connect_cb) { + if (server->connect_cb) { - rc = create_new_connected_udp_socket(server, s); - if(rc<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot handle UDP packet, size %d\n",(int)bsize); - } + rc = create_new_connected_udp_socket(server, s); + if (rc < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot handle UDP packet, size %d\n", (int)bsize); + } - } else { - server->sm.m.sm.s = s; - rc = handle_udp_packet(server, &(server->sm), server->e, server->ts); - } + } else { + server->sm.m.sm.s = s; + rc = handle_udp_packet(server, &(server->sm), server->e, server->ts); + } - if(rc < 0) { - if(eve(server->e->verbose)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot handle UDP event\n"); - } - } - } + if (rc < 0) { + if (eve(server->e->verbose)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot handle UDP event\n"); + } + } + } - ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh); - server->sm.m.sm.nd.nbh = NULL; + ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh); + server->sm.m.sm.nd.nbh = NULL; - if((bsize>0) && (cycle++ 0) && (cycle++ < MAX_SINGLE_UDP_BATCH)) + goto start_udp_cycle; - FUNCEND; + FUNCEND; } ///////////////////// operations ////////////////////////// -static int create_server_socket(dtls_listener_relay_server_type* server, int report_creation) { +static int create_server_socket(dtls_listener_relay_server_type *server, int report_creation) { FUNCSTART; - if(!server) return -1; + if (!server) + return -1; clean_server(server); { - ioa_socket_raw udp_listen_fd = -1; + ioa_socket_raw udp_listen_fd = -1; - udp_listen_fd = socket(server->addr.ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL); - if (udp_listen_fd < 0) { - perror("socket"); - return -1; - } + udp_listen_fd = socket(server->addr.ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL); + if (udp_listen_fd < 0) { + perror("socket"); + return -1; + } - server->udp_listen_s = create_ioa_socket_from_fd(server->e, udp_listen_fd, NULL, UDP_SOCKET, LISTENER_SOCKET, NULL, &(server->addr)); + server->udp_listen_s = + create_ioa_socket_from_fd(server->e, udp_listen_fd, NULL, UDP_SOCKET, LISTENER_SOCKET, NULL, &(server->addr)); - set_sock_buf_size(udp_listen_fd,UR_SERVER_SOCK_BUF_SIZE); + set_sock_buf_size(udp_listen_fd, UR_SERVER_SOCK_BUF_SIZE); - if(sock_bind_to_device(udp_listen_fd, (unsigned char*)server->ifname)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind listener socket to device %s\n",server->ifname); - } + if (sock_bind_to_device(udp_listen_fd, (unsigned char *)server->ifname) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Cannot bind listener socket to device %s\n", server->ifname); + } - set_raw_socket_ttl_options(udp_listen_fd, server->addr.ss.sa_family); - set_raw_socket_tos_options(udp_listen_fd, server->addr.ss.sa_family); + set_raw_socket_ttl_options(udp_listen_fd, server->addr.ss.sa_family); + set_raw_socket_tos_options(udp_listen_fd, server->addr.ss.sa_family); - { - const int max_binding_time = 60; - int addr_bind_cycle = 0; - retry_addr_bind: + { + const int max_binding_time = 60; + int addr_bind_cycle = 0; + retry_addr_bind: - if(addr_bind(udp_listen_fd,&server->addr,1,1,UDP_SOCKET)<0) { - perror("Cannot bind local socket to addr"); - char saddr[129]; - addr_to_string(&server->addr,(uint8_t*)saddr); - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"Cannot bind DTLS/UDP listener socket to addr %s\n",saddr); - if(addr_bind_cycle++addr, 1, 1, UDP_SOCKET) < 0) { + perror("Cannot bind local socket to addr"); + char saddr[129]; + addr_to_string(&server->addr, (uint8_t *)saddr); + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Cannot bind DTLS/UDP listener socket to addr %s\n", saddr); + if (addr_bind_cycle++ < max_binding_time) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Trying to bind DTLS/UDP listener socket to addr %s, again...\n", saddr); + sleep(1); + goto retry_addr_bind; + } + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Fatal final failure: cannot bind DTLS/UDP listener socket to addr %s\n", + saddr); + exit(-1); + } + } - server->udp_listen_ev = event_new(server->e->event_base,udp_listen_fd, - EV_READ|EV_PERSIST,udp_server_input_handler, - server); + server->udp_listen_ev = + event_new(server->e->event_base, udp_listen_fd, EV_READ | EV_PERSIST, udp_server_input_handler, server); - event_add(server->udp_listen_ev,NULL); + event_add(server->udp_listen_ev, NULL); } - if(report_creation) { - if(!turn_params.no_udp && !turn_params.no_dtls) - addr_debug_print(server->verbose, &server->addr,"DTLS/UDP listener opened on"); - else if(!turn_params.no_dtls) - addr_debug_print(server->verbose, &server->addr,"DTLS listener opened on"); - else if(!turn_params.no_udp) - addr_debug_print(server->verbose, &server->addr,"UDP listener opened on"); + if (report_creation) { + if (!turn_params.no_udp && !turn_params.no_dtls) + addr_debug_print(server->verbose, &server->addr, "DTLS/UDP listener opened on"); + else if (!turn_params.no_dtls) + addr_debug_print(server->verbose, &server->addr, "DTLS listener opened on"); + else if (!turn_params.no_udp) + addr_debug_print(server->verbose, &server->addr, "UDP listener opened on"); } FUNCEND; - + return 0; } -static int reopen_server_socket(dtls_listener_relay_server_type* server, evutil_socket_t fd) -{ - UNUSED_ARG(fd); +static int reopen_server_socket(dtls_listener_relay_server_type *server, evutil_socket_t fd) { + UNUSED_ARG(fd); - if(!server) - return 0; + if (!server) + return 0; - FUNCSTART; + FUNCSTART; - { - EVENT_DEL(server->udp_listen_ev); + { + EVENT_DEL(server->udp_listen_ev); - if(server->udp_listen_s->fd>=0) { - socket_closesocket(server->udp_listen_s->fd); - server->udp_listen_s->fd = -1; - } + if (server->udp_listen_s->fd >= 0) { + socket_closesocket(server->udp_listen_s->fd); + server->udp_listen_s->fd = -1; + } - if (!(server->udp_listen_s)) { - return create_server_socket(server,1); - } + if (!(server->udp_listen_s)) { + return create_server_socket(server, 1); + } - ioa_socket_raw udp_listen_fd = socket(server->addr.ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL); - if (udp_listen_fd < 0) { - perror("socket"); - FUNCEND; - return -1; - } + ioa_socket_raw udp_listen_fd = + socket(server->addr.ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL); + if (udp_listen_fd < 0) { + perror("socket"); + FUNCEND; + return -1; + } - server->udp_listen_s->fd = udp_listen_fd; + server->udp_listen_s->fd = udp_listen_fd; - /* some UDP sessions may fail due to the race condition here */ + /* some UDP sessions may fail due to the race condition here */ - set_socket_options(server->udp_listen_s); + set_socket_options(server->udp_listen_s); - set_sock_buf_size(udp_listen_fd, UR_SERVER_SOCK_BUF_SIZE); + set_sock_buf_size(udp_listen_fd, UR_SERVER_SOCK_BUF_SIZE); - if (sock_bind_to_device(udp_listen_fd, (unsigned char*) server->ifname) < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "Cannot bind listener socket to device %s\n", - server->ifname); - } + if (sock_bind_to_device(udp_listen_fd, (unsigned char *)server->ifname) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Cannot bind listener socket to device %s\n", server->ifname); + } - if(addr_bind(udp_listen_fd,&server->addr,1,1,UDP_SOCKET)<0) { - perror("Cannot bind local socket to addr"); - char saddr[129]; - addr_to_string(&server->addr,(uint8_t*)saddr); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind listener socket to addr %s\n",saddr); - return -1; - } + if (addr_bind(udp_listen_fd, &server->addr, 1, 1, UDP_SOCKET) < 0) { + perror("Cannot bind local socket to addr"); + char saddr[129]; + addr_to_string(&server->addr, (uint8_t *)saddr); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Cannot bind listener socket to addr %s\n", saddr); + return -1; + } - server->udp_listen_ev = event_new(server->e->event_base, udp_listen_fd, - EV_READ | EV_PERSIST, udp_server_input_handler, - server); + server->udp_listen_ev = + event_new(server->e->event_base, udp_listen_fd, EV_READ | EV_PERSIST, udp_server_input_handler, server); - event_add(server->udp_listen_ev, NULL ); - } + event_add(server->udp_listen_ev, NULL); + } - if (!turn_params.no_udp && !turn_params.no_dtls) - addr_debug_print(server->verbose, &server->addr, - "DTLS/UDP listener opened on "); - else if (!turn_params.no_dtls) - addr_debug_print(server->verbose, &server->addr, - "DTLS listener opened on "); - else if (!turn_params.no_udp) - addr_debug_print(server->verbose, &server->addr, - "UDP listener opened on "); + if (!turn_params.no_udp && !turn_params.no_dtls) + addr_debug_print(server->verbose, &server->addr, "DTLS/UDP listener opened on "); + else if (!turn_params.no_dtls) + addr_debug_print(server->verbose, &server->addr, "DTLS listener opened on "); + else if (!turn_params.no_udp) + addr_debug_print(server->verbose, &server->addr, "UDP listener opened on "); - FUNCEND; + FUNCEND; - return 0; + return 0; } #if defined(REQUEST_CLIENT_CERT) -static int dtls_verify_callback (int ok, X509_STORE_CTX *ctx) { +static int dtls_verify_callback(int ok, X509_STORE_CTX *ctx) { /* This function should ask the user * if he trusts the received certificate. * Here we always trust. */ - if(ok && ctx) return 1; + if (ok && ctx) + return 1; return -1; } #endif -static int init_server(dtls_listener_relay_server_type* server, - const char* ifname, - const char *local_address, - int port, - int verbose, - ioa_engine_handle e, - turn_turnserver *ts, - int report_creation, - ioa_engine_new_connection_event_handler send_socket) { +static int init_server(dtls_listener_relay_server_type *server, const char *ifname, const char *local_address, int port, + int verbose, ioa_engine_handle e, turn_turnserver *ts, int report_creation, + ioa_engine_new_connection_event_handler send_socket) { - if(!server) return -1; + if (!server) + return -1; server->ts = ts; server->connect_cb = send_socket; - if(ifname) STRCPY(server->ifname,ifname); + if (ifname) + STRCPY(server->ifname, ifname); - if(make_ioa_addr((const uint8_t*)local_address, port, &server->addr)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot create a DTLS/UDP listener for address: %s\n",local_address); - return -1; + if (make_ioa_addr((const uint8_t *)local_address, port, &server->addr) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot create a DTLS/UDP listener for address: %s\n", local_address); + return -1; } server->slen0 = get_ioa_addr_len(&(server->addr)); - server->verbose=verbose; - + server->verbose = verbose; + server->e = e; return create_server_socket(server, report_creation); } -static int clean_server(dtls_listener_relay_server_type* server) { - if(server) { - EVENT_DEL(server->udp_listen_ev); - close_ioa_socket(server->udp_listen_s); - server->udp_listen_s = NULL; +static int clean_server(dtls_listener_relay_server_type *server) { + if (server) { + EVENT_DEL(server->udp_listen_ev); + close_ioa_socket(server->udp_listen_s); + server->udp_listen_s = NULL; } return 0; } @@ -977,41 +930,32 @@ void setup_dtls_callbacks(SSL_CTX *ctx) { } #endif -dtls_listener_relay_server_type* create_dtls_listener_server(const char* ifname, - const char *local_address, - int port, - int verbose, - ioa_engine_handle e, - turn_turnserver *ts, - int report_creation, - ioa_engine_new_connection_event_handler send_socket) { - - dtls_listener_relay_server_type* server=(dtls_listener_relay_server_type*) - allocate_super_memory_engine(e,sizeof(dtls_listener_relay_server_type)); +dtls_listener_relay_server_type *create_dtls_listener_server(const char *ifname, const char *local_address, int port, + int verbose, ioa_engine_handle e, turn_turnserver *ts, + int report_creation, + ioa_engine_new_connection_event_handler send_socket) { - if(init_server(server, - ifname, local_address, port, - verbose, - e, ts, report_creation, send_socket)<0) { + dtls_listener_relay_server_type *server = + (dtls_listener_relay_server_type *)allocate_super_memory_engine(e, sizeof(dtls_listener_relay_server_type)); + + if (init_server(server, ifname, local_address, port, verbose, e, ts, report_creation, send_socket) < 0) { return NULL; } else { return server; } } -ioa_engine_handle get_engine(dtls_listener_relay_server_type* server) -{ - if(server) - return server->e; - return NULL; +ioa_engine_handle get_engine(dtls_listener_relay_server_type *server) { + if (server) + return server->e; + return NULL; } //////////// UDP send //////////////// -void udp_send_message(dtls_listener_relay_server_type *server, ioa_network_buffer_handle nbh, ioa_addr *dest) -{ - if(server && dest && nbh && (server->udp_listen_s)) - udp_send(server->udp_listen_s, dest, (char*)ioa_network_buffer_data(nbh), (int)ioa_network_buffer_get_size(nbh)); +void udp_send_message(dtls_listener_relay_server_type *server, ioa_network_buffer_handle nbh, ioa_addr *dest) { + if (server && dest && nbh && (server->udp_listen_s)) + udp_send(server->udp_listen_s, dest, (char *)ioa_network_buffer_data(nbh), (int)ioa_network_buffer_get_size(nbh)); } ////////////////////////////////////////////////////////////////// diff --git a/src/apps/relay/dtls_listener.h b/src/apps/relay/dtls_listener.h index 5ca4ec9..8dc04d2 100644 --- a/src/apps/relay/dtls_listener.h +++ b/src/apps/relay/dtls_listener.h @@ -54,18 +54,14 @@ typedef struct dtls_listener_relay_server_info dtls_listener_relay_server_type; void setup_dtls_callbacks(SSL_CTX *ctx); #endif -dtls_listener_relay_server_type* create_dtls_listener_server(const char* ifname, - const char *local_address, - int port, - int verbose, - ioa_engine_handle e, - turn_turnserver *ts, - int report_creation, - ioa_engine_new_connection_event_handler send_socket); +dtls_listener_relay_server_type *create_dtls_listener_server(const char *ifname, const char *local_address, int port, + int verbose, ioa_engine_handle e, turn_turnserver *ts, + int report_creation, + ioa_engine_new_connection_event_handler send_socket); void udp_send_message(dtls_listener_relay_server_type *server, ioa_network_buffer_handle nbh, ioa_addr *dest); -ioa_engine_handle get_engine(dtls_listener_relay_server_type* server); +ioa_engine_handle get_engine(dtls_listener_relay_server_type *server); /////////////////////////////////////////// diff --git a/src/apps/relay/http_server.c b/src/apps/relay/http_server.c index d82b439..2ba9f21 100644 --- a/src/apps/relay/http_server.c +++ b/src/apps/relay/http_server.c @@ -40,344 +40,341 @@ ////////////////////////////////////// struct headers_list { - size_t n; - char **keys; - char **values; + size_t n; + char **keys; + char **values; }; struct http_headers { - struct evkeyvalq *uri_headers; - struct headers_list *post_headers; + struct evkeyvalq *uri_headers; + struct headers_list *post_headers; }; ////////////////////////////////////// -static void write_http_echo(ioa_socket_handle s) -{ - if(s && !ioa_socket_tobeclosed(s)) { - SOCKET_APP_TYPE sat = get_ioa_socket_app_type(s); - if((sat == HTTP_CLIENT_SOCKET) || (sat == HTTPS_CLIENT_SOCKET)) { - ioa_network_buffer_handle nbh_http = ioa_network_buffer_allocate(s->e); - size_t len_http = ioa_network_buffer_get_size(nbh_http); - uint8_t *data = ioa_network_buffer_data(nbh_http); - char data_http[1025]; - char content_http[1025]; - const char* title = "TURN Server"; - snprintf(content_http,sizeof(content_http)-1,"\r\n\r\n \r\n %s\r\n \r\n \r\n %s
use https connection for the admin session\r\n \r\n\r\n",title,title); - snprintf(data_http,sizeof(data_http)-1,"HTTP/1.0 200 OK\r\nServer: %s\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: %d\r\n\r\n%.906s",TURN_SOFTWARE,(int)strlen(content_http),content_http); - len_http = strlen(data_http); - memcpy(data,data_http,len_http); - ioa_network_buffer_set_size(nbh_http,len_http); - send_data_from_ioa_socket_nbh(s, NULL, nbh_http, TTL_IGNORE, TOS_IGNORE,NULL); - } - } +static void write_http_echo(ioa_socket_handle s) { + if (s && !ioa_socket_tobeclosed(s)) { + SOCKET_APP_TYPE sat = get_ioa_socket_app_type(s); + if ((sat == HTTP_CLIENT_SOCKET) || (sat == HTTPS_CLIENT_SOCKET)) { + ioa_network_buffer_handle nbh_http = ioa_network_buffer_allocate(s->e); + size_t len_http = ioa_network_buffer_get_size(nbh_http); + uint8_t *data = ioa_network_buffer_data(nbh_http); + char data_http[1025]; + char content_http[1025]; + const char *title = "TURN Server"; + snprintf(content_http, sizeof(content_http) - 1, + "\r\n\r\n \r\n %s\r\n \r\n \r\n " + "%s
use https connection for the admin session\r\n \r\n\r\n", + title, title); + snprintf( + data_http, sizeof(data_http) - 1, + "HTTP/1.0 200 OK\r\nServer: %s\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: %d\r\n\r\n%.906s", + TURN_SOFTWARE, (int)strlen(content_http), content_http); + len_http = strlen(data_http); + memcpy(data, data_http, len_http); + ioa_network_buffer_set_size(nbh_http, len_http); + send_data_from_ioa_socket_nbh(s, NULL, nbh_http, TTL_IGNORE, TOS_IGNORE, NULL); + } + } } -void handle_http_echo(ioa_socket_handle s) { - write_http_echo(s); -} +void handle_http_echo(ioa_socket_handle s) { write_http_echo(s); } -const char* get_http_date_header(void) -{ - static char buffer_date[256]; - static char buffer_header[1025]; - static const char* wds[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; - static const char* mons[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; +const char *get_http_date_header(void) { + static char buffer_date[256]; + static char buffer_header[1025]; + static const char *wds[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + static const char *mons[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - time_t now = time(NULL); - struct tm *gmtm = gmtime(&now); + time_t now = time(NULL); + struct tm *gmtm = gmtime(&now); - buffer_header[0]=0; - buffer_date[0]=0; - if(gmtm) { - snprintf(buffer_date,sizeof(buffer_date)-1,"%s, %d %s %d %d:%d:%d GMT",wds[gmtm->tm_wday], gmtm->tm_mday, mons[gmtm->tm_mon], gmtm->tm_year+1900, gmtm->tm_hour, gmtm->tm_min, gmtm->tm_sec); - buffer_date[sizeof(buffer_date)-1]=0; - snprintf(buffer_header,sizeof(buffer_header)-1,"Date: %s\r\n",buffer_date); - buffer_header[sizeof(buffer_header)-1]=0; - } + buffer_header[0] = 0; + buffer_date[0] = 0; + if (gmtm) { + snprintf(buffer_date, sizeof(buffer_date) - 1, "%s, %d %s %d %d:%d:%d GMT", wds[gmtm->tm_wday], gmtm->tm_mday, + mons[gmtm->tm_mon], gmtm->tm_year + 1900, gmtm->tm_hour, gmtm->tm_min, gmtm->tm_sec); + buffer_date[sizeof(buffer_date) - 1] = 0; + snprintf(buffer_header, sizeof(buffer_header) - 1, "Date: %s\r\n", buffer_date); + buffer_header[sizeof(buffer_header) - 1] = 0; + } - return buffer_header; + return buffer_header; } /////////////////////////////////////////////// -static struct headers_list * post_parse(char *data, size_t data_len) -{ - while((*data=='\r')||(*data=='\n')) { ++data; --data_len; } - if (data_len) { - char *post_data = (char*)calloc(data_len + 1, sizeof(char)); - if (post_data != NULL) { - memcpy(post_data, data, data_len); - char *fmarker = NULL; - char *fsplit = strtok_r(post_data, "&", &fmarker); - struct headers_list *list = (struct headers_list*)calloc(sizeof(struct headers_list), 1); - while (fsplit != NULL) { - char *vmarker = NULL; - char *key = strtok_r(fsplit, "=", &vmarker); - if (key == NULL) - break; - else { - char *value = strtok_r(NULL, "=", &vmarker); - char empty[1]; - empty[0]=0; - value = value ? value : empty; - value = evhttp_decode_uri(value); - char *p = value; - while (*p) { - if (*p == '+') - *p = ' '; - p++; - } - list->keys = (char**)realloc(list->keys,sizeof(char*)*(list->n+1)); - list->keys[list->n] = strdup(key); - list->values = (char**)realloc(list->values,sizeof(char*)*(list->n+1)); - list->values[list->n] = value; - ++(list->n); - fsplit = strtok_r(NULL, "&", &fmarker); - } - } - free(post_data); - return list; - } - } - return NULL; +static struct headers_list *post_parse(char *data, size_t data_len) { + while ((*data == '\r') || (*data == '\n')) { + ++data; + --data_len; + } + if (data_len) { + char *post_data = (char *)calloc(data_len + 1, sizeof(char)); + if (post_data != NULL) { + memcpy(post_data, data, data_len); + char *fmarker = NULL; + char *fsplit = strtok_r(post_data, "&", &fmarker); + struct headers_list *list = (struct headers_list *)calloc(sizeof(struct headers_list), 1); + while (fsplit != NULL) { + char *vmarker = NULL; + char *key = strtok_r(fsplit, "=", &vmarker); + if (key == NULL) + break; + else { + char *value = strtok_r(NULL, "=", &vmarker); + char empty[1]; + empty[0] = 0; + value = value ? value : empty; + value = evhttp_decode_uri(value); + char *p = value; + while (*p) { + if (*p == '+') + *p = ' '; + p++; + } + list->keys = (char **)realloc(list->keys, sizeof(char *) * (list->n + 1)); + list->keys[list->n] = strdup(key); + list->values = (char **)realloc(list->values, sizeof(char *) * (list->n + 1)); + list->values[list->n] = value; + ++(list->n); + fsplit = strtok_r(NULL, "&", &fmarker); + } + } + free(post_data); + return list; + } + } + return NULL; } -static struct http_request* parse_http_request_1(struct http_request* ret, char* request, int parse_post) -{ +static struct http_request *parse_http_request_1(struct http_request *ret, char *request, int parse_post) { - if(ret && request) { + if (ret && request) { - char* s = strstr(request," HTTP/"); - if(!s) { - free(ret); - ret = NULL; - } else { - *s = 0; + char *s = strstr(request, " HTTP/"); + if (!s) { + free(ret); + ret = NULL; + } else { + *s = 0; - struct evhttp_uri *uri = evhttp_uri_parse(request); - if(!uri) { - free(ret); - ret = NULL; - } else { + struct evhttp_uri *uri = evhttp_uri_parse(request); + if (!uri) { + free(ret); + ret = NULL; + } else { - const char *query = evhttp_uri_get_query(uri); - if(query) { - struct evkeyvalq* kv = (struct evkeyvalq*)calloc(sizeof(struct evkeyvalq), 1); - if(evhttp_parse_query_str(query, kv)<0) { - free(ret); - ret = NULL; - } else { - ret->headers = (struct http_headers*)calloc(sizeof(struct http_headers), 1); - ret->headers->uri_headers = kv; - } - } + const char *query = evhttp_uri_get_query(uri); + if (query) { + struct evkeyvalq *kv = (struct evkeyvalq *)calloc(sizeof(struct evkeyvalq), 1); + if (evhttp_parse_query_str(query, kv) < 0) { + free(ret); + ret = NULL; + } else { + ret->headers = (struct http_headers *)calloc(sizeof(struct http_headers), 1); + ret->headers->uri_headers = kv; + } + } - const char *path = evhttp_uri_get_path(uri); - if(path && ret) - ret->path = strdup(path); + const char *path = evhttp_uri_get_path(uri); + if (path && ret) + ret->path = strdup(path); - evhttp_uri_free(uri); + evhttp_uri_free(uri); - if(parse_post && ret) { - char *body = strstr(s+1,"\r\n\r\n"); - if(body && body[0]) { - if(!ret->headers) { - ret->headers = (struct http_headers*)calloc(sizeof(struct http_headers), 1); - } - ret->headers->post_headers = post_parse(body,strlen(body)); - } - } - } + if (parse_post && ret) { + char *body = strstr(s + 1, "\r\n\r\n"); + if (body && body[0]) { + if (!ret->headers) { + ret->headers = (struct http_headers *)calloc(sizeof(struct http_headers), 1); + } + ret->headers->post_headers = post_parse(body, strlen(body)); + } + } + } - *s = ' '; - } - } + *s = ' '; + } + } - return ret; + return ret; } -struct http_request* parse_http_request(char* request) { +struct http_request *parse_http_request(char *request) { - struct http_request* ret = NULL; + struct http_request *ret = NULL; - if(request) { + if (request) { - ret = (struct http_request*)calloc(sizeof(struct http_request), 1); + ret = (struct http_request *)calloc(sizeof(struct http_request), 1); - if(strstr(request,"GET ") == request) { - ret->rtype = HRT_GET; - ret = parse_http_request_1(ret,request+4,0); - } else if(strstr(request,"HEAD ") == request) { - ret->rtype = HRT_HEAD; - ret = parse_http_request_1(ret,request+5,0); - } else if(strstr(request,"POST ") == request) { - ret->rtype = HRT_POST; - ret = parse_http_request_1(ret,request+5,1); - } else if(strstr(request,"PUT ") == request) { - ret->rtype = HRT_PUT; - ret = parse_http_request_1(ret,request+4,1); - } else if(strstr(request,"DELETE ") == request) { - ret->rtype = HRT_DELETE; - ret = parse_http_request_1(ret,request+7,1); - } else { - free(ret); - ret = NULL; - } - } + if (strstr(request, "GET ") == request) { + ret->rtype = HRT_GET; + ret = parse_http_request_1(ret, request + 4, 0); + } else if (strstr(request, "HEAD ") == request) { + ret->rtype = HRT_HEAD; + ret = parse_http_request_1(ret, request + 5, 0); + } else if (strstr(request, "POST ") == request) { + ret->rtype = HRT_POST; + ret = parse_http_request_1(ret, request + 5, 1); + } else if (strstr(request, "PUT ") == request) { + ret->rtype = HRT_PUT; + ret = parse_http_request_1(ret, request + 4, 1); + } else if (strstr(request, "DELETE ") == request) { + ret->rtype = HRT_DELETE; + ret = parse_http_request_1(ret, request + 7, 1); + } else { + free(ret); + ret = NULL; + } + } - return ret; + return ret; } -static const char * get_headers_list_value(struct headers_list *h, const char* key) { - const char* ret = NULL; - if(h && h->keys && h->values && key && key[0]) { - size_t i = 0; - for(i=0;in;++i) { - if(h->keys[i] && !strcmp(key,h->keys[i]) && h->values[i]) { - ret = h->values[i]; - break; - } - } - } - return ret; +static const char *get_headers_list_value(struct headers_list *h, const char *key) { + const char *ret = NULL; + if (h && h->keys && h->values && key && key[0]) { + size_t i = 0; + for (i = 0; i < h->n; ++i) { + if (h->keys[i] && !strcmp(key, h->keys[i]) && h->values[i]) { + ret = h->values[i]; + break; + } + } + } + return ret; } static void free_headers_list(struct headers_list *h) { - if(h) { - if(h->keys) { - size_t i = 0; - for(i=0;in;++i) { - if(h->keys[i]) { - free(h->keys[i]); - h->keys[i]=NULL; - } - } - free(h->keys); - h->keys = NULL; - } - if(h->values) { - size_t i = 0; - for(i=0;in;++i) { - if(h->values[i]) { - free(h->values[i]); - h->values[i]=NULL; - } - } - free(h->values); - h->values = NULL; - } - h->n = 0; - free(h); - } + if (h) { + if (h->keys) { + size_t i = 0; + for (i = 0; i < h->n; ++i) { + if (h->keys[i]) { + free(h->keys[i]); + h->keys[i] = NULL; + } + } + free(h->keys); + h->keys = NULL; + } + if (h->values) { + size_t i = 0; + for (i = 0; i < h->n; ++i) { + if (h->values[i]) { + free(h->values[i]); + h->values[i] = NULL; + } + } + free(h->values); + h->values = NULL; + } + h->n = 0; + free(h); + } } -const char *get_http_header_value(const struct http_request *request, const char* key, const char* default_value) { - const char *ret = NULL; - if(key && key[0] && request && request->headers) { - if(request->headers->uri_headers) { - ret = evhttp_find_header(request->headers->uri_headers,key); - } - if(!ret && request->headers->post_headers) { - ret = get_headers_list_value(request->headers->post_headers,key); - } - } - if(!ret) { - ret = default_value; - } - return ret; +const char *get_http_header_value(const struct http_request *request, const char *key, const char *default_value) { + const char *ret = NULL; + if (key && key[0] && request && request->headers) { + if (request->headers->uri_headers) { + ret = evhttp_find_header(request->headers->uri_headers, key); + } + if (!ret && request->headers->post_headers) { + ret = get_headers_list_value(request->headers->post_headers, key); + } + } + if (!ret) { + ret = default_value; + } + return ret; } void free_http_request(struct http_request *request) { - if(request) { - if(request->path) { - free(request->path); - request->path = NULL; - } - if(request->headers) { - if(request->headers->uri_headers) { - evhttp_clear_headers(request->headers->uri_headers); - free(request->headers->uri_headers); - request->headers->uri_headers = NULL; - } - if(request->headers->post_headers) { - free_headers_list(request->headers->post_headers); - request->headers->post_headers = NULL; - } - free(request->headers); - request->headers = NULL; - } - free(request); - } + if (request) { + if (request->path) { + free(request->path); + request->path = NULL; + } + if (request->headers) { + if (request->headers->uri_headers) { + evhttp_clear_headers(request->headers->uri_headers); + free(request->headers->uri_headers); + request->headers->uri_headers = NULL; + } + if (request->headers->post_headers) { + free_headers_list(request->headers->post_headers); + request->headers->post_headers = NULL; + } + free(request->headers); + request->headers = NULL; + } + free(request); + } } //////////////////////////////////////////// struct str_buffer { - size_t capacity; - size_t sz; - char* buffer; + size_t capacity; + size_t sz; + char *buffer; }; -struct str_buffer* str_buffer_new(void) -{ - struct str_buffer* ret = (struct str_buffer*)calloc(sizeof(struct str_buffer), 1); +struct str_buffer *str_buffer_new(void) { + struct str_buffer *ret = (struct str_buffer *)calloc(sizeof(struct str_buffer), 1); - ret->buffer = (char*)malloc(1); - ret->buffer[0] = 0; - ret->capacity = 1; - return ret; + ret->buffer = (char *)malloc(1); + ret->buffer[0] = 0; + ret->capacity = 1; + return ret; } -void str_buffer_append(struct str_buffer* sb, const char* str) -{ - if(sb && str && str[0]) { - size_t len = strlen(str); - while(sb->sz + len + 1 > sb->capacity) { - sb->capacity += len + 1024; - sb->buffer = (char*)realloc(sb->buffer,sb->capacity); - } - memcpy(sb->buffer+sb->sz,str,len+1); - sb->sz += len; - } +void str_buffer_append(struct str_buffer *sb, const char *str) { + if (sb && str && str[0]) { + size_t len = strlen(str); + while (sb->sz + len + 1 > sb->capacity) { + sb->capacity += len + 1024; + sb->buffer = (char *)realloc(sb->buffer, sb->capacity); + } + memcpy(sb->buffer + sb->sz, str, len + 1); + sb->sz += len; + } } -void str_buffer_append_sz(struct str_buffer* sb, size_t sz) -{ - char ssz[129]; - snprintf(ssz,sizeof(ssz)-1,"%lu",(unsigned long)sz); - str_buffer_append(sb,ssz); +void str_buffer_append_sz(struct str_buffer *sb, size_t sz) { + char ssz[129]; + snprintf(ssz, sizeof(ssz) - 1, "%lu", (unsigned long)sz); + str_buffer_append(sb, ssz); } -void str_buffer_append_sid(struct str_buffer* sb, turnsession_id sid) -{ - char ssz[129]; - snprintf(ssz,sizeof(ssz)-1,"%018llu",(unsigned long long)sid); - str_buffer_append(sb,ssz); +void str_buffer_append_sid(struct str_buffer *sb, turnsession_id sid) { + char ssz[129]; + snprintf(ssz, sizeof(ssz) - 1, "%018llu", (unsigned long long)sid); + str_buffer_append(sb, ssz); } -const char* str_buffer_get_str(const struct str_buffer *sb) -{ - if(sb) { - return sb->buffer; - } - return NULL; +const char *str_buffer_get_str(const struct str_buffer *sb) { + if (sb) { + return sb->buffer; + } + return NULL; } -size_t str_buffer_get_str_len(const struct str_buffer *sb) -{ - if(sb) { - return sb->sz; - } - return 0; +size_t str_buffer_get_str_len(const struct str_buffer *sb) { + if (sb) { + return sb->sz; + } + return 0; } -void str_buffer_free(struct str_buffer *sb) -{ - if(sb) { - free(sb->buffer); - free(sb); - } +void str_buffer_free(struct str_buffer *sb) { + if (sb) { + free(sb->buffer); + free(sb); + } } /////////////////////////////////////////////// diff --git a/src/apps/relay/http_server.h b/src/apps/relay/http_server.h index 2acda15..a4a11c1 100644 --- a/src/apps/relay/http_server.h +++ b/src/apps/relay/http_server.h @@ -31,12 +31,12 @@ #ifndef __TURN_HTTP_SERVER__ #define __TURN_HTTP_SERVER__ -#include "ns_turn_utils.h" -#include "ns_turn_server.h" #include "apputils.h" +#include "ns_turn_server.h" +#include "ns_turn_utils.h" -#include #include +#include #ifdef __cplusplus extern "C" { @@ -44,40 +44,33 @@ extern "C" { ///////// HTTP REQUEST ////////// -enum _HTTP_REQUEST_TYPE { - HRT_UNKNOWN=0, - HRT_GET, - HRT_HEAD, - HRT_POST, - HRT_PUT, - HRT_DELETE -}; +enum _HTTP_REQUEST_TYPE { HRT_UNKNOWN = 0, HRT_GET, HRT_HEAD, HRT_POST, HRT_PUT, HRT_DELETE }; typedef enum _HTTP_REQUEST_TYPE HTTP_REQUEST_TYPE; struct http_headers; struct http_request { - HTTP_REQUEST_TYPE rtype; - char *path; - struct http_headers *headers; + HTTP_REQUEST_TYPE rtype; + char *path; + struct http_headers *headers; }; -struct http_request* parse_http_request(char* request); -const char *get_http_header_value(const struct http_request *request, const char* key, const char* def); +struct http_request *parse_http_request(char *request); +const char *get_http_header_value(const struct http_request *request, const char *key, const char *def); void free_http_request(struct http_request *request); -const char* get_http_date_header(void); +const char *get_http_date_header(void); //////////////////////////////////////////// struct str_buffer; -struct str_buffer* str_buffer_new(void); -void str_buffer_append(struct str_buffer* sb, const char* str); -void str_buffer_append_sz(struct str_buffer* sb, size_t sz); -void str_buffer_append_sid(struct str_buffer* sb, turnsession_id sid); -const char* str_buffer_get_str(const struct str_buffer *sb); +struct str_buffer *str_buffer_new(void); +void str_buffer_append(struct str_buffer *sb, const char *str); +void str_buffer_append_sz(struct str_buffer *sb, size_t sz); +void str_buffer_append_sid(struct str_buffer *sb, turnsession_id sid); +const char *str_buffer_get_str(const struct str_buffer *sb); size_t str_buffer_get_str_len(const struct str_buffer *sb); void str_buffer_free(struct str_buffer *sb); @@ -93,4 +86,3 @@ void handle_http_echo(ioa_socket_handle s); #endif /// __TURN_HTTP_SERVER__/// - diff --git a/src/apps/relay/libtelnet.c b/src/apps/relay/libtelnet.c index f2e65a0..9caccf8 100644 --- a/src/apps/relay/libtelnet.c +++ b/src/apps/relay/libtelnet.c @@ -14,105 +14,105 @@ #ifdef HAVE_CONFIG_H #include #endif -#include -#include -#include #include #include +#include +#include +#include /* Win32 compatibility */ #if defined(WINDOWS) -# define vsnprintf _vsnprintf -# define __func__ __FUNCTION__ -# define ZLIB_WINAPI 1 -# if defined(_MSC_VER) +#define vsnprintf _vsnprintf +#define __func__ __FUNCTION__ +#define ZLIB_WINAPI 1 +#if defined(_MSC_VER) /* va_copy() is directly supported starting in Visual Studio 2013 * https://msdn.microsoft.com/en-us/library/kb57fad8(v=vs.110).aspx * https://msdn.microsoft.com/en-us/library/kb57fad8(v=vs.120).aspx */ -# if _MSC_VER <= 1700 -# define va_copy(dest, src) (dest = src) -# endif -# endif +#if _MSC_VER <= 1700 +#define va_copy(dest, src) (dest = src) +#endif +#endif #endif #if defined(HAVE_ZLIB) -# include +#include #endif #include "libtelnet.h" /* inlinable functions */ #if defined(__GNUC__) -# define INLINE __inline__ +#define INLINE __inline__ #elif __STDC_VERSION__ >= 199901L -# define INLINE inline +#define INLINE inline #else -# define INLINE +#define INLINE #endif /* helper for Q-method option tracking */ #define Q_US(q) ((q).state & 0x0F) #define Q_HIM(q) (((q).state & 0xF0) >> 4) -#define Q_MAKE(us,him) ((us) | ((him) << 4)) +#define Q_MAKE(us, him) ((us) | ((him) << 4)) /* helper for the negotiation routines */ -#define NEGOTIATE_EVENT(telnet,cmd,opt) \ - ev.type = (cmd); \ - ev.neg.telopt = (opt); \ - (telnet)->eh((telnet), &ev, (telnet)->ud); +#define NEGOTIATE_EVENT(telnet, cmd, opt) \ + ev.type = (cmd); \ + ev.neg.telopt = (opt); \ + (telnet)->eh((telnet), &ev, (telnet)->ud); /* telnet state codes */ enum telnet_state_t { - TELNET_STATE_DATA = 0, - TELNET_STATE_EOL, - TELNET_STATE_IAC, - TELNET_STATE_WILL, - TELNET_STATE_WONT, - TELNET_STATE_DO, - TELNET_STATE_DONT, - TELNET_STATE_SB, - TELNET_STATE_SB_DATA, - TELNET_STATE_SB_DATA_IAC + TELNET_STATE_DATA = 0, + TELNET_STATE_EOL, + TELNET_STATE_IAC, + TELNET_STATE_WILL, + TELNET_STATE_WONT, + TELNET_STATE_DO, + TELNET_STATE_DONT, + TELNET_STATE_SB, + TELNET_STATE_SB_DATA, + TELNET_STATE_SB_DATA_IAC }; typedef enum telnet_state_t telnet_state_t; /* telnet state tracker */ struct telnet_t { - /* user data */ - void *ud; - /* telopt support table */ - const telnet_telopt_t *telopts; - /* event handler */ - telnet_event_handler_t eh; + /* user data */ + void *ud; + /* telopt support table */ + const telnet_telopt_t *telopts; + /* event handler */ + telnet_event_handler_t eh; #if defined(HAVE_ZLIB) - /* zlib (mccp2) compression */ - z_stream *z; + /* zlib (mccp2) compression */ + z_stream *z; #endif - /* RFC1143 option negotiation states */ - struct telnet_rfc1143_t *q; - /* sub-request buffer */ - char *buffer; - /* current size of the buffer */ - size_t buffer_size; - /* current buffer write position (also length of buffer data) */ - size_t buffer_pos; - /* current state */ - enum telnet_state_t state; - /* option flags */ - unsigned char flags; - /* current subnegotiation telopt */ - unsigned char sb_telopt; - /* length of RFC1143 queue */ - unsigned int q_size; - /* number of entries in RFC1143 queue */ - unsigned int q_cnt; + /* RFC1143 option negotiation states */ + struct telnet_rfc1143_t *q; + /* sub-request buffer */ + char *buffer; + /* current size of the buffer */ + size_t buffer_size; + /* current buffer write position (also length of buffer data) */ + size_t buffer_pos; + /* current state */ + enum telnet_state_t state; + /* option flags */ + unsigned char flags; + /* current subnegotiation telopt */ + unsigned char sb_telopt; + /* length of RFC1143 queue */ + unsigned int q_size; + /* number of entries in RFC1143 queue */ + unsigned int q_cnt; }; /* RFC1143 option negotiation state */ typedef struct telnet_rfc1143_t { - unsigned char telopt; - unsigned char state; + unsigned char telopt; + unsigned char state; } telnet_rfc1143_t; /* RFC1143 state names */ @@ -124,39 +124,39 @@ typedef struct telnet_rfc1143_t { #define Q_WANTYES_OP 5 /* telnet NVT EOL sequences */ -static const char CRLF[] = { '\r', '\n' }; -static const char CRNUL[] = { '\r', '\0' }; +static const char CRLF[] = {'\r', '\n'}; +static const char CRNUL[] = {'\r', '\0'}; /* buffer sizes */ -static const size_t _buffer_sizes[] = { 0, 512, 2048, 8192, 16384, }; -static const size_t _buffer_sizes_count = sizeof(_buffer_sizes) / - sizeof(_buffer_sizes[0]); +static const size_t _buffer_sizes[] = { + 0, 512, 2048, 8192, 16384, +}; +static const size_t _buffer_sizes_count = sizeof(_buffer_sizes) / sizeof(_buffer_sizes[0]); /* RFC1143 option negotiation state table allocation quantum */ #define Q_BUFFER_GROWTH_QUANTUM 4 /* error generation function */ -static telnet_error_t telnet_error(telnet_t *telnet, unsigned line, - const char* func, telnet_error_t err, int fatal, const char *fmt, - ...) { - telnet_event_t ev; - char buffer[512]; - va_list va; +static telnet_error_t telnet_error(telnet_t *telnet, unsigned line, const char *func, telnet_error_t err, int fatal, + const char *fmt, ...) { + telnet_event_t ev; + char buffer[512]; + va_list va; - /* format informational text */ - va_start(va, fmt); - vsnprintf(buffer, sizeof(buffer), fmt, va); - va_end(va); + /* format informational text */ + va_start(va, fmt); + vsnprintf(buffer, sizeof(buffer), fmt, va); + va_end(va); - /* send error event to the user */ - ev.type = fatal ? TELNET_EV_ERROR : TELNET_EV_WARNING; - ev.error.file = __FILE__; - ev.error.func = func; - ev.error.line = line; - ev.error.msg = buffer; - telnet->eh(telnet, &ev, telnet->ud); + /* send error event to the user */ + ev.type = fatal ? TELNET_EV_ERROR : TELNET_EV_WARNING; + ev.error.file = __FILE__; + ev.error.func = func; + ev.error.line = line; + ev.error.msg = buffer; + telnet->eh(telnet, &ev, telnet->ud); - return err; + return err; } #if defined(HAVE_ZLIB) @@ -166,349 +166,333 @@ static telnet_error_t telnet_error(telnet_t *telnet, unsigned line, * failure. */ telnet_error_t _init_zlib(telnet_t *telnet, int deflate, int err_fatal) { - z_stream *z; - int rs; + z_stream *z; + int rs; - /* if compression is already enabled, fail loudly */ - if (telnet->z != 0) - return telnet_error(telnet, __LINE__, __func__, TELNET_EBADVAL, - err_fatal, "cannot initialize compression twice"); + /* if compression is already enabled, fail loudly */ + if (telnet->z != 0) + return telnet_error(telnet, __LINE__, __func__, TELNET_EBADVAL, err_fatal, "cannot initialize compression twice"); - /* allocate zstream box */ - if ((z= (z_stream *)calloc(1, sizeof(z_stream))) == 0) - return telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, err_fatal, - "malloc() failed: %s", strerror(errno)); + /* allocate zstream box */ + if ((z = (z_stream *)calloc(1, sizeof(z_stream))) == 0) + return telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, err_fatal, "malloc() failed: %s", strerror(errno)); - /* initialize */ - if (deflate) { - if ((rs = deflateInit(z, Z_DEFAULT_COMPRESSION)) != Z_OK) { - free(z); - return telnet_error(telnet, __LINE__, __func__, TELNET_ECOMPRESS, - err_fatal, "deflateInit() failed: %s", zError(rs)); - } - telnet->flags |= TELNET_PFLAG_DEFLATE; - } else { - if ((rs = inflateInit(z)) != Z_OK) { - free(z); - return telnet_error(telnet, __LINE__, __func__, TELNET_ECOMPRESS, - err_fatal, "inflateInit() failed: %s", zError(rs)); - } - telnet->flags &= ~TELNET_PFLAG_DEFLATE; - } + /* initialize */ + if (deflate) { + if ((rs = deflateInit(z, Z_DEFAULT_COMPRESSION)) != Z_OK) { + free(z); + return telnet_error(telnet, __LINE__, __func__, TELNET_ECOMPRESS, err_fatal, "deflateInit() failed: %s", + zError(rs)); + } + telnet->flags |= TELNET_PFLAG_DEFLATE; + } else { + if ((rs = inflateInit(z)) != Z_OK) { + free(z); + return telnet_error(telnet, __LINE__, __func__, TELNET_ECOMPRESS, err_fatal, "inflateInit() failed: %s", + zError(rs)); + } + telnet->flags &= ~TELNET_PFLAG_DEFLATE; + } - telnet->z = z; + telnet->z = z; - return TELNET_EOK; + return TELNET_EOK; } #endif /* defined(HAVE_ZLIB) */ /* push bytes out, compressing them first if need be */ -static void _send(telnet_t *telnet, const char *buffer, - size_t size) { - telnet_event_t ev; +static void _send(telnet_t *telnet, const char *buffer, size_t size) { + telnet_event_t ev; #if defined(HAVE_ZLIB) - /* if we have a deflate (compression) zlib box, use it */ - if (telnet->z != 0 && telnet->flags & TELNET_PFLAG_DEFLATE) { - char deflate_buffer[1024]; - int rs; + /* if we have a deflate (compression) zlib box, use it */ + if (telnet->z != 0 && telnet->flags & TELNET_PFLAG_DEFLATE) { + char deflate_buffer[1024]; + int rs; - /* initialize z state */ - telnet->z->next_in = (unsigned char *)buffer; - telnet->z->avail_in = (unsigned int)size; - telnet->z->next_out = (unsigned char *)deflate_buffer; - telnet->z->avail_out = sizeof(deflate_buffer); + /* initialize z state */ + telnet->z->next_in = (unsigned char *)buffer; + telnet->z->avail_in = (unsigned int)size; + telnet->z->next_out = (unsigned char *)deflate_buffer; + telnet->z->avail_out = sizeof(deflate_buffer); - /* deflate until buffer exhausted and all output is produced */ - while (telnet->z->avail_in > 0 || telnet->z->avail_out == 0) { - /* compress */ - if ((rs = deflate(telnet->z, Z_SYNC_FLUSH)) != Z_OK) { - telnet_error(telnet, __LINE__, __func__, TELNET_ECOMPRESS, 1, - "deflate() failed: %s", zError(rs)); - deflateEnd(telnet->z); - free(telnet->z); - telnet->z = 0; - break; - } + /* deflate until buffer exhausted and all output is produced */ + while (telnet->z->avail_in > 0 || telnet->z->avail_out == 0) { + /* compress */ + if ((rs = deflate(telnet->z, Z_SYNC_FLUSH)) != Z_OK) { + telnet_error(telnet, __LINE__, __func__, TELNET_ECOMPRESS, 1, "deflate() failed: %s", zError(rs)); + deflateEnd(telnet->z); + free(telnet->z); + telnet->z = 0; + break; + } - /* send event */ - ev.type = TELNET_EV_SEND; - ev.data.buffer = deflate_buffer; - ev.data.size = sizeof(deflate_buffer) - telnet->z->avail_out; - telnet->eh(telnet, &ev, telnet->ud); + /* send event */ + ev.type = TELNET_EV_SEND; + ev.data.buffer = deflate_buffer; + ev.data.size = sizeof(deflate_buffer) - telnet->z->avail_out; + telnet->eh(telnet, &ev, telnet->ud); - /* prepare output buffer for next run */ - telnet->z->next_out = (unsigned char *)deflate_buffer; - telnet->z->avail_out = sizeof(deflate_buffer); - } + /* prepare output buffer for next run */ + telnet->z->next_out = (unsigned char *)deflate_buffer; + telnet->z->avail_out = sizeof(deflate_buffer); + } - /* do not continue with remaining code */ - return; - } + /* do not continue with remaining code */ + return; + } #endif /* defined(HAVE_ZLIB) */ - ev.type = TELNET_EV_SEND; - ev.data.buffer = buffer; - ev.data.size = size; - telnet->eh(telnet, &ev, telnet->ud); + ev.type = TELNET_EV_SEND; + ev.data.buffer = buffer; + ev.data.size = size; + telnet->eh(telnet, &ev, telnet->ud); } /* to send bags of unsigned chars */ -#define _sendu(t, d, s) _send((t), (const char*)(d), (s)) +#define _sendu(t, d, s) _send((t), (const char *)(d), (s)) /* check if we support a particular telopt; if us is non-zero, we * check if we (local) supports it, otherwise we check if he (remote) * supports it. return non-zero if supported, zero if not supported. */ -static INLINE int _check_telopt(telnet_t *telnet, unsigned char telopt, - int us) { - int i; +static INLINE int _check_telopt(telnet_t *telnet, unsigned char telopt, int us) { + int i; - /* if we have no telopts table, we obviously don't support it */ - if (telnet->telopts == 0) - return 0; + /* if we have no telopts table, we obviously don't support it */ + if (telnet->telopts == 0) + return 0; - /* loop until found or end marker (us and him both 0) */ - for (i = 0; telnet->telopts[i].telopt != -1; ++i) { - if (telnet->telopts[i].telopt == telopt) { - if (us && telnet->telopts[i].us == TELNET_WILL) - return 1; - else if (!us && telnet->telopts[i].him == TELNET_DO) - return 1; - else - return 0; - } - } + /* loop until found or end marker (us and him both 0) */ + for (i = 0; telnet->telopts[i].telopt != -1; ++i) { + if (telnet->telopts[i].telopt == telopt) { + if (us && telnet->telopts[i].us == TELNET_WILL) + return 1; + else if (!us && telnet->telopts[i].him == TELNET_DO) + return 1; + else + return 0; + } + } - /* not found, so not supported */ - return 0; + /* not found, so not supported */ + return 0; } /* retrieve RFC1143 option state */ -static INLINE telnet_rfc1143_t _get_rfc1143(telnet_t *telnet, - unsigned char telopt) { - telnet_rfc1143_t empty; - unsigned int i; +static INLINE telnet_rfc1143_t _get_rfc1143(telnet_t *telnet, unsigned char telopt) { + telnet_rfc1143_t empty; + unsigned int i; - /* search for entry */ - for (i = 0; i != telnet->q_cnt; ++i) { - if (telnet->q[i].telopt == telopt) { - return telnet->q[i]; - } - } + /* search for entry */ + for (i = 0; i != telnet->q_cnt; ++i) { + if (telnet->q[i].telopt == telopt) { + return telnet->q[i]; + } + } - /* not found, return empty value */ - empty.telopt = telopt; - empty.state = 0; - return empty; + /* not found, return empty value */ + empty.telopt = telopt; + empty.state = 0; + return empty; } /* save RFC1143 option state */ -static INLINE void _set_rfc1143(telnet_t *telnet, unsigned char telopt, - char us, char him) { - telnet_rfc1143_t *qtmp; - unsigned int i; +static INLINE void _set_rfc1143(telnet_t *telnet, unsigned char telopt, char us, char him) { + telnet_rfc1143_t *qtmp; + unsigned int i; - /* search for entry */ - for (i = 0; i != telnet->q_cnt; ++i) { - if (telnet->q[i].telopt == telopt) { - telnet->q[i].state = Q_MAKE(us,him); - if (telopt != TELNET_TELOPT_BINARY) - return; - telnet->flags &= ~(TELNET_FLAG_TRANSMIT_BINARY | - TELNET_FLAG_RECEIVE_BINARY); - if (us == Q_YES) - telnet->flags |= TELNET_FLAG_TRANSMIT_BINARY; - if (him == Q_YES) - telnet->flags |= TELNET_FLAG_RECEIVE_BINARY; - return; - } - } + /* search for entry */ + for (i = 0; i != telnet->q_cnt; ++i) { + if (telnet->q[i].telopt == telopt) { + telnet->q[i].state = Q_MAKE(us, him); + if (telopt != TELNET_TELOPT_BINARY) + return; + telnet->flags &= ~(TELNET_FLAG_TRANSMIT_BINARY | TELNET_FLAG_RECEIVE_BINARY); + if (us == Q_YES) + telnet->flags |= TELNET_FLAG_TRANSMIT_BINARY; + if (him == Q_YES) + telnet->flags |= TELNET_FLAG_RECEIVE_BINARY; + return; + } + } - /* we're going to need to track state for it, so grow the queue - * by 4 (four) elements and put the telopt into it; bail on allocation - * error. we go by four because it seems like a reasonable guess as - * to the number of enabled options for most simple code, and it - * allows for an acceptable number of reallocations for complex code. - */ + /* we're going to need to track state for it, so grow the queue + * by 4 (four) elements and put the telopt into it; bail on allocation + * error. we go by four because it seems like a reasonable guess as + * to the number of enabled options for most simple code, and it + * allows for an acceptable number of reallocations for complex code. + */ - /* Did we reach the end of the table? */ - if (telnet->q_cnt >= telnet->q_size) { - /* Expand the size */ - if ((qtmp = (telnet_rfc1143_t *)realloc(telnet->q, - sizeof(telnet_rfc1143_t) * - (telnet->q_size + Q_BUFFER_GROWTH_QUANTUM))) == 0) { - telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, - "realloc() failed: %s", strerror(errno)); - return; - } - memset(&qtmp[telnet->q_size], 0, sizeof(telnet_rfc1143_t) * - Q_BUFFER_GROWTH_QUANTUM); - telnet->q = qtmp; - telnet->q_size += Q_BUFFER_GROWTH_QUANTUM; - } - /* Add entry to end of table */ - telnet->q[telnet->q_cnt].telopt = telopt; - telnet->q[telnet->q_cnt].state = Q_MAKE(us, him); - ++telnet->q_cnt; + /* Did we reach the end of the table? */ + if (telnet->q_cnt >= telnet->q_size) { + /* Expand the size */ + if ((qtmp = (telnet_rfc1143_t *)realloc(telnet->q, sizeof(telnet_rfc1143_t) * + (telnet->q_size + Q_BUFFER_GROWTH_QUANTUM))) == 0) { + telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "realloc() failed: %s", strerror(errno)); + return; + } + memset(&qtmp[telnet->q_size], 0, sizeof(telnet_rfc1143_t) * Q_BUFFER_GROWTH_QUANTUM); + telnet->q = qtmp; + telnet->q_size += Q_BUFFER_GROWTH_QUANTUM; + } + /* Add entry to end of table */ + telnet->q[telnet->q_cnt].telopt = telopt; + telnet->q[telnet->q_cnt].state = Q_MAKE(us, him); + ++telnet->q_cnt; } /* send negotiation bytes */ -static INLINE void _send_negotiate(telnet_t *telnet, unsigned char cmd, - unsigned char telopt) { - unsigned char bytes[3]; - bytes[0] = TELNET_IAC; - bytes[1] = cmd; - bytes[2] = telopt; - _sendu(telnet, bytes, 3); +static INLINE void _send_negotiate(telnet_t *telnet, unsigned char cmd, unsigned char telopt) { + unsigned char bytes[3]; + bytes[0] = TELNET_IAC; + bytes[1] = cmd; + bytes[2] = telopt; + _sendu(telnet, bytes, 3); } /* negotiation handling magic for RFC1143 */ static void _negotiate(telnet_t *telnet, unsigned char telopt) { - telnet_event_t ev; - telnet_rfc1143_t q; + telnet_event_t ev; + telnet_rfc1143_t q; - /* in PROXY mode, just pass it thru and do nothing */ - if (telnet->flags & TELNET_FLAG_PROXY) { - switch ((int)telnet->state) { - case TELNET_STATE_WILL: - NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt); - break; - case TELNET_STATE_WONT: - NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt); - break; - case TELNET_STATE_DO: - NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt); - break; - case TELNET_STATE_DONT: - NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt); - break; - } - return; - } + /* in PROXY mode, just pass it thru and do nothing */ + if (telnet->flags & TELNET_FLAG_PROXY) { + switch ((int)telnet->state) { + case TELNET_STATE_WILL: + NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt); + break; + case TELNET_STATE_WONT: + NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt); + break; + case TELNET_STATE_DO: + NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt); + break; + case TELNET_STATE_DONT: + NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt); + break; + } + return; + } - /* lookup the current state of the option */ - q = _get_rfc1143(telnet, telopt); + /* lookup the current state of the option */ + q = _get_rfc1143(telnet, telopt); - /* start processing... */ - switch ((int)telnet->state) { - /* request to enable option on remote end or confirm DO */ - case TELNET_STATE_WILL: - switch (Q_HIM(q)) { - case Q_NO: - if (_check_telopt(telnet, telopt, 0)) { - _set_rfc1143(telnet, telopt, Q_US(q), Q_YES); - _send_negotiate(telnet, TELNET_DO, telopt); - NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt); - } else - _send_negotiate(telnet, TELNET_DONT, telopt); - break; - case Q_WANTNO: - _set_rfc1143(telnet, telopt, Q_US(q), Q_NO); - NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt); - telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, - "DONT answered by WILL"); - break; - case Q_WANTNO_OP: - _set_rfc1143(telnet, telopt, Q_US(q), Q_YES); - NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt); - telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, - "DONT answered by WILL"); - break; - case Q_WANTYES: - _set_rfc1143(telnet, telopt, Q_US(q), Q_YES); - NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt); - break; - case Q_WANTYES_OP: - _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTNO); - _send_negotiate(telnet, TELNET_DONT, telopt); - NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt); - break; - } - break; + /* start processing... */ + switch ((int)telnet->state) { + /* request to enable option on remote end or confirm DO */ + case TELNET_STATE_WILL: + switch (Q_HIM(q)) { + case Q_NO: + if (_check_telopt(telnet, telopt, 0)) { + _set_rfc1143(telnet, telopt, Q_US(q), Q_YES); + _send_negotiate(telnet, TELNET_DO, telopt); + NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt); + } else + _send_negotiate(telnet, TELNET_DONT, telopt); + break; + case Q_WANTNO: + _set_rfc1143(telnet, telopt, Q_US(q), Q_NO); + NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt); + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "DONT answered by WILL"); + break; + case Q_WANTNO_OP: + _set_rfc1143(telnet, telopt, Q_US(q), Q_YES); + NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt); + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "DONT answered by WILL"); + break; + case Q_WANTYES: + _set_rfc1143(telnet, telopt, Q_US(q), Q_YES); + NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt); + break; + case Q_WANTYES_OP: + _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTNO); + _send_negotiate(telnet, TELNET_DONT, telopt); + NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt); + break; + } + break; - /* request to disable option on remote end, confirm DONT, reject DO */ - case TELNET_STATE_WONT: - switch (Q_HIM(q)) { - case Q_YES: - _set_rfc1143(telnet, telopt, Q_US(q), Q_NO); - _send_negotiate(telnet, TELNET_DONT, telopt); - NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt); - break; - case Q_WANTNO: - _set_rfc1143(telnet, telopt, Q_US(q), Q_NO); - NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt); - break; - case Q_WANTNO_OP: - _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTYES); - NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt); - break; - case Q_WANTYES: - case Q_WANTYES_OP: - _set_rfc1143(telnet, telopt, Q_US(q), Q_NO); - break; - } - break; + /* request to disable option on remote end, confirm DONT, reject DO */ + case TELNET_STATE_WONT: + switch (Q_HIM(q)) { + case Q_YES: + _set_rfc1143(telnet, telopt, Q_US(q), Q_NO); + _send_negotiate(telnet, TELNET_DONT, telopt); + NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt); + break; + case Q_WANTNO: + _set_rfc1143(telnet, telopt, Q_US(q), Q_NO); + NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt); + break; + case Q_WANTNO_OP: + _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTYES); + NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt); + break; + case Q_WANTYES: + case Q_WANTYES_OP: + _set_rfc1143(telnet, telopt, Q_US(q), Q_NO); + break; + } + break; - /* request to enable option on local end or confirm WILL */ - case TELNET_STATE_DO: - switch (Q_US(q)) { - case Q_NO: - if (_check_telopt(telnet, telopt, 1)) { - _set_rfc1143(telnet, telopt, Q_YES, Q_HIM(q)); - _send_negotiate(telnet, TELNET_WILL, telopt); - NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt); - } else - _send_negotiate(telnet, TELNET_WONT, telopt); - break; - case Q_WANTNO: - _set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q)); - NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt); - telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, - "WONT answered by DO"); - break; - case Q_WANTNO_OP: - _set_rfc1143(telnet, telopt, Q_YES, Q_HIM(q)); - NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt); - telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, - "WONT answered by DO"); - break; - case Q_WANTYES: - _set_rfc1143(telnet, telopt, Q_YES, Q_HIM(q)); - NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt); - break; - case Q_WANTYES_OP: - _set_rfc1143(telnet, telopt, Q_WANTNO, Q_HIM(q)); - _send_negotiate(telnet, TELNET_WONT, telopt); - NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt); - break; - } - break; + /* request to enable option on local end or confirm WILL */ + case TELNET_STATE_DO: + switch (Q_US(q)) { + case Q_NO: + if (_check_telopt(telnet, telopt, 1)) { + _set_rfc1143(telnet, telopt, Q_YES, Q_HIM(q)); + _send_negotiate(telnet, TELNET_WILL, telopt); + NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt); + } else + _send_negotiate(telnet, TELNET_WONT, telopt); + break; + case Q_WANTNO: + _set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q)); + NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt); + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "WONT answered by DO"); + break; + case Q_WANTNO_OP: + _set_rfc1143(telnet, telopt, Q_YES, Q_HIM(q)); + NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt); + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "WONT answered by DO"); + break; + case Q_WANTYES: + _set_rfc1143(telnet, telopt, Q_YES, Q_HIM(q)); + NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt); + break; + case Q_WANTYES_OP: + _set_rfc1143(telnet, telopt, Q_WANTNO, Q_HIM(q)); + _send_negotiate(telnet, TELNET_WONT, telopt); + NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt); + break; + } + break; - /* request to disable option on local end, confirm WONT, reject WILL */ - case TELNET_STATE_DONT: - switch (Q_US(q)) { - case Q_YES: - _set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q)); - _send_negotiate(telnet, TELNET_WONT, telopt); - NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt); - break; - case Q_WANTNO: - _set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q)); - NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt); - break; - case Q_WANTNO_OP: - _set_rfc1143(telnet, telopt, Q_WANTYES, Q_HIM(q)); - _send_negotiate(telnet, TELNET_WILL, telopt); - NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt); - break; - case Q_WANTYES: - case Q_WANTYES_OP: - _set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q)); - break; - } - break; - } + /* request to disable option on local end, confirm WONT, reject WILL */ + case TELNET_STATE_DONT: + switch (Q_US(q)) { + case Q_YES: + _set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q)); + _send_negotiate(telnet, TELNET_WONT, telopt); + NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt); + break; + case Q_WANTNO: + _set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q)); + NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt); + break; + case Q_WANTNO_OP: + _set_rfc1143(telnet, telopt, Q_WANTYES, Q_HIM(q)); + _send_negotiate(telnet, TELNET_WILL, telopt); + NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt); + break; + case Q_WANTYES: + case Q_WANTYES_OP: + _set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q)); + break; + } + break; + } } /* process an ENVIRON/NEW-ENVIRON subnegotiation buffer @@ -523,1145 +507,1097 @@ static void _negotiate(telnet_t *telnet, unsigned char telopt) { * value strings are NUL-terminated, all while fitting inside * of the original buffer. */ -static int _environ_telnet(telnet_t *telnet, unsigned char type, - char* buffer, size_t size) { - telnet_event_t ev; - struct telnet_environ_t *values = 0; - char *c, *last, *out; - size_t index, count; +static int _environ_telnet(telnet_t *telnet, unsigned char type, char *buffer, size_t size) { + telnet_event_t ev; + struct telnet_environ_t *values = 0; + char *c, *last, *out; + size_t index, count; - /* if we have no data, just pass it through */ - if (size == 0) { - return 0; - } + /* if we have no data, just pass it through */ + if (size == 0) { + return 0; + } - /* first byte must be a valid command */ - if ((unsigned)buffer[0] != TELNET_ENVIRON_SEND && - (unsigned)buffer[0] != TELNET_ENVIRON_IS && - (unsigned)buffer[0] != TELNET_ENVIRON_INFO) { - telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, - "telopt %d subneg has invalid command", type); - return 0; - } + /* first byte must be a valid command */ + if ((unsigned)buffer[0] != TELNET_ENVIRON_SEND && (unsigned)buffer[0] != TELNET_ENVIRON_IS && + (unsigned)buffer[0] != TELNET_ENVIRON_INFO) { + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "telopt %d subneg has invalid command", type); + return 0; + } - /* store ENVIRON command */ - ev.environ.cmd = buffer[0]; + /* store ENVIRON command */ + ev.environ.cmd = buffer[0]; - /* if we have no arguments, send an event with no data end return */ - if (size == 1) { - /* no list of variables given */ - ev.environ.values = 0; - ev.environ.size = 0; + /* if we have no arguments, send an event with no data end return */ + if (size == 1) { + /* no list of variables given */ + ev.environ.values = 0; + ev.environ.size = 0; - /* invoke event with our arguments */ - ev.type = TELNET_EV_ENVIRON; - telnet->eh(telnet, &ev, telnet->ud); + /* invoke event with our arguments */ + ev.type = TELNET_EV_ENVIRON; + telnet->eh(telnet, &ev, telnet->ud); - return 1; - } + return 1; + } - /* very second byte must be VAR or USERVAR, if present */ - if ((unsigned)buffer[1] != TELNET_ENVIRON_VAR && - (unsigned)buffer[1] != TELNET_ENVIRON_USERVAR) { - telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, - "telopt %d subneg missing variable type", type); - return 0; - } + /* very second byte must be VAR or USERVAR, if present */ + if ((unsigned)buffer[1] != TELNET_ENVIRON_VAR && (unsigned)buffer[1] != TELNET_ENVIRON_USERVAR) { + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "telopt %d subneg missing variable type", type); + return 0; + } - /* ensure last byte is not an escape byte (makes parsing later easier) */ - if ((unsigned)buffer[size - 1] == TELNET_ENVIRON_ESC) { - telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, - "telopt %d subneg ends with ESC", type); - return 0; - } + /* ensure last byte is not an escape byte (makes parsing later easier) */ + if ((unsigned)buffer[size - 1] == TELNET_ENVIRON_ESC) { + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "telopt %d subneg ends with ESC", type); + return 0; + } - /* count arguments; each valid entry starts with VAR or USERVAR */ - count = 0; - for (c = buffer + 1; c < buffer + size; ++c) { - if (*c == TELNET_ENVIRON_VAR || *c == TELNET_ENVIRON_USERVAR) { - ++count; - } else if (*c == TELNET_ENVIRON_ESC) { - /* skip the next byte */ - ++c; - } - } + /* count arguments; each valid entry starts with VAR or USERVAR */ + count = 0; + for (c = buffer + 1; c < buffer + size; ++c) { + if (*c == TELNET_ENVIRON_VAR || *c == TELNET_ENVIRON_USERVAR) { + ++count; + } else if (*c == TELNET_ENVIRON_ESC) { + /* skip the next byte */ + ++c; + } + } - /* allocate argument array, bail on error */ - if ((values = (struct telnet_environ_t *)calloc(count, - sizeof(struct telnet_environ_t))) == 0) { - telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, - "calloc() failed: %s", strerror(errno)); - return 0; - } + /* allocate argument array, bail on error */ + if ((values = (struct telnet_environ_t *)calloc(count, sizeof(struct telnet_environ_t))) == 0) { + telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "calloc() failed: %s", strerror(errno)); + return 0; + } - /* parse argument array strings */ - out = buffer; - c = buffer + 1; - for (index = 0; index != count; ++index) { - /* remember the variable type (will be VAR or USERVAR) */ - values[index].type = *c++; + /* parse argument array strings */ + out = buffer; + c = buffer + 1; + for (index = 0; index != count; ++index) { + /* remember the variable type (will be VAR or USERVAR) */ + values[index].type = *c++; - /* scan until we find an end-marker, and buffer up unescaped - * bytes into our buffer */ - last = out; - while (c < buffer + size) { - /* stop at the next variable or at the value */ - if ((unsigned)*c == TELNET_ENVIRON_VAR || - (unsigned)*c == TELNET_ENVIRON_VALUE || - (unsigned)*c == TELNET_ENVIRON_USERVAR) { - break; - } + /* scan until we find an end-marker, and buffer up unescaped + * bytes into our buffer */ + last = out; + while (c < buffer + size) { + /* stop at the next variable or at the value */ + if ((unsigned)*c == TELNET_ENVIRON_VAR || (unsigned)*c == TELNET_ENVIRON_VALUE || + (unsigned)*c == TELNET_ENVIRON_USERVAR) { + break; + } - /* buffer next byte (taking into account ESC) */ - if (*c == TELNET_ENVIRON_ESC) { - ++c; - } + /* buffer next byte (taking into account ESC) */ + if (*c == TELNET_ENVIRON_ESC) { + ++c; + } - *out++ = *c++; - } - *out++ = '\0'; + *out++ = *c++; + } + *out++ = '\0'; - /* store the variable name we have just received */ - values[index].var = last; - values[index].value = ""; + /* store the variable name we have just received */ + values[index].var = last; + values[index].value = ""; - /* if we got a value, find the next end marker and - * store the value; otherwise, store empty string */ - if (c < buffer + size && *c == TELNET_ENVIRON_VALUE) { - ++c; - last = out; - while (c < buffer + size) { - /* stop when we find the start of the next variable */ - if ((unsigned)*c == TELNET_ENVIRON_VAR || - (unsigned)*c == TELNET_ENVIRON_USERVAR) { - break; - } + /* if we got a value, find the next end marker and + * store the value; otherwise, store empty string */ + if (c < buffer + size && *c == TELNET_ENVIRON_VALUE) { + ++c; + last = out; + while (c < buffer + size) { + /* stop when we find the start of the next variable */ + if ((unsigned)*c == TELNET_ENVIRON_VAR || (unsigned)*c == TELNET_ENVIRON_USERVAR) { + break; + } - /* buffer next byte (taking into account ESC) */ - if (*c == TELNET_ENVIRON_ESC) { - ++c; - } + /* buffer next byte (taking into account ESC) */ + if (*c == TELNET_ENVIRON_ESC) { + ++c; + } - *out++ = *c++; - } - *out++ = '\0'; + *out++ = *c++; + } + *out++ = '\0'; - /* store the variable value */ - values[index].value = last; - } - } + /* store the variable value */ + values[index].value = last; + } + } - /* pass values array and count to event */ - ev.environ.values = values; - ev.environ.size = count; + /* pass values array and count to event */ + ev.environ.values = values; + ev.environ.size = count; - /* invoke event with our arguments */ - ev.type = TELNET_EV_ENVIRON; - telnet->eh(telnet, &ev, telnet->ud); + /* invoke event with our arguments */ + ev.type = TELNET_EV_ENVIRON; + telnet->eh(telnet, &ev, telnet->ud); - /* clean up */ - free(values); - return 1; + /* clean up */ + free(values); + return 1; } /* process an MSSP subnegotiation buffer */ -static int _mssp_telnet(telnet_t *telnet, char* buffer, size_t size) { - telnet_event_t ev; - struct telnet_environ_t *values; - char *var = 0; - char *c, *last, *out; - size_t i, count; - unsigned char next_type; +static int _mssp_telnet(telnet_t *telnet, char *buffer, size_t size) { + telnet_event_t ev; + struct telnet_environ_t *values; + char *var = 0; + char *c, *last, *out; + size_t i, count; + unsigned char next_type; - /* if we have no data, just pass it through */ - if (size == 0) { - return 0; - } + /* if we have no data, just pass it through */ + if (size == 0) { + return 0; + } - /* first byte must be a VAR */ - if ((unsigned)buffer[0] != TELNET_MSSP_VAR) { - telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, - "MSSP subnegotiation has invalid data"); - return 0; - } + /* first byte must be a VAR */ + if ((unsigned)buffer[0] != TELNET_MSSP_VAR) { + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "MSSP subnegotiation has invalid data"); + return 0; + } - /* count the arguments, any part that starts with VALUE */ - for (count = 0, i = 0; i != size; ++i) { - if ((unsigned)buffer[i] == TELNET_MSSP_VAL) { - ++count; - } - } + /* count the arguments, any part that starts with VALUE */ + for (count = 0, i = 0; i != size; ++i) { + if ((unsigned)buffer[i] == TELNET_MSSP_VAL) { + ++count; + } + } - /* allocate argument array, bail on error */ - if ((values = (struct telnet_environ_t *)calloc(count, - sizeof(struct telnet_environ_t))) == 0) { - telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, - "calloc() failed: %s", strerror(errno)); - return 0; - } + /* allocate argument array, bail on error */ + if ((values = (struct telnet_environ_t *)calloc(count, sizeof(struct telnet_environ_t))) == 0) { + telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "calloc() failed: %s", strerror(errno)); + return 0; + } - ev.mssp.values = values; - ev.mssp.size = count; + ev.mssp.values = values; + ev.mssp.size = count; - /* allocate strings in argument array */ - out = last = buffer; - next_type = buffer[0]; - for (i = 0, c = buffer + 1; c < buffer + size;) { - /* search for end marker */ - while (c < buffer + size && (unsigned)*c != TELNET_MSSP_VAR && - (unsigned)*c != TELNET_MSSP_VAL) { - *out++ = *c++; - } - *out++ = '\0'; + /* allocate strings in argument array */ + out = last = buffer; + next_type = buffer[0]; + for (i = 0, c = buffer + 1; c < buffer + size;) { + /* search for end marker */ + while (c < buffer + size && (unsigned)*c != TELNET_MSSP_VAR && (unsigned)*c != TELNET_MSSP_VAL) { + *out++ = *c++; + } + *out++ = '\0'; - /* if it's a variable name, just store the name for now */ - if (next_type == TELNET_MSSP_VAR) { - var = last; - } else if (next_type == TELNET_MSSP_VAL && var != 0) { - values[i].var = var; - values[i].value = last; - ++i; - } else { - telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, - "invalid MSSP subnegotiation data"); - free(values); - return 0; - } + /* if it's a variable name, just store the name for now */ + if (next_type == TELNET_MSSP_VAR) { + var = last; + } else if (next_type == TELNET_MSSP_VAL && var != 0) { + values[i].var = var; + values[i].value = last; + ++i; + } else { + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "invalid MSSP subnegotiation data"); + free(values); + return 0; + } - /* remember our next type and increment c for next loop run */ - last = out; - next_type = *c++; - } + /* remember our next type and increment c for next loop run */ + last = out; + next_type = *c++; + } - /* invoke event with our arguments */ - ev.type = TELNET_EV_MSSP; - telnet->eh(telnet, &ev, telnet->ud); + /* invoke event with our arguments */ + ev.type = TELNET_EV_MSSP; + telnet->eh(telnet, &ev, telnet->ud); - /* clean up */ - free(values); + /* clean up */ + free(values); - return 0; + return 0; } /* parse ZMP command subnegotiation buffers */ -static int _zmp_telnet(telnet_t *telnet, const char* buffer, size_t size) { - telnet_event_t ev; - const char **argv; - const char *c; - size_t i, argc; +static int _zmp_telnet(telnet_t *telnet, const char *buffer, size_t size) { + telnet_event_t ev; + const char **argv; + const char *c; + size_t i, argc; - /* make sure this is a valid ZMP buffer */ - if (size == 0 || buffer[size - 1] != 0) { - telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, - "incomplete ZMP frame"); - return 0; - } + /* make sure this is a valid ZMP buffer */ + if (size == 0 || buffer[size - 1] != 0) { + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "incomplete ZMP frame"); + return 0; + } - /* count arguments */ - for (argc = 0, c = buffer; c != buffer + size; ++argc) - c += strlen(c) + 1; + /* count arguments */ + for (argc = 0, c = buffer; c != buffer + size; ++argc) + c += strlen(c) + 1; - /* allocate argument array, bail on error */ - if ((argv = (const char **)calloc(argc, sizeof(const char *))) == 0) { - telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, - "calloc() failed: %s", strerror(errno)); - return 0; - } + /* allocate argument array, bail on error */ + if ((argv = (const char **)calloc(argc, sizeof(const char *))) == 0) { + telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "calloc() failed: %s", strerror(errno)); + return 0; + } - /* populate argument array */ - for (i = 0, c = buffer; i != argc; ++i) { - argv[i] = c; - c += strlen(c) + 1; - } + /* populate argument array */ + for (i = 0, c = buffer; i != argc; ++i) { + argv[i] = c; + c += strlen(c) + 1; + } - /* invoke event with our arguments */ - ev.type = TELNET_EV_ZMP; - ev.zmp.argv = argv; - ev.zmp.argc = argc; - telnet->eh(telnet, &ev, telnet->ud); + /* invoke event with our arguments */ + ev.type = TELNET_EV_ZMP; + ev.zmp.argv = argv; + ev.zmp.argc = argc; + telnet->eh(telnet, &ev, telnet->ud); - /* clean up */ - free(argv); - return 0; + /* clean up */ + free(argv); + return 0; } /* parse TERMINAL-TYPE command subnegotiation buffers */ -static int _ttype_telnet(telnet_t *telnet, const char* buffer, size_t size) { - telnet_event_t ev; +static int _ttype_telnet(telnet_t *telnet, const char *buffer, size_t size) { + telnet_event_t ev; - /* make sure request is not empty */ - if (size == 0) { - telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, - "incomplete TERMINAL-TYPE request"); - return 0; - } + /* make sure request is not empty */ + if (size == 0) { + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "incomplete TERMINAL-TYPE request"); + return 0; + } - /* make sure request has valid command type */ - if (buffer[0] != TELNET_TTYPE_IS && - buffer[0] != TELNET_TTYPE_SEND) { - telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, - "TERMINAL-TYPE request has invalid type"); - return 0; - } + /* make sure request has valid command type */ + if (buffer[0] != TELNET_TTYPE_IS && buffer[0] != TELNET_TTYPE_SEND) { + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "TERMINAL-TYPE request has invalid type"); + return 0; + } - /* send proper event */ - if (buffer[0] == TELNET_TTYPE_IS) { - char *name; + /* send proper event */ + if (buffer[0] == TELNET_TTYPE_IS) { + char *name; - /* allocate space for name */ - if ((name = (char *)malloc(size)) == 0) { - telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, - "malloc() failed: %s", strerror(errno)); - return 0; - } - memcpy(name, buffer + 1, size - 1); - name[size - 1] = '\0'; + /* allocate space for name */ + if ((name = (char *)malloc(size)) == 0) { + telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "malloc() failed: %s", strerror(errno)); + return 0; + } + memcpy(name, buffer + 1, size - 1); + name[size - 1] = '\0'; - ev.type = TELNET_EV_TTYPE; - ev.ttype.cmd = TELNET_TTYPE_IS; - ev.ttype.name = name; - telnet->eh(telnet, &ev, telnet->ud); + ev.type = TELNET_EV_TTYPE; + ev.ttype.cmd = TELNET_TTYPE_IS; + ev.ttype.name = name; + telnet->eh(telnet, &ev, telnet->ud); - /* clean up */ - free(name); - } else { - ev.type = TELNET_EV_TTYPE; - ev.ttype.cmd = TELNET_TTYPE_SEND; - ev.ttype.name = 0; - telnet->eh(telnet, &ev, telnet->ud); - } + /* clean up */ + free(name); + } else { + ev.type = TELNET_EV_TTYPE; + ev.ttype.cmd = TELNET_TTYPE_SEND; + ev.ttype.name = 0; + telnet->eh(telnet, &ev, telnet->ud); + } - return 0; + return 0; } /* process a subnegotiation buffer; return non-zero if the current buffer * must be aborted and reprocessed due to COMPRESS2 being activated */ static int _subnegotiate(telnet_t *telnet) { - telnet_event_t ev; + telnet_event_t ev; - /* standard subnegotiation event */ - ev.type = TELNET_EV_SUBNEGOTIATION; - ev.sub.telopt = telnet->sb_telopt; - ev.sub.buffer = telnet->buffer; - ev.sub.size = telnet->buffer_pos; - telnet->eh(telnet, &ev, telnet->ud); + /* standard subnegotiation event */ + ev.type = TELNET_EV_SUBNEGOTIATION; + ev.sub.telopt = telnet->sb_telopt; + ev.sub.buffer = telnet->buffer; + ev.sub.size = telnet->buffer_pos; + telnet->eh(telnet, &ev, telnet->ud); - switch (telnet->sb_telopt) { + switch (telnet->sb_telopt) { #if defined(HAVE_ZLIB) - /* received COMPRESS2 begin marker, setup our zlib box and - * start handling the compressed stream if it's not already. - */ - case TELNET_TELOPT_COMPRESS2: - if (telnet->sb_telopt == TELNET_TELOPT_COMPRESS2) { - if (_init_zlib(telnet, 0, 1) != TELNET_EOK) - return 0; + /* received COMPRESS2 begin marker, setup our zlib box and + * start handling the compressed stream if it's not already. + */ + case TELNET_TELOPT_COMPRESS2: + if (telnet->sb_telopt == TELNET_TELOPT_COMPRESS2) { + if (_init_zlib(telnet, 0, 1) != TELNET_EOK) + return 0; - /* notify app that compression was enabled */ - ev.type = TELNET_EV_COMPRESS; - ev.compress.state = 1; - telnet->eh(telnet, &ev, telnet->ud); - return 1; - } - return 0; + /* notify app that compression was enabled */ + ev.type = TELNET_EV_COMPRESS; + ev.compress.state = 1; + telnet->eh(telnet, &ev, telnet->ud); + return 1; + } + return 0; #endif /* defined(HAVE_ZLIB) */ - /* specially handled subnegotiation telopt types */ - case TELNET_TELOPT_ZMP: - return _zmp_telnet(telnet, telnet->buffer, telnet->buffer_pos); - case TELNET_TELOPT_TTYPE: - return _ttype_telnet(telnet, telnet->buffer, telnet->buffer_pos); - case TELNET_TELOPT_ENVIRON: - case TELNET_TELOPT_NEW_ENVIRON: - return _environ_telnet(telnet, telnet->sb_telopt, telnet->buffer, - telnet->buffer_pos); - case TELNET_TELOPT_MSSP: - return _mssp_telnet(telnet, telnet->buffer, telnet->buffer_pos); - default: - return 0; - } + /* specially handled subnegotiation telopt types */ + case TELNET_TELOPT_ZMP: + return _zmp_telnet(telnet, telnet->buffer, telnet->buffer_pos); + case TELNET_TELOPT_TTYPE: + return _ttype_telnet(telnet, telnet->buffer, telnet->buffer_pos); + case TELNET_TELOPT_ENVIRON: + case TELNET_TELOPT_NEW_ENVIRON: + return _environ_telnet(telnet, telnet->sb_telopt, telnet->buffer, telnet->buffer_pos); + case TELNET_TELOPT_MSSP: + return _mssp_telnet(telnet, telnet->buffer, telnet->buffer_pos); + default: + return 0; + } } /* initialize a telnet state tracker */ -telnet_t *telnet_init(const telnet_telopt_t *telopts, - telnet_event_handler_t eh, unsigned char flags, void *user_data) { - /* allocate structure */ - struct telnet_t *telnet = (telnet_t*)calloc(1, sizeof(telnet_t)); - if (telnet == 0) - return 0; +telnet_t *telnet_init(const telnet_telopt_t *telopts, telnet_event_handler_t eh, unsigned char flags, void *user_data) { + /* allocate structure */ + struct telnet_t *telnet = (telnet_t *)calloc(1, sizeof(telnet_t)); + if (telnet == 0) + return 0; - /* initialize data */ - telnet->ud = user_data; - telnet->telopts = telopts; - telnet->eh = eh; - telnet->flags = flags; + /* initialize data */ + telnet->ud = user_data; + telnet->telopts = telopts; + telnet->eh = eh; + telnet->flags = flags; - return telnet; + return telnet; } /* free up any memory allocated by a state tracker */ void telnet_free(telnet_t *telnet) { - /* free sub-request buffer */ - if (telnet->buffer != 0) { - free(telnet->buffer); - telnet->buffer = 0; - telnet->buffer_size = 0; - telnet->buffer_pos = 0; - } + /* free sub-request buffer */ + if (telnet->buffer != 0) { + free(telnet->buffer); + telnet->buffer = 0; + telnet->buffer_size = 0; + telnet->buffer_pos = 0; + } #if defined(HAVE_ZLIB) - /* free zlib box */ - if (telnet->z != 0) { - if (telnet->flags & TELNET_PFLAG_DEFLATE) - deflateEnd(telnet->z); - else - inflateEnd(telnet->z); - free(telnet->z); - telnet->z = 0; - } + /* free zlib box */ + if (telnet->z != 0) { + if (telnet->flags & TELNET_PFLAG_DEFLATE) + deflateEnd(telnet->z); + else + inflateEnd(telnet->z); + free(telnet->z); + telnet->z = 0; + } #endif /* defined(HAVE_ZLIB) */ - /* free RFC1143 queue */ - if (telnet->q) { - free(telnet->q); - telnet->q = NULL; - telnet->q_size = 0; - telnet->q_cnt = 0; - } + /* free RFC1143 queue */ + if (telnet->q) { + free(telnet->q); + telnet->q = NULL; + telnet->q_size = 0; + telnet->q_cnt = 0; + } - /* free the telnet structure itself */ - free(telnet); + /* free the telnet structure itself */ + free(telnet); } /* push a byte into the telnet buffer */ -static telnet_error_t _buffer_byte(telnet_t *telnet, - unsigned char byte) { - char *new_buffer; - size_t i; +static telnet_error_t _buffer_byte(telnet_t *telnet, unsigned char byte) { + char *new_buffer; + size_t i; - /* check if we're out of room */ - if (telnet->buffer_pos == telnet->buffer_size) { - /* find the next buffer size */ - for (i = 0; i != _buffer_sizes_count; ++i) { - if (_buffer_sizes[i] == telnet->buffer_size) { - break; - } - } + /* check if we're out of room */ + if (telnet->buffer_pos == telnet->buffer_size) { + /* find the next buffer size */ + for (i = 0; i != _buffer_sizes_count; ++i) { + if (_buffer_sizes[i] == telnet->buffer_size) { + break; + } + } - /* overflow -- can't grow any more */ - if (i >= _buffer_sizes_count - 1) { - telnet_error(telnet, __LINE__, __func__, TELNET_EOVERFLOW, 0, - "subnegotiation buffer size limit reached"); - return TELNET_EOVERFLOW; - } + /* overflow -- can't grow any more */ + if (i >= _buffer_sizes_count - 1) { + telnet_error(telnet, __LINE__, __func__, TELNET_EOVERFLOW, 0, "subnegotiation buffer size limit reached"); + return TELNET_EOVERFLOW; + } - /* (re)allocate buffer */ - new_buffer = (char *)realloc(telnet->buffer, _buffer_sizes[i + 1]); - if (new_buffer == 0) { - telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, - "realloc() failed"); - return TELNET_ENOMEM; - } + /* (re)allocate buffer */ + new_buffer = (char *)realloc(telnet->buffer, _buffer_sizes[i + 1]); + if (new_buffer == 0) { + telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "realloc() failed"); + return TELNET_ENOMEM; + } - telnet->buffer = new_buffer; - telnet->buffer_size = _buffer_sizes[i + 1]; - } + telnet->buffer = new_buffer; + telnet->buffer_size = _buffer_sizes[i + 1]; + } - /* push the byte, all set */ - telnet->buffer[telnet->buffer_pos++] = byte; - return TELNET_EOK; + /* push the byte, all set */ + telnet->buffer[telnet->buffer_pos++] = byte; + return TELNET_EOK; } static void _process(telnet_t *telnet, const char *buffer, size_t size) { - telnet_event_t ev; - unsigned char byte; - size_t i, start; - for (i = start = 0; i != size; ++i) { - byte = buffer[i]; - switch (telnet->state) { - /* regular data */ - case TELNET_STATE_DATA: - /* on an IAC byte, pass through all pending bytes and - * switch states */ - if (byte == TELNET_IAC) { - if (i != start) { - ev.type = TELNET_EV_DATA; - ev.data.buffer = buffer + start; - ev.data.size = i - start; - telnet->eh(telnet, &ev, telnet->ud); - } - telnet->state = TELNET_STATE_IAC; - } else if (byte == '\r' && - (telnet->flags & TELNET_FLAG_NVT_EOL) && - !(telnet->flags & TELNET_FLAG_RECEIVE_BINARY)) { - if (i != start) { - ev.type = TELNET_EV_DATA; - ev.data.buffer = buffer + start; - ev.data.size = i - start; - telnet->eh(telnet, &ev, telnet->ud); - } - telnet->state = TELNET_STATE_EOL; - } - break; + telnet_event_t ev; + unsigned char byte; + size_t i, start; + for (i = start = 0; i != size; ++i) { + byte = buffer[i]; + switch (telnet->state) { + /* regular data */ + case TELNET_STATE_DATA: + /* on an IAC byte, pass through all pending bytes and + * switch states */ + if (byte == TELNET_IAC) { + if (i != start) { + ev.type = TELNET_EV_DATA; + ev.data.buffer = buffer + start; + ev.data.size = i - start; + telnet->eh(telnet, &ev, telnet->ud); + } + telnet->state = TELNET_STATE_IAC; + } else if (byte == '\r' && (telnet->flags & TELNET_FLAG_NVT_EOL) && + !(telnet->flags & TELNET_FLAG_RECEIVE_BINARY)) { + if (i != start) { + ev.type = TELNET_EV_DATA; + ev.data.buffer = buffer + start; + ev.data.size = i - start; + telnet->eh(telnet, &ev, telnet->ud); + } + telnet->state = TELNET_STATE_EOL; + } + break; - /* NVT EOL to be translated */ - case TELNET_STATE_EOL: - if (byte != '\n') { - byte = '\r'; - ev.type = TELNET_EV_DATA; - ev.data.buffer = (char*)&byte; - ev.data.size = 1; - telnet->eh(telnet, &ev, telnet->ud); - byte = buffer[i]; - } - // any byte following '\r' other than '\n' or '\0' is invalid, - // so pass both \r and the byte - start = i; - if (byte == '\0') - ++start; - /* state update */ - telnet->state = TELNET_STATE_DATA; - break; + /* NVT EOL to be translated */ + case TELNET_STATE_EOL: + if (byte != '\n') { + byte = '\r'; + ev.type = TELNET_EV_DATA; + ev.data.buffer = (char *)&byte; + ev.data.size = 1; + telnet->eh(telnet, &ev, telnet->ud); + byte = buffer[i]; + } + // any byte following '\r' other than '\n' or '\0' is invalid, + // so pass both \r and the byte + start = i; + if (byte == '\0') + ++start; + /* state update */ + telnet->state = TELNET_STATE_DATA; + break; - /* IAC command */ - case TELNET_STATE_IAC: - switch (byte) { - /* subnegotiation */ - case TELNET_SB: - telnet->state = TELNET_STATE_SB; - break; - /* negotiation commands */ - case TELNET_WILL: - telnet->state = TELNET_STATE_WILL; - break; - case TELNET_WONT: - telnet->state = TELNET_STATE_WONT; - break; - case TELNET_DO: - telnet->state = TELNET_STATE_DO; - break; - case TELNET_DONT: - telnet->state = TELNET_STATE_DONT; - break; - /* IAC escaping */ - case TELNET_IAC: - /* event */ - ev.type = TELNET_EV_DATA; - ev.data.buffer = (char*)&byte; - ev.data.size = 1; - telnet->eh(telnet, &ev, telnet->ud); + /* IAC command */ + case TELNET_STATE_IAC: + switch (byte) { + /* subnegotiation */ + case TELNET_SB: + telnet->state = TELNET_STATE_SB; + break; + /* negotiation commands */ + case TELNET_WILL: + telnet->state = TELNET_STATE_WILL; + break; + case TELNET_WONT: + telnet->state = TELNET_STATE_WONT; + break; + case TELNET_DO: + telnet->state = TELNET_STATE_DO; + break; + case TELNET_DONT: + telnet->state = TELNET_STATE_DONT; + break; + /* IAC escaping */ + case TELNET_IAC: + /* event */ + ev.type = TELNET_EV_DATA; + ev.data.buffer = (char *)&byte; + ev.data.size = 1; + telnet->eh(telnet, &ev, telnet->ud); - /* state update */ - start = i + 1; - telnet->state = TELNET_STATE_DATA; - break; - /* some other command */ - default: - /* event */ - ev.type = TELNET_EV_IAC; - ev.iac.cmd = byte; - telnet->eh(telnet, &ev, telnet->ud); + /* state update */ + start = i + 1; + telnet->state = TELNET_STATE_DATA; + break; + /* some other command */ + default: + /* event */ + ev.type = TELNET_EV_IAC; + ev.iac.cmd = byte; + telnet->eh(telnet, &ev, telnet->ud); - /* state update */ - start = i + 1; - telnet->state = TELNET_STATE_DATA; - } - break; + /* state update */ + start = i + 1; + telnet->state = TELNET_STATE_DATA; + } + break; - /* negotiation commands */ - case TELNET_STATE_WILL: - case TELNET_STATE_WONT: - case TELNET_STATE_DO: - case TELNET_STATE_DONT: - _negotiate(telnet, byte); - start = i + 1; - telnet->state = TELNET_STATE_DATA; - break; + /* negotiation commands */ + case TELNET_STATE_WILL: + case TELNET_STATE_WONT: + case TELNET_STATE_DO: + case TELNET_STATE_DONT: + _negotiate(telnet, byte); + start = i + 1; + telnet->state = TELNET_STATE_DATA; + break; - /* subnegotiation -- determine subnegotiation telopt */ - case TELNET_STATE_SB: - telnet->sb_telopt = byte; - telnet->buffer_pos = 0; - telnet->state = TELNET_STATE_SB_DATA; - break; + /* subnegotiation -- determine subnegotiation telopt */ + case TELNET_STATE_SB: + telnet->sb_telopt = byte; + telnet->buffer_pos = 0; + telnet->state = TELNET_STATE_SB_DATA; + break; - /* subnegotiation -- buffer bytes until end request */ - case TELNET_STATE_SB_DATA: - /* IAC command in subnegotiation -- either IAC SE or IAC IAC */ - if (byte == TELNET_IAC) { - telnet->state = TELNET_STATE_SB_DATA_IAC; - } else if (telnet->sb_telopt == TELNET_TELOPT_COMPRESS && byte == TELNET_WILL) { - /* In 1998 MCCP used TELOPT 85 and the protocol defined an invalid - * subnegotiation sequence (IAC SB 85 WILL SE) to start compression. - * Subsequently MCCP version 2 was created in 2000 using TELOPT 86 - * and a valid subnegotiation (IAC SB 86 IAC SE). libtelnet for now - * just captures and discards MCCPv1 sequences. - */ - start = i + 2; - telnet->state = TELNET_STATE_DATA; - /* buffer the byte, or bail if we can't */ - } else if (_buffer_byte(telnet, byte) != TELNET_EOK) { - start = i + 1; - telnet->state = TELNET_STATE_DATA; - } - break; + /* subnegotiation -- buffer bytes until end request */ + case TELNET_STATE_SB_DATA: + /* IAC command in subnegotiation -- either IAC SE or IAC IAC */ + if (byte == TELNET_IAC) { + telnet->state = TELNET_STATE_SB_DATA_IAC; + } else if (telnet->sb_telopt == TELNET_TELOPT_COMPRESS && byte == TELNET_WILL) { + /* In 1998 MCCP used TELOPT 85 and the protocol defined an invalid + * subnegotiation sequence (IAC SB 85 WILL SE) to start compression. + * Subsequently MCCP version 2 was created in 2000 using TELOPT 86 + * and a valid subnegotiation (IAC SB 86 IAC SE). libtelnet for now + * just captures and discards MCCPv1 sequences. + */ + start = i + 2; + telnet->state = TELNET_STATE_DATA; + /* buffer the byte, or bail if we can't */ + } else if (_buffer_byte(telnet, byte) != TELNET_EOK) { + start = i + 1; + telnet->state = TELNET_STATE_DATA; + } + break; - /* IAC escaping inside a subnegotiation */ - case TELNET_STATE_SB_DATA_IAC: - switch (byte) { - /* end subnegotiation */ - case TELNET_SE: - /* return to default state */ - start = i + 1; - telnet->state = TELNET_STATE_DATA; + /* IAC escaping inside a subnegotiation */ + case TELNET_STATE_SB_DATA_IAC: + switch (byte) { + /* end subnegotiation */ + case TELNET_SE: + /* return to default state */ + start = i + 1; + telnet->state = TELNET_STATE_DATA; - /* process subnegotiation */ - if (_subnegotiate(telnet) != 0) { - /* any remaining bytes in the buffer are compressed. - * we have to re-invoke telnet_recv to get those - * bytes inflated and abort trying to process the - * remaining compressed bytes in the current _process - * buffer argument - */ - telnet_recv(telnet, &buffer[start], size - start); - return; - } - break; - /* escaped IAC byte */ - case TELNET_IAC: - /* push IAC into buffer */ - if (_buffer_byte(telnet, TELNET_IAC) != - TELNET_EOK) { - start = i + 1; - telnet->state = TELNET_STATE_DATA; - } else { - telnet->state = TELNET_STATE_SB_DATA; - } - break; - /* something else -- protocol error. attempt to process - * content in subnegotiation buffer, then evaluate the - * given command as an IAC code. - */ - default: - telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, - "unexpected byte after IAC inside SB: %d", - byte); + /* process subnegotiation */ + if (_subnegotiate(telnet) != 0) { + /* any remaining bytes in the buffer are compressed. + * we have to re-invoke telnet_recv to get those + * bytes inflated and abort trying to process the + * remaining compressed bytes in the current _process + * buffer argument + */ + telnet_recv(telnet, &buffer[start], size - start); + return; + } + break; + /* escaped IAC byte */ + case TELNET_IAC: + /* push IAC into buffer */ + if (_buffer_byte(telnet, TELNET_IAC) != TELNET_EOK) { + start = i + 1; + telnet->state = TELNET_STATE_DATA; + } else { + telnet->state = TELNET_STATE_SB_DATA; + } + break; + /* something else -- protocol error. attempt to process + * content in subnegotiation buffer, then evaluate the + * given command as an IAC code. + */ + default: + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "unexpected byte after IAC inside SB: %d", byte); - /* enter IAC state */ - start = i + 1; - telnet->state = TELNET_STATE_IAC; + /* enter IAC state */ + start = i + 1; + telnet->state = TELNET_STATE_IAC; - /* process subnegotiation; see comment in - * TELNET_STATE_SB_DATA_IAC about invoking telnet_recv() - */ - if (_subnegotiate(telnet) != 0) { - telnet_recv(telnet, &buffer[start], size - start); - return; - } else { - /* recursive call to get the current input byte processed - * as a regular IAC command. we could use a goto, but - * that would be gross. - */ - _process(telnet, (char *)&byte, 1); - } - break; - } - break; - } - } + /* process subnegotiation; see comment in + * TELNET_STATE_SB_DATA_IAC about invoking telnet_recv() + */ + if (_subnegotiate(telnet) != 0) { + telnet_recv(telnet, &buffer[start], size - start); + return; + } else { + /* recursive call to get the current input byte processed + * as a regular IAC command. we could use a goto, but + * that would be gross. + */ + _process(telnet, (char *)&byte, 1); + } + break; + } + break; + } + } - /* pass through any remaining bytes */ - if (telnet->state == TELNET_STATE_DATA && i != start) { - ev.type = TELNET_EV_DATA; - ev.data.buffer = buffer + start; - ev.data.size = i - start; - telnet->eh(telnet, &ev, telnet->ud); - } + /* pass through any remaining bytes */ + if (telnet->state == TELNET_STATE_DATA && i != start) { + ev.type = TELNET_EV_DATA; + ev.data.buffer = buffer + start; + ev.data.size = i - start; + telnet->eh(telnet, &ev, telnet->ud); + } } /* push a bytes into the state tracker */ -void telnet_recv(telnet_t *telnet, const char *buffer, - size_t size) { +void telnet_recv(telnet_t *telnet, const char *buffer, size_t size) { #if defined(HAVE_ZLIB) - /* if we have an inflate (decompression) zlib stream, use it */ - if (telnet->z != 0 && !(telnet->flags & TELNET_PFLAG_DEFLATE)) { - char inflate_buffer[1024]; - int rs; + /* if we have an inflate (decompression) zlib stream, use it */ + if (telnet->z != 0 && !(telnet->flags & TELNET_PFLAG_DEFLATE)) { + char inflate_buffer[1024]; + int rs; - /* initialize zlib state */ - telnet->z->next_in = (unsigned char*)buffer; - telnet->z->avail_in = (unsigned int)size; - telnet->z->next_out = (unsigned char *)inflate_buffer; - telnet->z->avail_out = sizeof(inflate_buffer); + /* initialize zlib state */ + telnet->z->next_in = (unsigned char *)buffer; + telnet->z->avail_in = (unsigned int)size; + telnet->z->next_out = (unsigned char *)inflate_buffer; + telnet->z->avail_out = sizeof(inflate_buffer); - /* inflate until buffer exhausted and all output is produced */ - while (telnet->z->avail_in > 0 || telnet->z->avail_out == 0) { - /* reset output buffer */ + /* inflate until buffer exhausted and all output is produced */ + while (telnet->z->avail_in > 0 || telnet->z->avail_out == 0) { + /* reset output buffer */ - /* decompress */ - rs = inflate(telnet->z, Z_SYNC_FLUSH); + /* decompress */ + rs = inflate(telnet->z, Z_SYNC_FLUSH); - /* process the decompressed bytes on success */ - if (rs == Z_OK || rs == Z_STREAM_END) - _process(telnet, inflate_buffer, sizeof(inflate_buffer) - - telnet->z->avail_out); - else - telnet_error(telnet, __LINE__, __func__, TELNET_ECOMPRESS, 1, - "inflate() failed: %s", zError(rs)); + /* process the decompressed bytes on success */ + if (rs == Z_OK || rs == Z_STREAM_END) + _process(telnet, inflate_buffer, sizeof(inflate_buffer) - telnet->z->avail_out); + else + telnet_error(telnet, __LINE__, __func__, TELNET_ECOMPRESS, 1, "inflate() failed: %s", zError(rs)); - /* prepare output buffer for next run */ - telnet->z->next_out = (unsigned char *)inflate_buffer; - telnet->z->avail_out = sizeof(inflate_buffer); + /* prepare output buffer for next run */ + telnet->z->next_out = (unsigned char *)inflate_buffer; + telnet->z->avail_out = sizeof(inflate_buffer); - /* on error (or on end of stream) disable further inflation */ - if (rs != Z_OK) { - telnet_event_t ev; + /* on error (or on end of stream) disable further inflation */ + if (rs != Z_OK) { + telnet_event_t ev; - /* disable compression */ - inflateEnd(telnet->z); - free(telnet->z); - telnet->z = 0; + /* disable compression */ + inflateEnd(telnet->z); + free(telnet->z); + telnet->z = 0; - /* send event */ - ev.type = TELNET_EV_COMPRESS; - ev.compress.state = 0; - telnet->eh(telnet, &ev, telnet->ud); + /* send event */ + ev.type = TELNET_EV_COMPRESS; + ev.compress.state = 0; + telnet->eh(telnet, &ev, telnet->ud); - break; - } - } + break; + } + } - /* COMPRESS2 is not negotiated, just process */ - } else + /* COMPRESS2 is not negotiated, just process */ + } else #endif /* defined(HAVE_ZLIB) */ - _process(telnet, buffer, size); + _process(telnet, buffer, size); } /* send an iac command */ void telnet_iac(telnet_t *telnet, unsigned char cmd) { - unsigned char bytes[2]; - bytes[0] = TELNET_IAC; - bytes[1] = cmd; - _sendu(telnet, bytes, 2); + unsigned char bytes[2]; + bytes[0] = TELNET_IAC; + bytes[1] = cmd; + _sendu(telnet, bytes, 2); } /* send negotiation */ -void telnet_negotiate(telnet_t *telnet, unsigned char cmd, - unsigned char telopt) { - telnet_rfc1143_t q; +void telnet_negotiate(telnet_t *telnet, unsigned char cmd, unsigned char telopt) { + telnet_rfc1143_t q; - /* if we're in proxy mode, just send it now */ - if (telnet->flags & TELNET_FLAG_PROXY) { - unsigned char bytes[3]; - bytes[0] = TELNET_IAC; - bytes[1] = cmd; - bytes[2] = telopt; - _sendu(telnet, bytes, 3); - return; - } + /* if we're in proxy mode, just send it now */ + if (telnet->flags & TELNET_FLAG_PROXY) { + unsigned char bytes[3]; + bytes[0] = TELNET_IAC; + bytes[1] = cmd; + bytes[2] = telopt; + _sendu(telnet, bytes, 3); + return; + } - /* get current option states */ - q = _get_rfc1143(telnet, telopt); + /* get current option states */ + q = _get_rfc1143(telnet, telopt); - switch (cmd) { - /* advertise willingess to support an option */ - case TELNET_WILL: - switch (Q_US(q)) { - case Q_NO: - _set_rfc1143(telnet, telopt, Q_WANTYES, Q_HIM(q)); - _send_negotiate(telnet, TELNET_WILL, telopt); - break; - case Q_WANTNO: - _set_rfc1143(telnet, telopt, Q_WANTNO_OP, Q_HIM(q)); - break; - case Q_WANTYES_OP: - _set_rfc1143(telnet, telopt, Q_WANTYES, Q_HIM(q)); - break; - } - break; + switch (cmd) { + /* advertise willingess to support an option */ + case TELNET_WILL: + switch (Q_US(q)) { + case Q_NO: + _set_rfc1143(telnet, telopt, Q_WANTYES, Q_HIM(q)); + _send_negotiate(telnet, TELNET_WILL, telopt); + break; + case Q_WANTNO: + _set_rfc1143(telnet, telopt, Q_WANTNO_OP, Q_HIM(q)); + break; + case Q_WANTYES_OP: + _set_rfc1143(telnet, telopt, Q_WANTYES, Q_HIM(q)); + break; + } + break; - /* force turn-off of locally enabled option */ - case TELNET_WONT: - switch (Q_US(q)) { - case Q_YES: - _set_rfc1143(telnet, telopt, Q_WANTNO, Q_HIM(q)); - _send_negotiate(telnet, TELNET_WONT, telopt); - break; - case Q_WANTYES: - _set_rfc1143(telnet, telopt, Q_WANTYES_OP, Q_HIM(q)); - break; - case Q_WANTNO_OP: - _set_rfc1143(telnet, telopt, Q_WANTNO, Q_HIM(q)); - break; - } - break; + /* force turn-off of locally enabled option */ + case TELNET_WONT: + switch (Q_US(q)) { + case Q_YES: + _set_rfc1143(telnet, telopt, Q_WANTNO, Q_HIM(q)); + _send_negotiate(telnet, TELNET_WONT, telopt); + break; + case Q_WANTYES: + _set_rfc1143(telnet, telopt, Q_WANTYES_OP, Q_HIM(q)); + break; + case Q_WANTNO_OP: + _set_rfc1143(telnet, telopt, Q_WANTNO, Q_HIM(q)); + break; + } + break; - /* ask remote end to enable an option */ - case TELNET_DO: - switch (Q_HIM(q)) { - case Q_NO: - _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTYES); - _send_negotiate(telnet, TELNET_DO, telopt); - break; - case Q_WANTNO: - _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTNO_OP); - break; - case Q_WANTYES_OP: - _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTYES); - break; - } - break; + /* ask remote end to enable an option */ + case TELNET_DO: + switch (Q_HIM(q)) { + case Q_NO: + _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTYES); + _send_negotiate(telnet, TELNET_DO, telopt); + break; + case Q_WANTNO: + _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTNO_OP); + break; + case Q_WANTYES_OP: + _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTYES); + break; + } + break; - /* demand remote end disable an option */ - case TELNET_DONT: - switch (Q_HIM(q)) { - case Q_YES: - _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTNO); - _send_negotiate(telnet, TELNET_DONT, telopt); - break; - case Q_WANTYES: - _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTYES_OP); - break; - case Q_WANTNO_OP: - _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTNO); - break; - } - break; - } + /* demand remote end disable an option */ + case TELNET_DONT: + switch (Q_HIM(q)) { + case Q_YES: + _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTNO); + _send_negotiate(telnet, TELNET_DONT, telopt); + break; + case Q_WANTYES: + _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTYES_OP); + break; + case Q_WANTNO_OP: + _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTNO); + break; + } + break; + } } /* send non-command data (escapes IAC bytes) */ -void telnet_send(telnet_t *telnet, const char *buffer, - size_t size) { - size_t i, l; +void telnet_send(telnet_t *telnet, const char *buffer, size_t size) { + size_t i, l; - for (l = i = 0; i != size; ++i) { - /* dump prior portion of text, send escaped bytes */ - if (buffer[i] == (char)TELNET_IAC) { - /* dump prior text if any */ - if (i != l) { - _send(telnet, buffer + l, i - l); - } - l = i + 1; + for (l = i = 0; i != size; ++i) { + /* dump prior portion of text, send escaped bytes */ + if (buffer[i] == (char)TELNET_IAC) { + /* dump prior text if any */ + if (i != l) { + _send(telnet, buffer + l, i - l); + } + l = i + 1; - /* send escape */ - telnet_iac(telnet, TELNET_IAC); - } - } + /* send escape */ + telnet_iac(telnet, TELNET_IAC); + } + } - /* send whatever portion of buffer is left */ - if (i != l) { - _send(telnet, buffer + l, i - l); - } + /* send whatever portion of buffer is left */ + if (i != l) { + _send(telnet, buffer + l, i - l); + } } /* send non-command text (escapes IAC bytes and does NVT translation) */ -void telnet_send_text(telnet_t *telnet, const char *buffer, - size_t size) { - size_t i, l; +void telnet_send_text(telnet_t *telnet, const char *buffer, size_t size) { + size_t i, l; - for (l = i = 0; i != size; ++i) { - /* dump prior portion of text, send escaped bytes */ - if (buffer[i] == (char)TELNET_IAC) { - /* dump prior text if any */ - if (i != l) { - _send(telnet, buffer + l, i - l); - } - l = i + 1; + for (l = i = 0; i != size; ++i) { + /* dump prior portion of text, send escaped bytes */ + if (buffer[i] == (char)TELNET_IAC) { + /* dump prior text if any */ + if (i != l) { + _send(telnet, buffer + l, i - l); + } + l = i + 1; - /* send escape */ - telnet_iac(telnet, TELNET_IAC); - } - /* special characters if not in BINARY mode */ - else if (!(telnet->flags & TELNET_FLAG_TRANSMIT_BINARY) && - (buffer[i] == '\r' || buffer[i] == '\n')) { - /* dump prior portion of text */ - if (i != l) { - _send(telnet, buffer + l, i - l); - } - l = i + 1; + /* send escape */ + telnet_iac(telnet, TELNET_IAC); + } + /* special characters if not in BINARY mode */ + else if (!(telnet->flags & TELNET_FLAG_TRANSMIT_BINARY) && (buffer[i] == '\r' || buffer[i] == '\n')) { + /* dump prior portion of text */ + if (i != l) { + _send(telnet, buffer + l, i - l); + } + l = i + 1; - /* automatic translation of \r -> CRNUL */ - if (buffer[i] == '\r') { - _send(telnet, CRNUL, 2); - } - /* automatic translation of \n -> CRLF */ - else { - _send(telnet, CRLF, 2); - } - } - } + /* automatic translation of \r -> CRNUL */ + if (buffer[i] == '\r') { + _send(telnet, CRNUL, 2); + } + /* automatic translation of \n -> CRLF */ + else { + _send(telnet, CRLF, 2); + } + } + } - /* send whatever portion of buffer is left */ - if (i != l) { - _send(telnet, buffer + l, i - l); - } + /* send whatever portion of buffer is left */ + if (i != l) { + _send(telnet, buffer + l, i - l); + } } /* send subnegotiation header */ void telnet_begin_sb(telnet_t *telnet, unsigned char telopt) { - unsigned char sb[3]; - sb[0] = TELNET_IAC; - sb[1] = TELNET_SB; - sb[2] = telopt; - _sendu(telnet, sb, 3); + unsigned char sb[3]; + sb[0] = TELNET_IAC; + sb[1] = TELNET_SB; + sb[2] = telopt; + _sendu(telnet, sb, 3); } - /* send complete subnegotiation */ -void telnet_subnegotiation(telnet_t *telnet, unsigned char telopt, - const char *buffer, size_t size) { - unsigned char bytes[5]; - bytes[0] = TELNET_IAC; - bytes[1] = TELNET_SB; - bytes[2] = telopt; - bytes[3] = TELNET_IAC; - bytes[4] = TELNET_SE; +void telnet_subnegotiation(telnet_t *telnet, unsigned char telopt, const char *buffer, size_t size) { + unsigned char bytes[5]; + bytes[0] = TELNET_IAC; + bytes[1] = TELNET_SB; + bytes[2] = telopt; + bytes[3] = TELNET_IAC; + bytes[4] = TELNET_SE; - _sendu(telnet, bytes, 3); - telnet_send(telnet, buffer, size); - _sendu(telnet, bytes + 3, 2); + _sendu(telnet, bytes, 3); + telnet_send(telnet, buffer, size); + _sendu(telnet, bytes + 3, 2); #if defined(HAVE_ZLIB) - /* if we're a proxy and we just sent the COMPRESS2 marker, we must - * make sure all further data is compressed if not already. - */ - if (telnet->flags & TELNET_FLAG_PROXY && - telopt == TELNET_TELOPT_COMPRESS2) { - telnet_event_t ev; + /* if we're a proxy and we just sent the COMPRESS2 marker, we must + * make sure all further data is compressed if not already. + */ + if (telnet->flags & TELNET_FLAG_PROXY && telopt == TELNET_TELOPT_COMPRESS2) { + telnet_event_t ev; - if (_init_zlib(telnet, 1, 1) != TELNET_EOK) - return; + if (_init_zlib(telnet, 1, 1) != TELNET_EOK) + return; - /* notify app that compression was enabled */ - ev.type = TELNET_EV_COMPRESS; - ev.compress.state = 1; - telnet->eh(telnet, &ev, telnet->ud); - } + /* notify app that compression was enabled */ + ev.type = TELNET_EV_COMPRESS; + ev.compress.state = 1; + telnet->eh(telnet, &ev, telnet->ud); + } #endif /* defined(HAVE_ZLIB) */ } void telnet_begin_compress2(telnet_t *telnet) { #if defined(HAVE_ZLIB) - static const unsigned char compress2[] = { TELNET_IAC, TELNET_SB, - TELNET_TELOPT_COMPRESS2, TELNET_IAC, TELNET_SE }; + static const unsigned char compress2[] = {TELNET_IAC, TELNET_SB, TELNET_TELOPT_COMPRESS2, TELNET_IAC, TELNET_SE}; - telnet_event_t ev; + telnet_event_t ev; - /* attempt to create output stream first, bail if we can't */ - if (_init_zlib(telnet, 1, 0) != TELNET_EOK) - return; + /* attempt to create output stream first, bail if we can't */ + if (_init_zlib(telnet, 1, 0) != TELNET_EOK) + return; - /* send compression marker. we send directly to the event handler - * instead of passing through _send because _send would result in - * the compress marker itself being compressed. - */ - ev.type = TELNET_EV_SEND; - ev.data.buffer = (const char*)compress2; - ev.data.size = sizeof(compress2); - telnet->eh(telnet, &ev, telnet->ud); + /* send compression marker. we send directly to the event handler + * instead of passing through _send because _send would result in + * the compress marker itself being compressed. + */ + ev.type = TELNET_EV_SEND; + ev.data.buffer = (const char *)compress2; + ev.data.size = sizeof(compress2); + telnet->eh(telnet, &ev, telnet->ud); - /* notify app that compression was successfully enabled */ - ev.type = TELNET_EV_COMPRESS; - ev.compress.state = 1; - telnet->eh(telnet, &ev, telnet->ud); + /* notify app that compression was successfully enabled */ + ev.type = TELNET_EV_COMPRESS; + ev.compress.state = 1; + telnet->eh(telnet, &ev, telnet->ud); #else - (void)telnet; + (void)telnet; #endif /* defined(HAVE_ZLIB) */ } /* send formatted data with \r and \n translation in addition to IAC IAC */ int telnet_vprintf(telnet_t *telnet, const char *fmt, va_list va) { - char buffer[1024]; - char *output = buffer; - unsigned int rs, i, l; + char buffer[1024]; + char *output = buffer; + unsigned int rs, i, l; - /* format */ - va_list va2; - va_copy(va2, va); - rs = vsnprintf(buffer, sizeof(buffer), fmt, va); - if (rs >= sizeof(buffer)) { - output = (char*)malloc(rs + 1); - if (output == 0) { - telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, - "malloc() failed: %s", strerror(errno)); - va_end(va2); - return -1; - } - rs = vsnprintf(output, rs + 1, fmt, va2); - } - va_end(va2); + /* format */ + va_list va2; + va_copy(va2, va); + rs = vsnprintf(buffer, sizeof(buffer), fmt, va); + if (rs >= sizeof(buffer)) { + output = (char *)malloc(rs + 1); + if (output == 0) { + telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "malloc() failed: %s", strerror(errno)); + va_end(va2); + return -1; + } + rs = vsnprintf(output, rs + 1, fmt, va2); + } + va_end(va2); - /* send */ - for (l = i = 0; i != rs; ++i) { - /* special characters */ - if (output[i] == (char)TELNET_IAC || output[i] == '\r' || - output[i] == '\n') { - /* dump prior portion of text */ - if (i != l) - _send(telnet, output + l, i - l); - l = i + 1; + /* send */ + for (l = i = 0; i != rs; ++i) { + /* special characters */ + if (output[i] == (char)TELNET_IAC || output[i] == '\r' || output[i] == '\n') { + /* dump prior portion of text */ + if (i != l) + _send(telnet, output + l, i - l); + l = i + 1; - /* IAC -> IAC IAC */ - if (output[i] == (char)TELNET_IAC) - telnet_iac(telnet, TELNET_IAC); - /* automatic translation of \r -> CRNUL */ - else if (output[i] == '\r') - _send(telnet, CRNUL, 2); - /* automatic translation of \n -> CRLF */ - else if (output[i] == '\n') - _send(telnet, CRLF, 2); - } - } + /* IAC -> IAC IAC */ + if (output[i] == (char)TELNET_IAC) + telnet_iac(telnet, TELNET_IAC); + /* automatic translation of \r -> CRNUL */ + else if (output[i] == '\r') + _send(telnet, CRNUL, 2); + /* automatic translation of \n -> CRLF */ + else if (output[i] == '\n') + _send(telnet, CRLF, 2); + } + } - /* send whatever portion of output is left */ - if (i != l) { - _send(telnet, output + l, i - l); - } + /* send whatever portion of output is left */ + if (i != l) { + _send(telnet, output + l, i - l); + } - /* free allocated memory, if any */ - if (output != buffer) { - free(output); - } + /* free allocated memory, if any */ + if (output != buffer) { + free(output); + } - return rs; + return rs; } /* see telnet_vprintf */ int telnet_printf(telnet_t *telnet, const char *fmt, ...) { - va_list va; - int rs; + va_list va; + int rs; - va_start(va, fmt); - rs = telnet_vprintf(telnet, fmt, va); - va_end(va); + va_start(va, fmt); + rs = telnet_vprintf(telnet, fmt, va); + va_end(va); - return rs; + return rs; } /* send formatted data through telnet_send */ int telnet_raw_vprintf(telnet_t *telnet, const char *fmt, va_list va) { - char buffer[1024]; - char *output = buffer; - unsigned int rs; + char buffer[1024]; + char *output = buffer; + unsigned int rs; - /* format; allocate more space if necessary */ - va_list va2; - va_copy(va2, va); - rs = vsnprintf(buffer, sizeof(buffer), fmt, va); - if (rs >= sizeof(buffer)) { - output = (char*)malloc(rs + 1); - if (output == 0) { - telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, - "malloc() failed: %s", strerror(errno)); - va_end(va2); - return -1; - } - rs = vsnprintf(output, rs + 1, fmt, va2); - } - va_end(va2); + /* format; allocate more space if necessary */ + va_list va2; + va_copy(va2, va); + rs = vsnprintf(buffer, sizeof(buffer), fmt, va); + if (rs >= sizeof(buffer)) { + output = (char *)malloc(rs + 1); + if (output == 0) { + telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "malloc() failed: %s", strerror(errno)); + va_end(va2); + return -1; + } + rs = vsnprintf(output, rs + 1, fmt, va2); + } + va_end(va2); - /* send out the formatted data */ - telnet_send(telnet, output, rs); + /* send out the formatted data */ + telnet_send(telnet, output, rs); - /* release allocated memory, if any */ - if (output != buffer) { - free(output); - } + /* release allocated memory, if any */ + if (output != buffer) { + free(output); + } - return rs; + return rs; } /* see telnet_raw_vprintf */ int telnet_raw_printf(telnet_t *telnet, const char *fmt, ...) { - va_list va; - int rs; + va_list va; + int rs; - va_start(va, fmt); - rs = telnet_raw_vprintf(telnet, fmt, va); - va_end(va); + va_start(va, fmt); + rs = telnet_raw_vprintf(telnet, fmt, va); + va_end(va); - return rs; + return rs; } /* begin NEW-ENVIRON subnegotation */ void telnet_begin_newenviron(telnet_t *telnet, unsigned char cmd) { - telnet_begin_sb(telnet, TELNET_TELOPT_NEW_ENVIRON); - telnet_send(telnet, (const char *)&cmd, 1); + telnet_begin_sb(telnet, TELNET_TELOPT_NEW_ENVIRON); + telnet_send(telnet, (const char *)&cmd, 1); } /* send a NEW-ENVIRON value */ -void telnet_newenviron_value(telnet_t *telnet, unsigned char type, - const char *string) { - telnet_send(telnet, (const char*)&type, 1); +void telnet_newenviron_value(telnet_t *telnet, unsigned char type, const char *string) { + telnet_send(telnet, (const char *)&type, 1); - if (string != 0) { - telnet_send(telnet, string, strlen(string)); - } + if (string != 0) { + telnet_send(telnet, string, strlen(string)); + } } /* send TERMINAL-TYPE SEND command */ void telnet_ttype_send(telnet_t *telnet) { - static const unsigned char SEND[] = { TELNET_IAC, TELNET_SB, - TELNET_TELOPT_TTYPE, TELNET_TTYPE_SEND, TELNET_IAC, TELNET_SE }; - _sendu(telnet, SEND, sizeof(SEND)); + static const unsigned char SEND[] = {TELNET_IAC, TELNET_SB, TELNET_TELOPT_TTYPE, + TELNET_TTYPE_SEND, TELNET_IAC, TELNET_SE}; + _sendu(telnet, SEND, sizeof(SEND)); } /* send TERMINAL-TYPE IS command */ -void telnet_ttype_is(telnet_t *telnet, const char* ttype) { - static const unsigned char IS[] = { TELNET_IAC, TELNET_SB, - TELNET_TELOPT_TTYPE, TELNET_TTYPE_IS }; - _sendu(telnet, IS, sizeof(IS)); - _send(telnet, ttype, strlen(ttype)); - telnet_finish_sb(telnet); +void telnet_ttype_is(telnet_t *telnet, const char *ttype) { + static const unsigned char IS[] = {TELNET_IAC, TELNET_SB, TELNET_TELOPT_TTYPE, TELNET_TTYPE_IS}; + _sendu(telnet, IS, sizeof(IS)); + _send(telnet, ttype, strlen(ttype)); + telnet_finish_sb(telnet); } /* send ZMP data */ void telnet_send_zmp(telnet_t *telnet, size_t argc, const char **argv) { - size_t i; + size_t i; - /* ZMP header */ - telnet_begin_zmp(telnet, argv[0]); + /* ZMP header */ + telnet_begin_zmp(telnet, argv[0]); - /* send out each argument, including trailing NUL byte */ - for (i = 1; i != argc; ++i) - telnet_zmp_arg(telnet, argv[i]); + /* send out each argument, including trailing NUL byte */ + for (i = 1; i != argc; ++i) + telnet_zmp_arg(telnet, argv[i]); - /* ZMP footer */ - telnet_finish_zmp(telnet); + /* ZMP footer */ + telnet_finish_zmp(telnet); } /* send ZMP data using varargs */ void telnet_send_vzmpv(telnet_t *telnet, va_list va) { - const char* arg; + const char *arg; - /* ZMP header */ - telnet_begin_sb(telnet, TELNET_TELOPT_ZMP); + /* ZMP header */ + telnet_begin_sb(telnet, TELNET_TELOPT_ZMP); - /* send out each argument, including trailing NUL byte */ - while ((arg = va_arg(va, const char *)) != 0) - telnet_zmp_arg(telnet, arg); + /* send out each argument, including trailing NUL byte */ + while ((arg = va_arg(va, const char *)) != 0) + telnet_zmp_arg(telnet, arg); - /* ZMP footer */ - telnet_finish_zmp(telnet); + /* ZMP footer */ + telnet_finish_zmp(telnet); } /* see telnet_send_vzmpv */ void telnet_send_zmpv(telnet_t *telnet, ...) { - va_list va; + va_list va; - va_start(va, telnet); - telnet_send_vzmpv(telnet, va); - va_end(va); + va_start(va, telnet); + telnet_send_vzmpv(telnet, va); + va_end(va); } /* begin a ZMP command */ void telnet_begin_zmp(telnet_t *telnet, const char *cmd) { - telnet_begin_sb(telnet, TELNET_TELOPT_ZMP); - telnet_zmp_arg(telnet, cmd); + telnet_begin_sb(telnet, TELNET_TELOPT_ZMP); + telnet_zmp_arg(telnet, cmd); } /* send a ZMP argument */ -void telnet_zmp_arg(telnet_t *telnet, const char* arg) { - telnet_send(telnet, arg, strlen(arg) + 1); -} +void telnet_zmp_arg(telnet_t *telnet, const char *arg) { telnet_send(telnet, arg, strlen(arg) + 1); } diff --git a/src/apps/relay/libtelnet.h b/src/apps/relay/libtelnet.h index 40030c1..45c52f1 100644 --- a/src/apps/relay/libtelnet.h +++ b/src/apps/relay/libtelnet.h @@ -53,11 +53,11 @@ extern "C" { /* printf type checking feature in GCC and some other compilers */ #if __GNUC__ -# define TELNET_GNU_PRINTF(f,a) __attribute__((format(printf, f, a))) /*!< internal helper */ -# define TELNET_GNU_SENTINEL __attribute__((sentinel)) /*!< internal helper */ +#define TELNET_GNU_PRINTF(f, a) __attribute__((format(printf, f, a))) /*!< internal helper */ +#define TELNET_GNU_SENTINEL __attribute__((sentinel)) /*!< internal helper */ #else -# define TELNET_GNU_PRINTF(f,a) /*!< internal helper */ -# define TELNET_GNU_SENTINEL /*!< internal helper */ +#define TELNET_GNU_PRINTF(f, a) /*!< internal helper */ +#define TELNET_GNU_SENTINEL /*!< internal helper */ #endif /* Disable environ macro for Visual C++ 2015. */ @@ -178,168 +178,168 @@ typedef struct telnet_telopt_t telnet_telopt_t; /*! \name Telnet state tracker flags. */ /*@{*/ /*! Control behavior of telnet state tracker. */ -#define TELNET_FLAG_PROXY (1<<0) -#define TELNET_FLAG_NVT_EOL (1<<1) +#define TELNET_FLAG_PROXY (1 << 0) +#define TELNET_FLAG_NVT_EOL (1 << 1) /* Internal-only bits in option flags */ -#define TELNET_FLAG_TRANSMIT_BINARY (1<<5) -#define TELNET_FLAG_RECEIVE_BINARY (1<<6) -#define TELNET_PFLAG_DEFLATE (1<<7) +#define TELNET_FLAG_TRANSMIT_BINARY (1 << 5) +#define TELNET_FLAG_RECEIVE_BINARY (1 << 6) +#define TELNET_PFLAG_DEFLATE (1 << 7) /*@}*/ -/*! - * error codes +/*! + * error codes */ enum telnet_error_t { - TELNET_EOK = 0, /*!< no error */ - TELNET_EBADVAL, /*!< invalid parameter, or API misuse */ - TELNET_ENOMEM, /*!< memory allocation failure */ - TELNET_EOVERFLOW, /*!< data exceeds buffer size */ - TELNET_EPROTOCOL, /*!< invalid sequence of special bytes */ - TELNET_ECOMPRESS /*!< error handling compressed streams */ + TELNET_EOK = 0, /*!< no error */ + TELNET_EBADVAL, /*!< invalid parameter, or API misuse */ + TELNET_ENOMEM, /*!< memory allocation failure */ + TELNET_EOVERFLOW, /*!< data exceeds buffer size */ + TELNET_EPROTOCOL, /*!< invalid sequence of special bytes */ + TELNET_ECOMPRESS /*!< error handling compressed streams */ }; typedef enum telnet_error_t telnet_error_t; /*!< Error code type. */ -/*! - * event codes +/*! + * event codes */ enum telnet_event_type_t { - TELNET_EV_DATA = 0, /*!< raw text data has been received */ - TELNET_EV_SEND, /*!< data needs to be sent to the peer */ - TELNET_EV_IAC, /*!< generic IAC code received */ - TELNET_EV_WILL, /*!< WILL option negotiation received */ - TELNET_EV_WONT, /*!< WONT option neogitation received */ - TELNET_EV_DO, /*!< DO option negotiation received */ - TELNET_EV_DONT, /*!< DONT option negotiation received */ - TELNET_EV_SUBNEGOTIATION, /*!< sub-negotiation data received */ - TELNET_EV_COMPRESS, /*!< compression has been enabled */ - TELNET_EV_ZMP, /*!< ZMP command has been received */ - TELNET_EV_TTYPE, /*!< TTYPE command has been received */ - TELNET_EV_ENVIRON, /*!< ENVIRON command has been received */ - TELNET_EV_MSSP, /*!< MSSP command has been received */ - TELNET_EV_WARNING, /*!< recoverable error has occured */ - TELNET_EV_ERROR /*!< non-recoverable error has occured */ + TELNET_EV_DATA = 0, /*!< raw text data has been received */ + TELNET_EV_SEND, /*!< data needs to be sent to the peer */ + TELNET_EV_IAC, /*!< generic IAC code received */ + TELNET_EV_WILL, /*!< WILL option negotiation received */ + TELNET_EV_WONT, /*!< WONT option neogitation received */ + TELNET_EV_DO, /*!< DO option negotiation received */ + TELNET_EV_DONT, /*!< DONT option negotiation received */ + TELNET_EV_SUBNEGOTIATION, /*!< sub-negotiation data received */ + TELNET_EV_COMPRESS, /*!< compression has been enabled */ + TELNET_EV_ZMP, /*!< ZMP command has been received */ + TELNET_EV_TTYPE, /*!< TTYPE command has been received */ + TELNET_EV_ENVIRON, /*!< ENVIRON command has been received */ + TELNET_EV_MSSP, /*!< MSSP command has been received */ + TELNET_EV_WARNING, /*!< recoverable error has occured */ + TELNET_EV_ERROR /*!< non-recoverable error has occured */ }; typedef enum telnet_event_type_t telnet_event_type_t; /*!< Telnet event type. */ -/*! - * environ/MSSP command information +/*! + * environ/MSSP command information */ struct telnet_environ_t { - unsigned char type; /*!< either TELNET_ENVIRON_VAR or TELNET_ENVIRON_USERVAR */ - char *var; /*!< name of the variable being set */ - char *value; /*!< value of variable being set; empty string if no value */ + unsigned char type; /*!< either TELNET_ENVIRON_VAR or TELNET_ENVIRON_USERVAR */ + char *var; /*!< name of the variable being set */ + char *value; /*!< value of variable being set; empty string if no value */ }; -/*! - * event information +/*! + * event information */ union telnet_event_t { - /*! - * \brief Event type - * - * The type field will determine which of the other event structure fields - * have been filled in. For instance, if the event type is TELNET_EV_ZMP, - * then the zmp event field (and ONLY the zmp event field) will be filled - * in. - */ - enum telnet_event_type_t type; + /*! + * \brief Event type + * + * The type field will determine which of the other event structure fields + * have been filled in. For instance, if the event type is TELNET_EV_ZMP, + * then the zmp event field (and ONLY the zmp event field) will be filled + * in. + */ + enum telnet_event_type_t type; - /*! - * data event: for DATA and SEND events - */ - struct data_t { - enum telnet_event_type_t _type; /*!< alias for type */ - const char *buffer; /*!< byte buffer */ - size_t size; /*!< number of bytes in buffer */ - } data; + /*! + * data event: for DATA and SEND events + */ + struct data_t { + enum telnet_event_type_t _type; /*!< alias for type */ + const char *buffer; /*!< byte buffer */ + size_t size; /*!< number of bytes in buffer */ + } data; - /*! - * WARNING and ERROR events - */ - struct error_t { - enum telnet_event_type_t _type; /*!< alias for type */ - const char *file; /*!< file the error occured in */ - const char *func; /*!< function the error occured in */ - const char *msg; /*!< error message string */ - int line; /*!< line of file error occured on */ - telnet_error_t errcode; /*!< error code */ - } error; + /*! + * WARNING and ERROR events + */ + struct error_t { + enum telnet_event_type_t _type; /*!< alias for type */ + const char *file; /*!< file the error occured in */ + const char *func; /*!< function the error occured in */ + const char *msg; /*!< error message string */ + int line; /*!< line of file error occured on */ + telnet_error_t errcode; /*!< error code */ + } error; - /*! - * command event: for IAC - */ - struct iac_t { - enum telnet_event_type_t _type; /*!< alias for type */ - unsigned char cmd; /*!< telnet command received */ - } iac; + /*! + * command event: for IAC + */ + struct iac_t { + enum telnet_event_type_t _type; /*!< alias for type */ + unsigned char cmd; /*!< telnet command received */ + } iac; - /*! - * negotiation event: WILL, WONT, DO, DONT - */ - struct negotiate_t { - enum telnet_event_type_t _type; /*!< alias for type */ - unsigned char telopt; /*!< option being negotiated */ - } neg; + /*! + * negotiation event: WILL, WONT, DO, DONT + */ + struct negotiate_t { + enum telnet_event_type_t _type; /*!< alias for type */ + unsigned char telopt; /*!< option being negotiated */ + } neg; - /*! - * subnegotiation event - */ - struct subnegotiate_t { - enum telnet_event_type_t _type; /*!< alias for type */ - const char *buffer; /*!< data of sub-negotiation */ - size_t size; /*!< number of bytes in buffer */ - unsigned char telopt; /*!< option code for negotiation */ - } sub; + /*! + * subnegotiation event + */ + struct subnegotiate_t { + enum telnet_event_type_t _type; /*!< alias for type */ + const char *buffer; /*!< data of sub-negotiation */ + size_t size; /*!< number of bytes in buffer */ + unsigned char telopt; /*!< option code for negotiation */ + } sub; - /*! - * ZMP event - */ - struct zmp_t { - enum telnet_event_type_t _type; /*!< alias for type */ - const char **argv; /*!< array of argument string */ - size_t argc; /*!< number of elements in argv */ - } zmp; + /*! + * ZMP event + */ + struct zmp_t { + enum telnet_event_type_t _type; /*!< alias for type */ + const char **argv; /*!< array of argument string */ + size_t argc; /*!< number of elements in argv */ + } zmp; - /*! - * TTYPE event - */ - struct ttype_t { - enum telnet_event_type_t _type; /*!< alias for type */ - unsigned char cmd; /*!< TELNET_TTYPE_IS or TELNET_TTYPE_SEND */ - const char* name; /*!< terminal type name (IS only) */ - } ttype; + /*! + * TTYPE event + */ + struct ttype_t { + enum telnet_event_type_t _type; /*!< alias for type */ + unsigned char cmd; /*!< TELNET_TTYPE_IS or TELNET_TTYPE_SEND */ + const char *name; /*!< terminal type name (IS only) */ + } ttype; - /*! - * COMPRESS event - */ - struct compress_t { - enum telnet_event_type_t _type; /*!< alias for type */ - unsigned char state; /*!< 1 if compression is enabled, - 0 if disabled */ - } compress; + /*! + * COMPRESS event + */ + struct compress_t { + enum telnet_event_type_t _type; /*!< alias for type */ + unsigned char state; /*!< 1 if compression is enabled, + 0 if disabled */ + } compress; - /*! - * ENVIRON/NEW-ENVIRON event - */ - struct environ_t { - enum telnet_event_type_t _type; /*!< alias for type */ - const struct telnet_environ_t *values; /*!< array of variable values */ - size_t size; /*!< number of elements in values */ - unsigned char cmd; /*!< SEND, IS, or INFO */ - } environ; - - /*! - * MSSP event - */ - struct mssp_t { - enum telnet_event_type_t _type; /*!< alias for type */ - const struct telnet_environ_t *values; /*!< array of variable values */ - size_t size; /*!< number of elements in values */ - } mssp; + /*! + * ENVIRON/NEW-ENVIRON event + */ + struct environ_t { + enum telnet_event_type_t _type; /*!< alias for type */ + const struct telnet_environ_t *values; /*!< array of variable values */ + size_t size; /*!< number of elements in values */ + unsigned char cmd; /*!< SEND, IS, or INFO */ + } environ; + + /*! + * MSSP event + */ + struct mssp_t { + enum telnet_event_type_t _type; /*!< alias for type */ + const struct telnet_environ_t *values; /*!< array of variable values */ + size_t size; /*!< number of elements in values */ + } mssp; }; -/*! +/*! * \brief event handler * * This is the type of function that must be passed to @@ -351,20 +351,19 @@ union telnet_event_t { * \param event Event structure with details about the event * \param user_data User-supplied pointer */ -typedef void (*telnet_event_handler_t)(telnet_t *telnet, - telnet_event_t *event, void *user_data); +typedef void (*telnet_event_handler_t)(telnet_t *telnet, telnet_event_t *event, void *user_data); -/*! - * telopt support table element; use telopt of -1 for end marker +/*! + * telopt support table element; use telopt of -1 for end marker */ struct telnet_telopt_t { - short telopt; /*!< one of the TELOPT codes or -1 */ - unsigned char us; /*!< TELNET_WILL or TELNET_WONT */ - unsigned char him; /*!< TELNET_DO or TELNET_DONT */ + short telopt; /*!< one of the TELOPT codes or -1 */ + unsigned char us; /*!< TELNET_WILL or TELNET_WONT */ + unsigned char him; /*!< TELNET_DO or TELNET_DONT */ }; -/*! - * state tracker -- private data structure +/*! + * state tracker -- private data structure */ struct telnet_t; @@ -381,8 +380,8 @@ struct telnet_t; * \param user_data Optional data pointer that will be passsed to eh. * \return Telnet state tracker object. */ -extern telnet_t* telnet_init(const telnet_telopt_t *telopts, - telnet_event_handler_t eh, unsigned char flags, void *user_data); +extern telnet_t *telnet_init(const telnet_telopt_t *telopts, telnet_event_handler_t eh, unsigned char flags, + void *user_data); /*! * \brief Free up any memory allocated by a state tracker. @@ -407,8 +406,7 @@ extern void telnet_free(telnet_t *telnet); * \param buffer Pointer to byte buffer. * \param size Number of bytes pointed to by buffer. */ -extern void telnet_recv(telnet_t *telnet, const char *buffer, - size_t size); +extern void telnet_recv(telnet_t *telnet, const char *buffer, size_t size); /*! * \brief Send a telnet command. @@ -429,8 +427,7 @@ extern void telnet_iac(telnet_t *telnet, unsigned char cmd); * \param cmd TELNET_WILL, TELNET_WONT, TELNET_DO, or TELNET_DONT. * \param opt One of the TELNET_TELOPT_* values. */ -extern void telnet_negotiate(telnet_t *telnet, unsigned char cmd, - unsigned char opt); +extern void telnet_negotiate(telnet_t *telnet, unsigned char cmd, unsigned char opt); /*! * Send non-command data (escapes IAC bytes). @@ -439,8 +436,7 @@ extern void telnet_negotiate(telnet_t *telnet, unsigned char cmd, * \param buffer Buffer of bytes to send. * \param size Number of bytes to send. */ -extern void telnet_send(telnet_t *telnet, - const char *buffer, size_t size); +extern void telnet_send(telnet_t *telnet, const char *buffer, size_t size); /*! * Send non-command text (escapes IAC bytes and translates @@ -450,8 +446,7 @@ extern void telnet_send(telnet_t *telnet, * \param buffer Buffer of bytes to send. * \param size Number of bytes to send. */ -extern void telnet_send_text(telnet_t *telnet, - const char *buffer, size_t size); +extern void telnet_send_text(telnet_t *telnet, const char *buffer, size_t size); /*! * \brief Begin a sub-negotiation command. @@ -463,8 +458,7 @@ extern void telnet_send_text(telnet_t *telnet, * \param telnet Telnet state tracker object. * \param telopt One of the TELNET_TELOPT_* values. */ -extern void telnet_begin_sb(telnet_t *telnet, - unsigned char telopt); +extern void telnet_begin_sb(telnet_t *telnet, unsigned char telopt); /*! * \brief Finish a sub-negotiation command. @@ -489,8 +483,7 @@ extern void telnet_begin_sb(telnet_t *telnet, * \param buffer Byte buffer for sub-negotiation data. * \param size Number of bytes to use for sub-negotiation data. */ -extern void telnet_subnegotiation(telnet_t *telnet, unsigned char telopt, - const char *buffer, size_t size); +extern void telnet_subnegotiation(telnet_t *telnet, unsigned char telopt, const char *buffer, size_t size); /*! * \brief Begin sending compressed data. @@ -520,8 +513,7 @@ extern void telnet_begin_compress2(telnet_t *telnet); * \param fmt Format string. * \return Number of bytes sent. */ -extern int telnet_printf(telnet_t *telnet, const char *fmt, ...) - TELNET_GNU_PRINTF(2, 3); +extern int telnet_printf(telnet_t *telnet, const char *fmt, ...) TELNET_GNU_PRINTF(2, 3); /*! * \brief Send formatted data. @@ -541,8 +533,7 @@ extern int telnet_vprintf(telnet_t *telnet, const char *fmt, va_list va); * \param fmt Format string. * \return Number of bytes sent. */ -extern int telnet_raw_printf(telnet_t *telnet, const char *fmt, ...) - TELNET_GNU_PRINTF(2, 3); +extern int telnet_raw_printf(telnet_t *telnet, const char *fmt, ...) TELNET_GNU_PRINTF(2, 3); /*! * \brief Send formatted data (no newline escaping). @@ -577,8 +568,7 @@ extern void telnet_begin_newenviron(telnet_t *telnet, unsigned char type); * TELNET_ENVIRON_VALUE. * \param string Variable name or value. */ -extern void telnet_newenviron_value(telnet_t* telnet, unsigned char type, - const char *string); +extern void telnet_newenviron_value(telnet_t *telnet, unsigned char type, const char *string); /*! * \brief Finish a NEW-ENVIRON command. @@ -629,7 +619,7 @@ extern void telnet_ttype_send(telnet_t *telnet); * \param telnet Telnet state tracker object. * \param ttype Name of the terminal-type being sent. */ -extern void telnet_ttype_is(telnet_t *telnet, const char* ttype); +extern void telnet_ttype_is(telnet_t *telnet, const char *ttype); /*! * \brief Send a ZMP command. diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 9a87da7..1505fd6 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -34,13 +34,13 @@ #include "prom_server.h" #if defined(WINDOWS) - #include +#include - #define WORKING_BUFFER_SIZE 15000 - #define MAX_TRIES 3 +#define WORKING_BUFFER_SIZE 15000 +#define MAX_TRIES 3 - #define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x)) - #define FREE(x) HeapFree(GetProcessHeap(), 0, (x)) +#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x)) +#define FREE(x) HeapFree(GetProcessHeap(), 0, (x)) #endif #if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L) @@ -54,9 +54,9 @@ static int use_lt_credentials = 0; static int anon_credentials = 0; -//long term credential +// long term credential static int use_ltc = 0; -//timelimited long term credential +// timelimited long term credential static int use_tltc = 0; ////// ALPN ////////// @@ -91,57 +91,57 @@ char HTTP_ALPN[128] = "http/1.1"; turn_params_t turn_params = { //////////////// OpenSSL group ////////////////////// - NULL, /* tls_ctx */ - NULL, /* dtls_ctx */ + NULL, /* tls_ctx */ + NULL, /* dtls_ctx */ DH_2066, /*dh_key_size*/ - - "", /*cipher_list*/ - "", /*ec_curve_name*/ - - "", /*ca_cert_file*/ + + "", /*cipher_list*/ + "", /*ec_curve_name*/ + + "", /*ca_cert_file*/ "turn_server_cert.pem", /*cert_file*/ - "turn_server_pkey.pem", /*pkey_file*/ - "", /*tls_password*/ - "", /*dh_file*/ + "turn_server_pkey.pem", /*pkey_file*/ + "", /*tls_password*/ + "", /*dh_file*/ 0, /*no_tlsv1*/ - 0, /*no_tlsv1_1*/ - 0, /*no_tlsv1_2*/ - /*no_tls*/ - #if !TLS_SUPPORTED - 1, - #else - 0, - #endif - /*no_dtls*/ - #if !DTLS_SUPPORTED - 1, - #else - 0, - #endif + 0, /*no_tlsv1_1*/ + 0, /*no_tlsv1_2*/ + /*no_tls*/ +#if !TLS_SUPPORTED + 1, +#else + 0, +#endif +/*no_dtls*/ +#if !DTLS_SUPPORTED + 1, +#else + 0, +#endif - NULL, /*tls_ctx_update_ev*/ + NULL, /*tls_ctx_update_ev*/ {0, NULL}, /*tls_mutex*/ //////////////// Common params //////////////////// - TURN_VERBOSE_NONE, /* verbose */ - 0, /* turn_daemon */ - 0, /* no_software_attribute */ - 0, /* web_admin_listen_on_workers */ + TURN_VERBOSE_NONE, /* verbose */ + 0, /* turn_daemon */ + 0, /* no_software_attribute */ + 0, /* web_admin_listen_on_workers */ - 0, /* do_not_use_config_file */ + 0, /* do_not_use_config_file */ "/var/run/turnserver.pid", /* pidfile */ - "", /* acme_redirect */ + "", /* acme_redirect */ //////////////// Listener server ///////////////// - DEFAULT_STUN_PORT, /* listener_port*/ + DEFAULT_STUN_PORT, /* listener_port*/ DEFAULT_STUN_TLS_PORT, /* tls_listener_port */ - 0, /* alt_listener_port */ - 0, /* alt_tls_listener_port */ - 0, /* tcp_proxy_port */ - 1, /* rfc5780 */ + 0, /* alt_listener_port */ + 0, /* alt_tls_listener_port */ + 0, /* tcp_proxy_port */ + 1, /* rfc5780 */ 0, /* no_udp */ 0, /* no_tcp */ @@ -152,91 +152,89 @@ turn_params_t turn_params = { "", /*listener_ifname*/ - {"", ""}, /*redis_statsdb*/ - 0, /*use_redis_statsdb*/ - { - NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,NULL,NULL,NULL - }, /*listener*/ - {NULL, 0}, /*ip_whitelist*/ - {NULL, 0}, /*ip_blacklist*/ - NEV_UNKNOWN, /*net_engine_version*/ - { "Unknown", - "UDP listening socket per session", - "UDP thread per network endpoint", - "UDP thread per CPU core" }, /*net_engine_version_txt*/ + {"", ""}, /*redis_statsdb*/ + 0, /*use_redis_statsdb*/ + {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, NULL, NULL, NULL}, /*listener*/ + {NULL, 0}, /*ip_whitelist*/ + {NULL, 0}, /*ip_blacklist*/ + NEV_UNKNOWN, /*net_engine_version*/ + {"Unknown", "UDP listening socket per session", "UDP thread per network endpoint", + "UDP thread per CPU core"}, /*net_engine_version_txt*/ //////////////// Relay servers ////////////////////////////////// - LOW_DEFAULT_PORTS_BOUNDARY, /*min_port*/ - HIGH_DEFAULT_PORTS_BOUNDARY,/*max_port*/ + LOW_DEFAULT_PORTS_BOUNDARY, /*min_port*/ + HIGH_DEFAULT_PORTS_BOUNDARY, /*max_port*/ 0, /*check_origin*/ 0, /*no_multicast_peers*/ 0, /*allow_loopback_peers*/ - "", /*relay_ifname*/ - 0, /*relays_number*/ + "", /*relay_ifname*/ + 0, /*relays_number*/ NULL, /*relay_addrs*/ - 0, /*default_relays*/ + 0, /*default_relays*/ - NULL, /*external_ip*/ + NULL, /*external_ip*/ DEFAULT_GENERAL_RELAY_SERVERS_NUMBER, /*general_relay_servers_number*/ - 0, /*udp_relay_servers_number*/ + 0, /*udp_relay_servers_number*/ ////////////// Auth server ///////////////////////////////////// - "","",0, + "", + "", + 0, /////////////// AUX SERVERS //////////////// - {NULL,0,{0,NULL}}, /*aux_servers_list*/ - 0, /*udp_self_balance*/ + {NULL, 0, {0, NULL}}, /*aux_servers_list*/ + 0, /*udp_self_balance*/ /////////////// ALTERNATE SERVERS //////////////// - {NULL,0,{0,NULL}}, /*alternate_servers_list*/ - {NULL,0,{0,NULL}}, /*tls_alternate_servers_list*/ + {NULL, 0, {0, NULL}}, /*alternate_servers_list*/ + {NULL, 0, {0, NULL}}, /*tls_alternate_servers_list*/ /////////////// stop server //////////////// 0, /*stop_turn_server*/ /////////////// MISC PARAMS //////////////// - 0, /* stun_only */ - 0, /* no_stun */ - 0, /* secure_stun */ - 0, /* server_relay */ - 0, /* fingerprint */ - ':', /* rest_api_separator */ + 0, /* stun_only */ + 0, /* no_stun */ + 0, /* secure_stun */ + 0, /* server_relay */ + 0, /* fingerprint */ + ':', /* rest_api_separator */ STUN_DEFAULT_NONCE_EXPIRATION_TIME, /* stale_nonce */ STUN_DEFAULT_MAX_ALLOCATE_LIFETIME, /* max_allocate_lifetime */ - STUN_DEFAULT_CHANNEL_LIFETIME, /* channel_lifetime */ - STUN_DEFAULT_PERMISSION_LIFETIME, /* permission_lifetime */ - 0, /* mobility */ - TURN_CREDENTIALS_NONE, /* ct */ - 0, /* use_auth_secret_with_timestamp */ - 0, /* max_bps */ - 0, /* bps_capacity */ - 0, /* bps_capacity_allocated */ - 0, /* total_quota */ - 0, /* user_quota */ - 0, /* prometheus disabled by default */ - DEFAULT_PROM_SERVER_PORT, /* prometheus port */ + STUN_DEFAULT_CHANNEL_LIFETIME, /* channel_lifetime */ + STUN_DEFAULT_PERMISSION_LIFETIME, /* permission_lifetime */ + 0, /* mobility */ + TURN_CREDENTIALS_NONE, /* ct */ + 0, /* use_auth_secret_with_timestamp */ + 0, /* max_bps */ + 0, /* bps_capacity */ + 0, /* bps_capacity_allocated */ + 0, /* total_quota */ + 0, /* user_quota */ + 0, /* prometheus disabled by default */ + DEFAULT_PROM_SERVER_PORT, /* prometheus port */ 0, /* prometheus username labelling disabled by default when prometheus is enabled */ ///////////// Users DB ////////////// - { (TURN_USERDB_TYPE)0, {"\0","\0"}, {0,NULL, {NULL,0}} }, + {(TURN_USERDB_TYPE)0, {"\0", "\0"}, {0, NULL, {NULL, 0}}}, ///////////// CPUs ////////////////// DEFAULT_CPUS_NUMBER, ///////// Encryption ///////// - "", /* secret_key_file */ - "", /* secret_key */ - ALLOCATION_DEFAULT_ADDRESS_FAMILY_IPV4, /* allocation_default_address_family */ - 0, /* no_auth_pings */ - 0, /* no_dynamic_ip_list */ - 0, /* no_dynamic_realms */ + "", /* secret_key_file */ + "", /* secret_key */ + ALLOCATION_DEFAULT_ADDRESS_FAMILY_IPV4, /* allocation_default_address_family */ + 0, /* no_auth_pings */ + 0, /* no_dynamic_ip_list */ + 0, /* no_dynamic_realms */ - 0, /* log_binding */ - 0, /* no_stun_backward_compatibility */ - 0 /* response_origin_only_with_rfc5780 */ + 0, /* log_binding */ + 0, /* no_stun_backward_compatibility */ + 0 /* response_origin_only_with_rfc5780 */ }; //////////////// OpenSSL Init ////////////////////// @@ -248,18 +246,18 @@ static void openssl_setup(void); * openssl req -new -key pkey -out cert.req * openssl x509 -req -days 365 -in cert.req -signkey pkey -out cert * -*/ + */ //////////// Common static process params //////// #if defined(WINDOWS) -//TODO: implement it!!! +// TODO: implement it!!! #else static gid_t procgroupid = 0; static uid_t procuserid = 0; static gid_t procgroupid_set = 0; static uid_t procuserid_set = 0; -static char procusername[1025]="\0"; -static char procgroupname[1025]="\0"; +static char procusername[1025] = "\0"; +static char procgroupname[1025] = "\0"; #endif ////////////// Configuration functionality //////////////////////////////// @@ -269,2873 +267,2973 @@ static void reload_ssl_certs(evutil_socket_t sock, short events, void *args); ////////////////////////////////////////////////// -static int make_local_listeners_list(void) -{ - int ret = 0; +static int make_local_listeners_list(void) { + int ret = 0; #if defined(WINDOWS) - DWORD dwSize = 0; - DWORD dwRetVal = 0; + DWORD dwSize = 0; + DWORD dwRetVal = 0; - unsigned int i = 0; + unsigned int i = 0; - // Set the flags to pass to GetAdaptersAddresses - ULONG flags = GAA_FLAG_INCLUDE_PREFIX; + // Set the flags to pass to GetAdaptersAddresses + ULONG flags = GAA_FLAG_INCLUDE_PREFIX; - // default to unspecified address family (both) - ULONG family = AF_UNSPEC; + // default to unspecified address family (both) + ULONG family = AF_UNSPEC; - LPVOID lpMsgBuf = NULL; + LPVOID lpMsgBuf = NULL; - PIP_ADAPTER_ADDRESSES pAddresses = NULL; - ULONG outBufLen = 0; - ULONG Iterations = 0; + PIP_ADAPTER_ADDRESSES pAddresses = NULL; + ULONG outBufLen = 0; + ULONG Iterations = 0; - PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL; - PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL; - PIP_ADAPTER_ANYCAST_ADDRESS pAnycast = NULL; - PIP_ADAPTER_MULTICAST_ADDRESS pMulticast = NULL; - IP_ADAPTER_DNS_SERVER_ADDRESS *pDnServer = NULL; - IP_ADAPTER_PREFIX *pPrefix = NULL; + PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL; + PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL; + PIP_ADAPTER_ANYCAST_ADDRESS pAnycast = NULL; + PIP_ADAPTER_MULTICAST_ADDRESS pMulticast = NULL; + IP_ADAPTER_DNS_SERVER_ADDRESS *pDnServer = NULL; + IP_ADAPTER_PREFIX *pPrefix = NULL; - // Allocate a 15 KB buffer to start with. - outBufLen = WORKING_BUFFER_SIZE; + // Allocate a 15 KB buffer to start with. + outBufLen = WORKING_BUFFER_SIZE; - do { + do { - pAddresses = (IP_ADAPTER_ADDRESSES *)MALLOC(outBufLen); - if (pAddresses == NULL) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n"); - return -1; - } - - dwRetVal = - GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen); - - if (dwRetVal == ERROR_BUFFER_OVERFLOW) { - FREE(pAddresses); - pAddresses = NULL; - } - else { - break; - } - - Iterations++; - - } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES)); - - if (dwRetVal == NO_ERROR) { - // If successful, output some information from the data we received - pCurrAddresses = pAddresses; - while (pCurrAddresses) { - /* - printf("\tLength of the IP_ADAPTER_ADDRESS struct: %ld\n", - pCurrAddresses->Length); - printf("\tIfIndex (IPv4 interface): %u\n", pCurrAddresses->IfIndex); - printf("\tAdapter name: %s\n", pCurrAddresses->AdapterName);//*/ - - pUnicast = pCurrAddresses->FirstUnicastAddress; - if (pUnicast != NULL) { - //printf("\tNumber of Unicast Addresses:\n"); - for (i = 0; pUnicast != NULL; pUnicast = pUnicast->Next) - { - char saddr[INET6_ADDRSTRLEN] = ""; - if (AF_INET == pUnicast->Address.lpSockaddr->sa_family) // IPV4 - { - if (!inet_ntop(PF_INET, - &((struct sockaddr_in*)pUnicast->Address.lpSockaddr)->sin_addr, - saddr, INET6_ADDRSTRLEN)) - continue; - if (strstr(saddr, "169.254.") == saddr) - continue; - if (!strcmp(saddr, "0.0.0.0")) - continue; - } - else if (AF_INET6 == pUnicast->Address.lpSockaddr->sa_family) // IPV6 - { - if (!inet_ntop(PF_INET6, - &((struct sockaddr_in6*)pUnicast->Address.lpSockaddr)->sin6_addr, - saddr, INET6_ADDRSTRLEN)) - continue; - if (strstr(saddr, "fe80") == saddr) - continue; - if (!strcmp(saddr, "::")) - continue; - } - else - continue; - - //printf("\t\tIP: %s\n", saddr); - - add_listener_addr(saddr); - - if (MIB_IF_TYPE_LOOPBACK != pCurrAddresses->IfType) - ret++; - } - } - /* - else - printf("\tNo Unicast Addresses\n"); - - pAnycast = pCurrAddresses->FirstAnycastAddress; - if (pAnycast) { - for (i = 0; pAnycast != NULL; i++) - pAnycast = pAnycast->Next; - printf("\tNumber of Anycast Addresses: %d\n", i); - } - else - printf("\tNo Anycast Addresses\n"); - - pMulticast = pCurrAddresses->FirstMulticastAddress; - if (pMulticast) { - for (i = 0; pMulticast != NULL; i++) - pMulticast = pMulticast->Next; - printf("\tNumber of Multicast Addresses: %d\n", i); - } - else - printf("\tNo Multicast Addresses\n"); - - pDnServer = pCurrAddresses->FirstDnsServerAddress; - if (pDnServer) { - for (i = 0; pDnServer != NULL; i++) - pDnServer = pDnServer->Next; - printf("\tNumber of DNS Server Addresses: %d\n", i); - } - else - printf("\tNo DNS Server Addresses\n"); - - printf("\tDNS Suffix: %wS\n", pCurrAddresses->DnsSuffix); - printf("\tDescription: %wS\n", pCurrAddresses->Description); - printf("\tFriendly name: %wS\n", pCurrAddresses->FriendlyName); - - if (pCurrAddresses->PhysicalAddressLength != 0) { - printf("\tPhysical address: "); - for (i = 0; i < (int)pCurrAddresses->PhysicalAddressLength; - i++) { - if (i == (pCurrAddresses->PhysicalAddressLength - 1)) - printf("%.2X\n", - (int)pCurrAddresses->PhysicalAddress[i]); - else - printf("%.2X-", - (int)pCurrAddresses->PhysicalAddress[i]); - } - } - printf("\tFlags: %ld\n", pCurrAddresses->Flags); - printf("\tMtu: %lu\n", pCurrAddresses->Mtu); - char* pType = NULL; - - switch (pCurrAddresses->IfType) - { - case MIB_IF_TYPE_ETHERNET: - pType = "ETHERNET"; - break; - case MIB_IF_TYPE_PPP: - pType = "PPP"; - break; - case MIB_IF_TYPE_LOOPBACK: - pType = "LOOPBACK"; - break; - case MIB_IF_TYPE_SLIP: - pType = "ATM"; - break; - case IF_TYPE_IEEE80211: - pType = "WIFI"; - break; - } - printf("\tIfType: %ld (%s)\n", pCurrAddresses->IfType, pType); - printf("\tOperStatus: %ld\n", pCurrAddresses->OperStatus); - printf("\tIpv6IfIndex (IPv6 interface): %u\n", - pCurrAddresses->Ipv6IfIndex); - printf("\tZoneIndices (hex): "); - for (i = 0; i < 16; i++) - printf("%lx ", pCurrAddresses->ZoneIndices[i]); - printf("\n"); - - printf("\tTransmit link speed: %I64u\n", pCurrAddresses->TransmitLinkSpeed); - printf("\tReceive link speed: %I64u\n", pCurrAddresses->ReceiveLinkSpeed); - - pPrefix = pCurrAddresses->FirstPrefix; - if (pPrefix) { - for (i = 0; pPrefix != NULL; i++) - pPrefix = pPrefix->Next; - printf("\tNumber of IP Adapter Prefix entries: %d\n", i); - } - else - printf("\tNumber of IP Adapter Prefix entries: 0\n"); - - printf("\n");//*/ - - pCurrAddresses = pCurrAddresses->Next; - } + pAddresses = (IP_ADAPTER_ADDRESSES *)MALLOC(outBufLen); + if (pAddresses == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n"); + return -1; } + + dwRetVal = GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen); + + if (dwRetVal == ERROR_BUFFER_OVERFLOW) { + FREE(pAddresses); + pAddresses = NULL; + } else { + break; + } + + Iterations++; + + } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES)); + + if (dwRetVal == NO_ERROR) { + // If successful, output some information from the data we received + pCurrAddresses = pAddresses; + while (pCurrAddresses) { + /* + printf("\tLength of the IP_ADAPTER_ADDRESS struct: %ld\n", + pCurrAddresses->Length); + printf("\tIfIndex (IPv4 interface): %u\n", pCurrAddresses->IfIndex); + printf("\tAdapter name: %s\n", pCurrAddresses->AdapterName);//*/ + + pUnicast = pCurrAddresses->FirstUnicastAddress; + if (pUnicast != NULL) { + // printf("\tNumber of Unicast Addresses:\n"); + for (i = 0; pUnicast != NULL; pUnicast = pUnicast->Next) { + char saddr[INET6_ADDRSTRLEN] = ""; + if (AF_INET == pUnicast->Address.lpSockaddr->sa_family) // IPV4 + { + if (!inet_ntop(PF_INET, &((struct sockaddr_in *)pUnicast->Address.lpSockaddr)->sin_addr, saddr, + INET6_ADDRSTRLEN)) + continue; + if (strstr(saddr, "169.254.") == saddr) + continue; + if (!strcmp(saddr, "0.0.0.0")) + continue; + } else if (AF_INET6 == pUnicast->Address.lpSockaddr->sa_family) // IPV6 + { + if (!inet_ntop(PF_INET6, &((struct sockaddr_in6 *)pUnicast->Address.lpSockaddr)->sin6_addr, saddr, + INET6_ADDRSTRLEN)) + continue; + if (strstr(saddr, "fe80") == saddr) + continue; + if (!strcmp(saddr, "::")) + continue; + } else + continue; + + // printf("\t\tIP: %s\n", saddr); + + add_listener_addr(saddr); + + if (MIB_IF_TYPE_LOOPBACK != pCurrAddresses->IfType) + ret++; + } + } + /* + else + printf("\tNo Unicast Addresses\n"); + + pAnycast = pCurrAddresses->FirstAnycastAddress; + if (pAnycast) { + for (i = 0; pAnycast != NULL; i++) + pAnycast = pAnycast->Next; + printf("\tNumber of Anycast Addresses: %d\n", i); + } + else + printf("\tNo Anycast Addresses\n"); + + pMulticast = pCurrAddresses->FirstMulticastAddress; + if (pMulticast) { + for (i = 0; pMulticast != NULL; i++) + pMulticast = pMulticast->Next; + printf("\tNumber of Multicast Addresses: %d\n", i); + } + else + printf("\tNo Multicast Addresses\n"); + + pDnServer = pCurrAddresses->FirstDnsServerAddress; + if (pDnServer) { + for (i = 0; pDnServer != NULL; i++) + pDnServer = pDnServer->Next; + printf("\tNumber of DNS Server Addresses: %d\n", i); + } + else + printf("\tNo DNS Server Addresses\n"); + + printf("\tDNS Suffix: %wS\n", pCurrAddresses->DnsSuffix); + printf("\tDescription: %wS\n", pCurrAddresses->Description); + printf("\tFriendly name: %wS\n", pCurrAddresses->FriendlyName); + + if (pCurrAddresses->PhysicalAddressLength != 0) { + printf("\tPhysical address: "); + for (i = 0; i < (int)pCurrAddresses->PhysicalAddressLength; + i++) { + if (i == (pCurrAddresses->PhysicalAddressLength - 1)) + printf("%.2X\n", + (int)pCurrAddresses->PhysicalAddress[i]); + else + printf("%.2X-", + (int)pCurrAddresses->PhysicalAddress[i]); + } + } + printf("\tFlags: %ld\n", pCurrAddresses->Flags); + printf("\tMtu: %lu\n", pCurrAddresses->Mtu); + char* pType = NULL; + + switch (pCurrAddresses->IfType) + { + case MIB_IF_TYPE_ETHERNET: + pType = "ETHERNET"; + break; + case MIB_IF_TYPE_PPP: + pType = "PPP"; + break; + case MIB_IF_TYPE_LOOPBACK: + pType = "LOOPBACK"; + break; + case MIB_IF_TYPE_SLIP: + pType = "ATM"; + break; + case IF_TYPE_IEEE80211: + pType = "WIFI"; + break; + } + printf("\tIfType: %ld (%s)\n", pCurrAddresses->IfType, pType); + printf("\tOperStatus: %ld\n", pCurrAddresses->OperStatus); + printf("\tIpv6IfIndex (IPv6 interface): %u\n", + pCurrAddresses->Ipv6IfIndex); + printf("\tZoneIndices (hex): "); + for (i = 0; i < 16; i++) + printf("%lx ", pCurrAddresses->ZoneIndices[i]); + printf("\n"); + + printf("\tTransmit link speed: %I64u\n", pCurrAddresses->TransmitLinkSpeed); + printf("\tReceive link speed: %I64u\n", pCurrAddresses->ReceiveLinkSpeed); + + pPrefix = pCurrAddresses->FirstPrefix; + if (pPrefix) { + for (i = 0; pPrefix != NULL; i++) + pPrefix = pPrefix->Next; + printf("\tNumber of IP Adapter Prefix entries: %d\n", i); + } + else + printf("\tNumber of IP Adapter Prefix entries: 0\n"); + + printf("\n");//*/ + + pCurrAddresses = pCurrAddresses->Next; + } + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Call to GetAdaptersAddresses failed with error: %d\n", dwRetVal); + if (dwRetVal == ERROR_NO_DATA) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\tNo addresses were found for the requested parameters\n"); else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Call to GetAdaptersAddresses failed with error: %d\n", - dwRetVal); - if (dwRetVal == ERROR_NO_DATA) - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "\tNo addresses were found for the requested parameters\n"); - else { - if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, dwRetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - // Default language - (LPTSTR)& lpMsgBuf, 0, NULL)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\tError: %s", lpMsgBuf); - LocalFree(lpMsgBuf); - if (pAddresses) - FREE(pAddresses); - return -2; - } - } + if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, dwRetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + // Default language + (LPTSTR)&lpMsgBuf, 0, NULL)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\tError: %s", lpMsgBuf); + LocalFree(lpMsgBuf); + if (pAddresses) + FREE(pAddresses); + return -2; + } } + } - if (pAddresses) { - FREE(pAddresses); - } + if (pAddresses) { + FREE(pAddresses); + } #else - struct ifaddrs * ifs = NULL; - struct ifaddrs * ifa = NULL; + struct ifaddrs *ifs = NULL; + struct ifaddrs *ifa = NULL; - char saddr[INET6_ADDRSTRLEN] = ""; + char saddr[INET6_ADDRSTRLEN] = ""; - if((getifaddrs(&ifs) == 0) && ifs) { + if ((getifaddrs(&ifs) == 0) && ifs) { - for (ifa = ifs; ifa != NULL; ifa = ifa->ifa_next) { + for (ifa = ifs; ifa != NULL; ifa = ifa->ifa_next) { - if(!(ifa->ifa_flags & IFF_UP)) - continue; + if (!(ifa->ifa_flags & IFF_UP)) + continue; - if(!(ifa->ifa_addr)) - continue; + if (!(ifa->ifa_addr)) + continue; - if (ifa ->ifa_addr->sa_family == AF_INET) { - if(!inet_ntop(AF_INET, &((struct sockaddr_in *) ifa->ifa_addr)->sin_addr, saddr, - INET_ADDRSTRLEN)) - continue; - if(strstr(saddr,"169.254.") == saddr) - continue; - if(!strcmp(saddr,"0.0.0.0")) - continue; - } else if (ifa->ifa_addr->sa_family == AF_INET6) { - if(!inet_ntop(AF_INET6, &((struct sockaddr_in6 *) ifa->ifa_addr)->sin6_addr, saddr, - INET6_ADDRSTRLEN)) - continue; - if(strstr(saddr,"fe80") == saddr) - continue; - if(!strcmp(saddr,"::")) - continue; - } else { - continue; - } + if (ifa->ifa_addr->sa_family == AF_INET) { + if (!inet_ntop(AF_INET, &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr, saddr, INET_ADDRSTRLEN)) + continue; + if (strstr(saddr, "169.254.") == saddr) + continue; + if (!strcmp(saddr, "0.0.0.0")) + continue; + } else if (ifa->ifa_addr->sa_family == AF_INET6) { + if (!inet_ntop(AF_INET6, &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr, saddr, INET6_ADDRSTRLEN)) + continue; + if (strstr(saddr, "fe80") == saddr) + continue; + if (!strcmp(saddr, "::")) + continue; + } else { + continue; + } - add_listener_addr(saddr); + add_listener_addr(saddr); - if(!(ifa->ifa_flags & IFF_LOOPBACK)) - ret++; - } - freeifaddrs(ifs); - } + if (!(ifa->ifa_flags & IFF_LOOPBACK)) + ret++; + } + freeifaddrs(ifs); + } #endif - return ret; + return ret; } -static int make_local_relays_list(int allow_local, int family) -{ - int counter = 0; +static int make_local_relays_list(int allow_local, int family) { + int counter = 0; #if defined(WINDOWS) - DWORD dwRetVal = 0; - // Set the flags to pass to GetAdaptersAddresses - ULONG flags = GAA_FLAG_INCLUDE_PREFIX; + DWORD dwRetVal = 0; + // Set the flags to pass to GetAdaptersAddresses + ULONG flags = GAA_FLAG_INCLUDE_PREFIX; - // default to unspecified address family (both) - ULONG fm = AF_UNSPEC; + // default to unspecified address family (both) + ULONG fm = AF_UNSPEC; - LPVOID lpMsgBuf = NULL; + LPVOID lpMsgBuf = NULL; - PIP_ADAPTER_ADDRESSES pAddresses = NULL; - ULONG outBufLen = 0; - ULONG Iterations = 0; + PIP_ADAPTER_ADDRESSES pAddresses = NULL; + ULONG outBufLen = 0; + ULONG Iterations = 0; - PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL; - PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL; + PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL; + PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL; - // Allocate a 15 KB buffer to start with. - outBufLen = WORKING_BUFFER_SIZE; + // Allocate a 15 KB buffer to start with. + outBufLen = WORKING_BUFFER_SIZE; - do { + do { - pAddresses = (IP_ADAPTER_ADDRESSES *)MALLOC(outBufLen); - if (pAddresses == NULL) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n"); - return -1; - } - - dwRetVal = - GetAdaptersAddresses(fm, flags, NULL, pAddresses, &outBufLen); - - if (dwRetVal == ERROR_BUFFER_OVERFLOW) { - FREE(pAddresses); - pAddresses = NULL; - } - else { - break; - } - - Iterations++; - - } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES)); - - if (dwRetVal == NO_ERROR) { - // If successful, output some information from the data we received - pCurrAddresses = pAddresses; - while (pCurrAddresses) { - /* - printf("\tLength of the IP_ADAPTER_ADDRESS struct: %ld\n", - pCurrAddresses->Length); - printf("\tIfIndex (IPv4 interface): %u\n", pCurrAddresses->IfIndex); - printf("\tAdapter name: %s\n", pCurrAddresses->AdapterName);//*/ - - pUnicast = pCurrAddresses->FirstUnicastAddress; - if (pUnicast != NULL) { - //printf("\tNumber of Unicast Addresses:\n"); - for (; pUnicast != NULL; pUnicast = pUnicast->Next) { - if (!allow_local && (MIB_IF_TYPE_LOOPBACK == pCurrAddresses->IfType)) - continue; - - char saddr[INET6_ADDRSTRLEN] = ""; - if (AF_INET == pUnicast->Address.lpSockaddr->sa_family) // IPV4 - { - if (family != AF_INET) - continue; - if (!inet_ntop(PF_INET, &((struct sockaddr_in*)pUnicast->Address.lpSockaddr)->sin_addr, saddr, INET6_ADDRSTRLEN)) - continue; - if (strstr(saddr, "169.254.") == saddr) - continue; - if (!strcmp(saddr, "0.0.0.0")) - continue; - } - else if (AF_INET6 == pUnicast->Address.lpSockaddr->sa_family) // IPV6 - { - if (family != AF_INET6) - continue; - - if (!inet_ntop(PF_INET6, &((struct sockaddr_in6*)pUnicast->Address.lpSockaddr)->sin6_addr, saddr, INET6_ADDRSTRLEN)) - continue; - if (strstr(saddr, "fe80") == saddr) - continue; - if (!strcmp(saddr, "::")) - continue; - } - else - continue; - - if (add_relay_addr(saddr) > 0) { - counter += 1; - } - } - } - pCurrAddresses = pCurrAddresses->Next; - } + pAddresses = (IP_ADAPTER_ADDRESSES *)MALLOC(outBufLen); + if (pAddresses == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n"); + return -1; } - if (pAddresses) { - FREE(pAddresses); + dwRetVal = GetAdaptersAddresses(fm, flags, NULL, pAddresses, &outBufLen); + + if (dwRetVal == ERROR_BUFFER_OVERFLOW) { + FREE(pAddresses); + pAddresses = NULL; + } else { + break; } + + Iterations++; + + } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES)); + + if (dwRetVal == NO_ERROR) { + // If successful, output some information from the data we received + pCurrAddresses = pAddresses; + while (pCurrAddresses) { + /* + printf("\tLength of the IP_ADAPTER_ADDRESS struct: %ld\n", + pCurrAddresses->Length); + printf("\tIfIndex (IPv4 interface): %u\n", pCurrAddresses->IfIndex); + printf("\tAdapter name: %s\n", pCurrAddresses->AdapterName);//*/ + + pUnicast = pCurrAddresses->FirstUnicastAddress; + if (pUnicast != NULL) { + // printf("\tNumber of Unicast Addresses:\n"); + for (; pUnicast != NULL; pUnicast = pUnicast->Next) { + if (!allow_local && (MIB_IF_TYPE_LOOPBACK == pCurrAddresses->IfType)) + continue; + + char saddr[INET6_ADDRSTRLEN] = ""; + if (AF_INET == pUnicast->Address.lpSockaddr->sa_family) // IPV4 + { + if (family != AF_INET) + continue; + if (!inet_ntop(PF_INET, &((struct sockaddr_in *)pUnicast->Address.lpSockaddr)->sin_addr, saddr, + INET6_ADDRSTRLEN)) + continue; + if (strstr(saddr, "169.254.") == saddr) + continue; + if (!strcmp(saddr, "0.0.0.0")) + continue; + } else if (AF_INET6 == pUnicast->Address.lpSockaddr->sa_family) // IPV6 + { + if (family != AF_INET6) + continue; + + if (!inet_ntop(PF_INET6, &((struct sockaddr_in6 *)pUnicast->Address.lpSockaddr)->sin6_addr, saddr, + INET6_ADDRSTRLEN)) + continue; + if (strstr(saddr, "fe80") == saddr) + continue; + if (!strcmp(saddr, "::")) + continue; + } else + continue; + + if (add_relay_addr(saddr) > 0) { + counter += 1; + } + } + } + pCurrAddresses = pCurrAddresses->Next; + } + } + + if (pAddresses) { + FREE(pAddresses); + } #else - struct ifaddrs * ifs = NULL; - struct ifaddrs * ifa = NULL; + struct ifaddrs *ifs = NULL; + struct ifaddrs *ifa = NULL; - char saddr[INET6_ADDRSTRLEN] = ""; + char saddr[INET6_ADDRSTRLEN] = ""; - getifaddrs(&ifs); + getifaddrs(&ifs); - if (ifs) { - for (ifa = ifs; ifa != NULL; ifa = ifa->ifa_next) { + if (ifs) { + for (ifa = ifs; ifa != NULL; ifa = ifa->ifa_next) { - if(!(ifa->ifa_flags & IFF_UP)) - continue; + if (!(ifa->ifa_flags & IFF_UP)) + continue; - if(!(ifa->ifa_name)) - continue; - if(!(ifa ->ifa_addr)) - continue; + if (!(ifa->ifa_name)) + continue; + if (!(ifa->ifa_addr)) + continue; - if(!allow_local && (ifa->ifa_flags & IFF_LOOPBACK)) - continue; + if (!allow_local && (ifa->ifa_flags & IFF_LOOPBACK)) + continue; - if (ifa ->ifa_addr->sa_family == AF_INET) { + if (ifa->ifa_addr->sa_family == AF_INET) { - if(family != AF_INET) - continue; + if (family != AF_INET) + continue; - if(!inet_ntop(AF_INET, &((struct sockaddr_in *) ifa->ifa_addr)->sin_addr, saddr, - INET_ADDRSTRLEN)) - continue; - if(strstr(saddr,"169.254.") == saddr) - continue; - if(!strcmp(saddr,"0.0.0.0")) - continue; - } else if (ifa->ifa_addr->sa_family == AF_INET6) { + if (!inet_ntop(AF_INET, &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr, saddr, INET_ADDRSTRLEN)) + continue; + if (strstr(saddr, "169.254.") == saddr) + continue; + if (!strcmp(saddr, "0.0.0.0")) + continue; + } else if (ifa->ifa_addr->sa_family == AF_INET6) { - if(family != AF_INET6) - continue; + if (family != AF_INET6) + continue; - if(!inet_ntop(AF_INET6, &((struct sockaddr_in6 *) ifa->ifa_addr)->sin6_addr, saddr, - INET6_ADDRSTRLEN)) - continue; - if(strstr(saddr,"fe80") == saddr) - continue; - if(!strcmp(saddr,"::")) - continue; - } else - continue; + if (!inet_ntop(AF_INET6, &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr, saddr, INET6_ADDRSTRLEN)) + continue; + if (strstr(saddr, "fe80") == saddr) + continue; + if (!strcmp(saddr, "::")) + continue; + } else + continue; - if(add_relay_addr(saddr)>0) { - counter += 1; - } - } - freeifaddrs(ifs); - } + if (add_relay_addr(saddr) > 0) { + counter += 1; + } + } + freeifaddrs(ifs); + } #endif - return counter; + return counter; } -int get_a_local_relay(int family, ioa_addr *relay_addr) -{ - int ret = -1; - int allow_local = 0; +int get_a_local_relay(int family, ioa_addr *relay_addr) { + int ret = -1; + int allow_local = 0; #if defined(WINDOWS) - DWORD dwRetVal = 0; - // Set the flags to pass to GetAdaptersAddresses - ULONG flags = GAA_FLAG_INCLUDE_PREFIX; + DWORD dwRetVal = 0; + // Set the flags to pass to GetAdaptersAddresses + ULONG flags = GAA_FLAG_INCLUDE_PREFIX; - // default to unspecified address family (both) - ULONG fm = AF_UNSPEC; + // default to unspecified address family (both) + ULONG fm = AF_UNSPEC; - LPVOID lpMsgBuf = NULL; + LPVOID lpMsgBuf = NULL; - PIP_ADAPTER_ADDRESSES pAddresses = NULL; - ULONG outBufLen = 0; - ULONG Iterations = 0; + PIP_ADAPTER_ADDRESSES pAddresses = NULL; + ULONG outBufLen = 0; + ULONG Iterations = 0; - PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL; - PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL; + PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL; + PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL; - outBufLen = WORKING_BUFFER_SIZE; + outBufLen = WORKING_BUFFER_SIZE; - do { + do { - pAddresses = (IP_ADAPTER_ADDRESSES *)MALLOC(outBufLen); - if (pAddresses == NULL) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n"); - return -1; - } + pAddresses = (IP_ADAPTER_ADDRESSES *)MALLOC(outBufLen); + if (pAddresses == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n"); + return -1; + } - dwRetVal = - GetAdaptersAddresses(fm, flags, NULL, pAddresses, &outBufLen); + dwRetVal = GetAdaptersAddresses(fm, flags, NULL, pAddresses, &outBufLen); - if (dwRetVal == ERROR_BUFFER_OVERFLOW) { - FREE(pAddresses); - pAddresses = NULL; - } - else { + if (dwRetVal == ERROR_BUFFER_OVERFLOW) { + FREE(pAddresses); + pAddresses = NULL; + } else { + break; + } + + Iterations++; + + } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES)); + + if (dwRetVal == NO_ERROR) { + galr_start: + // If successful, output some information from the data we received + pCurrAddresses = pAddresses; + while (pCurrAddresses) { + pUnicast = pCurrAddresses->FirstUnicastAddress; + if (pUnicast != NULL) { + // printf("\tNumber of Unicast Addresses:\n"); + for (; pUnicast != NULL; pUnicast = pUnicast->Next) { + if (!allow_local && (MIB_IF_TYPE_LOOPBACK == pCurrAddresses->IfType)) + continue; + + char saddr[INET6_ADDRSTRLEN] = ""; + if (AF_INET == pUnicast->Address.lpSockaddr->sa_family) // IPV4 + { + if (family != AF_INET) + continue; + if (!inet_ntop(PF_INET, &((struct sockaddr_in *)pUnicast->Address.lpSockaddr)->sin_addr, saddr, + INET6_ADDRSTRLEN)) + continue; + if (strstr(saddr, "169.254.") == saddr) + continue; + if (!strcmp(saddr, "0.0.0.0")) + continue; + } else if (AF_INET6 == pUnicast->Address.lpSockaddr->sa_family) // IPV6 + { + if (family != AF_INET6) + continue; + + if (!inet_ntop(PF_INET6, &((struct sockaddr_in6 *)pUnicast->Address.lpSockaddr)->sin6_addr, saddr, + INET6_ADDRSTRLEN)) + continue; + if (strstr(saddr, "fe80") == saddr) + continue; + if (!strcmp(saddr, "::")) + continue; + } else + continue; + + if (make_ioa_addr((const uint8_t *)saddr, 0, relay_addr) < 0) { + continue; + } else { + ret = 0; break; + } } - - Iterations++; - - } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES)); - - if (dwRetVal == NO_ERROR) { - galr_start: - // If successful, output some information from the data we received - pCurrAddresses = pAddresses; - while (pCurrAddresses) { - pUnicast = pCurrAddresses->FirstUnicastAddress; - if (pUnicast != NULL) { - //printf("\tNumber of Unicast Addresses:\n"); - for (; pUnicast != NULL; pUnicast = pUnicast->Next) { - if (!allow_local && (MIB_IF_TYPE_LOOPBACK == pCurrAddresses->IfType)) - continue; - - char saddr[INET6_ADDRSTRLEN] = ""; - if (AF_INET == pUnicast->Address.lpSockaddr->sa_family) // IPV4 - { - if (family != AF_INET) - continue; - if (!inet_ntop(PF_INET, &((struct sockaddr_in*)pUnicast->Address.lpSockaddr)->sin_addr, saddr, INET6_ADDRSTRLEN)) - continue; - if (strstr(saddr, "169.254.") == saddr) - continue; - if (!strcmp(saddr, "0.0.0.0")) - continue; - } - else if (AF_INET6 == pUnicast->Address.lpSockaddr->sa_family) // IPV6 - { - if (family != AF_INET6) - continue; - - if (!inet_ntop(PF_INET6, &((struct sockaddr_in6*)pUnicast->Address.lpSockaddr)->sin6_addr, saddr, INET6_ADDRSTRLEN)) - continue; - if (strstr(saddr, "fe80") == saddr) - continue; - if (!strcmp(saddr, "::")) - continue; -} - else - continue; - - if (make_ioa_addr((const uint8_t*)saddr, 0, relay_addr) < 0) { - continue; - } else { - ret = 0; - break; - } - } - } - pCurrAddresses = pCurrAddresses->Next; - } - - if (ret < 0 && !allow_local) { - allow_local = 1; - goto galr_start; - } + } + pCurrAddresses = pCurrAddresses->Next; } - if (pAddresses) { - FREE(pAddresses); + if (ret < 0 && !allow_local) { + allow_local = 1; + goto galr_start; } + } + + if (pAddresses) { + FREE(pAddresses); + } #else - struct ifaddrs * ifs = NULL; + struct ifaddrs *ifs = NULL; - char saddr[INET6_ADDRSTRLEN] = ""; + char saddr[INET6_ADDRSTRLEN] = ""; - getifaddrs(&ifs); + getifaddrs(&ifs); - if (ifs) { + if (ifs) { - galr_start: + galr_start : - { - struct ifaddrs *ifa = NULL; + { + struct ifaddrs *ifa = NULL; - for (ifa = ifs; ifa != NULL ; ifa = ifa->ifa_next) { + for (ifa = ifs; ifa != NULL; ifa = ifa->ifa_next) { - if (!(ifa->ifa_flags & IFF_UP)) - continue; + if (!(ifa->ifa_flags & IFF_UP)) + continue; - if (!(ifa->ifa_name)) - continue; - if (!(ifa->ifa_addr)) - continue; + if (!(ifa->ifa_name)) + continue; + if (!(ifa->ifa_addr)) + continue; - if (!allow_local && (ifa->ifa_flags & IFF_LOOPBACK)) - continue; + if (!allow_local && (ifa->ifa_flags & IFF_LOOPBACK)) + continue; - if (ifa->ifa_addr->sa_family == AF_INET) { + if (ifa->ifa_addr->sa_family == AF_INET) { - if (family != AF_INET) - continue; + if (family != AF_INET) + continue; - if (!inet_ntop(AF_INET, - &((struct sockaddr_in *) ifa->ifa_addr)->sin_addr, - saddr, INET_ADDRSTRLEN)) - continue; - if (strstr(saddr, "169.254.") == saddr) - continue; - if (!strcmp(saddr, "0.0.0.0")) - continue; - } else if (ifa->ifa_addr->sa_family == AF_INET6) { + if (!inet_ntop(AF_INET, &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr, saddr, INET_ADDRSTRLEN)) + continue; + if (strstr(saddr, "169.254.") == saddr) + continue; + if (!strcmp(saddr, "0.0.0.0")) + continue; + } else if (ifa->ifa_addr->sa_family == AF_INET6) { - if (family != AF_INET6) - continue; + if (family != AF_INET6) + continue; - if (!inet_ntop(AF_INET6, - &((struct sockaddr_in6 *) ifa->ifa_addr)->sin6_addr, - saddr, INET6_ADDRSTRLEN)) - continue; - if (strstr(saddr, "fe80") == saddr) - continue; - if (!strcmp(saddr, "::")) - continue; - } else - continue; + if (!inet_ntop(AF_INET6, &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr, saddr, INET6_ADDRSTRLEN)) + continue; + if (strstr(saddr, "fe80") == saddr) + continue; + if (!strcmp(saddr, "::")) + continue; + } else + continue; - if (make_ioa_addr((const uint8_t*) saddr, 0, relay_addr) < 0) { - continue; - } else { - ret = 0; - break; - } - } - } + if (make_ioa_addr((const uint8_t *)saddr, 0, relay_addr) < 0) { + continue; + } else { + ret = 0; + break; + } + } + } - if(ret<0 && !allow_local) { - allow_local = 1; - goto galr_start; - } + if (ret < 0 && !allow_local) { + allow_local = 1; + goto galr_start; + } - freeifaddrs(ifs); - } - return -1; + freeifaddrs(ifs); + } + return -1; #endif } ////////////////////////////////////////////////// -static char Usage[] = "Usage: turnserver [options]\n" -"Options:\n" -" -d, --listening-device Listener interface device (NOT RECOMMENDED. Optional, Linux only).\n" -" -p, --listening-port TURN listener port (Default: 3478).\n" -" Note: actually, TLS & DTLS sessions can connect to the \"plain\" TCP & UDP port(s), too,\n" -" if allowed by configuration.\n" -" --tls-listening-port TURN listener port for TLS & DTLS listeners\n" -" (Default: 5349).\n" -" Note: actually, \"plain\" TCP & UDP sessions can connect to the TLS & DTLS port(s), too,\n" -" if allowed by configuration. The TURN server\n" -" \"automatically\" recognizes the type of traffic. Actually, two listening\n" -" endpoints (the \"plain\" one and the \"tls\" one) are equivalent in terms of\n" -" functionality; but we keep both endpoints to satisfy the RFC 5766 specs.\n" -" For secure TCP connections, we currently support SSL version 3 and\n" -" TLS versions 1.0, 1.1 and 1.2. For secure UDP connections, we support\n" -" DTLS version 1.\n" -" --alt-listening-port Alternative listening port for STUN CHANGE_REQUEST (in RFC 5780 sense, \n" -" or in old RFC 3489 sense, default is \"listening port plus one\").\n" -" --alt-tls-listening-port Alternative listening port for TLS and DTLS,\n" -" the default is \"TLS/DTLS port plus one\".\n" -" --tcp-proxy-port Support connections from TCP loadbalancer on this port. The loadbalancer should\n" -" use the binary proxy protocol (https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)\n" -" -L, --listening-ip Listener IP address of relay server. Multiple listeners can be specified.\n" -" --aux-server Auxiliary STUN/TURN server listening endpoint.\n" -" Auxiliary servers do not have alternative ports and\n" -" they do not support RFC 5780 functionality (CHANGE REQUEST).\n" -" Valid formats are 1.2.3.4:5555 for IPv4 and [1:2::3:4]:5555 for IPv6.\n" -" --udp-self-balance (recommended for older Linuxes only) Automatically balance UDP traffic\n" -" over auxiliary servers (if configured).\n" -" The load balancing is using the ALTERNATE-SERVER mechanism.\n" -" The TURN client must support 300 ALTERNATE-SERVER response for this functionality.\n" -" -i, --relay-device Relay interface device for relay sockets (NOT RECOMMENDED. Optional, Linux only).\n" -" -E, --relay-ip Relay address (the local IP address that will be used to relay the\n" -" packets to the peer).\n" -" Multiple relay addresses may be used.\n" -" The same IP(s) can be used as both listening IP(s) and relay IP(s).\n" -" If no relay IP(s) specified, then the turnserver will apply the default\n" -" policy: it will decide itself which relay addresses to be used, and it\n" -" will always be using the client socket IP address as the relay IP address\n" -" of the TURN session (if the requested relay address family is the same\n" -" as the family of the client socket).\n" -" -X, --external-ip TURN Server public/private address mapping, if the server is behind NAT.\n" -" In that situation, if a -X is used in form \"-X ip\" then that ip will be reported\n" -" as relay IP address of all allocations. This scenario works only in a simple case\n" -" when one single relay address is be used, and no STUN CHANGE_REQUEST\n" -" functionality is required.\n" -" That single relay address must be mapped by NAT to the 'external' IP.\n" -" For that 'external' IP, NAT must forward ports directly (relayed port 12345\n" -" must be always mapped to the same 'external' port 12345).\n" -" In more complex case when more than one IP address is involved,\n" -" that option must be used several times in the command line, each entry must\n" -" have form \"-X public-ip/private-ip\", to map all involved addresses.\n" -" --allow-loopback-peers Allow peers on the loopback addresses (127.x.x.x and ::1).\n" -" --no-multicast-peers Disallow peers on well-known broadcast addresses (224.0.0.0 and above, and FFXX:*).\n" -" -m, --relay-threads Number of relay threads to handle the established connections\n" -" (in addition to authentication thread and the listener thread).\n" -" If explicitly set to 0 then application runs in single-threaded mode.\n" -" If not set then a default OS-dependent optimal algorithm will be employed.\n" -" The default thread number is the number of CPUs.\n" -" In older systems (pre-Linux 3.9) the number of UDP relay threads always equals\n" -" the number of listening endpoints (unless -m 0 is set).\n" -" --min-port Lower bound of the UDP port range for relay endpoints allocation.\n" -" Default value is 49152, according to RFC 5766.\n" -" --max-port Upper bound of the UDP port range for relay endpoints allocation.\n" -" Default value is 65535, according to RFC 5766.\n" -" -v, --verbose 'Moderate' verbose mode.\n" -" -V, --Verbose Extra verbose mode, very annoying (for debug purposes only).\n" -" -o, --daemon Start process as daemon (detach from current shell).\n" -" --no-software-attribute Production mode: hide the software version (formerly --prod).\n" -" -f, --fingerprint Use fingerprints in the TURN messages.\n" -" -a, --lt-cred-mech Use the long-term credential mechanism.\n" -" -z, --no-auth Do not use any credential mechanism, allow anonymous access.\n" -" -u, --user User account, in form 'username:password', for long-term credentials.\n" -" Cannot be used with TURN REST API.\n" -" -r, --realm The default realm to be used for the users when no explicit\n" -" origin/realm relationship was found in the database.\n" -" Must be used with long-term credentials \n" -" mechanism or with TURN REST API.\n" -" --check-origin-consistency The flag that sets the origin consistency check:\n" -" across the session, all requests must have the same\n" -" main ORIGIN attribute value (if the ORIGIN was\n" -" initially used by the session).\n" -" -q, --user-quota Per-user allocation quota: how many concurrent allocations a user can create.\n" -" This option can also be set through the database, for a particular realm.\n" -" -Q, --total-quota Total allocations quota: global limit on concurrent allocations.\n" -" This option can also be set through the database, for a particular realm.\n" -" -s, --max-bps Default max bytes-per-second bandwidth a TURN session is allowed to handle\n" -" (input and output network streams are treated separately). Anything above\n" -" that limit will be dropped or temporary suppressed\n" -" (within the available buffer limits).\n" -" This option can also be set through the database, for a particular realm.\n" -" -B, --bps-capacity Maximum server capacity.\n" -" Total bytes-per-second bandwidth the TURN server is allowed to allocate\n" -" for the sessions, combined (input and output network streams are treated separately).\n" -" -c Configuration file name (default - turnserver.conf).\n" +static char Usage[] = + "Usage: turnserver [options]\n" + "Options:\n" + " -d, --listening-device Listener interface device (NOT RECOMMENDED. Optional, Linux " + "only).\n" + " -p, --listening-port TURN listener port (Default: 3478).\n" + " Note: actually, TLS & DTLS sessions can connect to the \"plain\" TCP & " + "UDP port(s), too,\n" + " if allowed by configuration.\n" + " --tls-listening-port TURN listener port for TLS & DTLS listeners\n" + " (Default: 5349).\n" + " Note: actually, \"plain\" TCP & UDP sessions can connect to the TLS & " + "DTLS port(s), too,\n" + " if allowed by configuration. The TURN server\n" + " \"automatically\" recognizes the type of traffic. Actually, two " + "listening\n" + " endpoints (the \"plain\" one and the \"tls\" one) are equivalent in " + "terms of\n" + " functionality; but we keep both endpoints to satisfy the RFC 5766 " + "specs.\n" + " For secure TCP connections, we currently support SSL version 3 and\n" + " TLS versions 1.0, 1.1 and 1.2. For secure UDP connections, we support\n" + " DTLS version 1.\n" + " --alt-listening-port Alternative listening port for STUN CHANGE_REQUEST (in RFC " + "5780 sense, \n" + " or in old RFC 3489 sense, default is \"listening port plus " + "one\").\n" + " --alt-tls-listening-port Alternative listening port for TLS and DTLS,\n" + " the default is \"TLS/DTLS port plus one\".\n" + " --tcp-proxy-port Support connections from TCP loadbalancer on this port. The " + "loadbalancer should\n" + " use the binary proxy protocol " + "(https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)\n" + " -L, --listening-ip Listener IP address of relay server. Multiple listeners can be " + "specified.\n" + " --aux-server Auxiliary STUN/TURN server listening endpoint.\n" + " Auxiliary servers do not have alternative ports and\n" + " they do not support RFC 5780 functionality (CHANGE REQUEST).\n" + " Valid formats are 1.2.3.4:5555 for IPv4 and [1:2::3:4]:5555 for IPv6.\n" + " --udp-self-balance (recommended for older Linuxes only) Automatically balance UDP " + "traffic\n" + " over auxiliary servers (if configured).\n" + " The load balancing is using the ALTERNATE-SERVER mechanism.\n" + " The TURN client must support 300 ALTERNATE-SERVER response for this " + "functionality.\n" + " -i, --relay-device Relay interface device for relay sockets (NOT RECOMMENDED. " + "Optional, Linux only).\n" + " -E, --relay-ip Relay address (the local IP address that will be used to relay " + "the\n" + " packets to the peer).\n" + " Multiple relay addresses may be used.\n" + " The same IP(s) can be used as both listening IP(s) and relay IP(s).\n" + " If no relay IP(s) specified, then the turnserver will apply the " + "default\n" + " policy: it will decide itself which relay addresses to be used, and " + "it\n" + " will always be using the client socket IP address as the relay IP " + "address\n" + " of the TURN session (if the requested relay address family is the " + "same\n" + " as the family of the client socket).\n" + " -X, --external-ip TURN Server public/private address mapping, if the server is " + "behind NAT.\n" + " In that situation, if a -X is used in form \"-X ip\" then that ip will " + "be reported\n" + " as relay IP address of all allocations. This scenario works only in a " + "simple case\n" + " when one single relay address is be used, and no STUN CHANGE_REQUEST\n" + " functionality is required.\n" + " That single relay address must be mapped by NAT to the 'external' IP.\n" + " For that 'external' IP, NAT must forward ports directly (relayed port " + "12345\n" + " must be always mapped to the same 'external' port 12345).\n" + " In more complex case when more than one IP address is involved,\n" + " that option must be used several times in the command line, each entry " + "must\n" + " have form \"-X public-ip/private-ip\", to map all involved addresses.\n" + " --allow-loopback-peers Allow peers on the loopback addresses (127.x.x.x and ::1).\n" + " --no-multicast-peers Disallow peers on well-known broadcast addresses (224.0.0.0 " + "and above, and FFXX:*).\n" + " -m, --relay-threads Number of relay threads to handle the established connections\n" + " (in addition to authentication thread and the listener thread).\n" + " If explicitly set to 0 then application runs in single-threaded mode.\n" + " If not set then a default OS-dependent optimal algorithm will be " + "employed.\n" + " The default thread number is the number of CPUs.\n" + " In older systems (pre-Linux 3.9) the number of UDP relay threads " + "always equals\n" + " the number of listening endpoints (unless -m 0 is set).\n" + " --min-port Lower bound of the UDP port range for relay endpoints " + "allocation.\n" + " Default value is 49152, according to RFC 5766.\n" + " --max-port Upper bound of the UDP port range for relay endpoints " + "allocation.\n" + " Default value is 65535, according to RFC 5766.\n" + " -v, --verbose 'Moderate' verbose mode.\n" + " -V, --Verbose Extra verbose mode, very annoying (for debug purposes only).\n" + " -o, --daemon Start process as daemon (detach from current shell).\n" + " --no-software-attribute Production mode: hide the software version (formerly --prod).\n" + " -f, --fingerprint Use fingerprints in the TURN messages.\n" + " -a, --lt-cred-mech Use the long-term credential mechanism.\n" + " -z, --no-auth Do not use any credential mechanism, allow anonymous access.\n" + " -u, --user User account, in form 'username:password', for long-term " + "credentials.\n" + " Cannot be used with TURN REST API.\n" + " -r, --realm The default realm to be used for the users when no explicit\n" + " origin/realm relationship was found in the database.\n" + " Must be used with long-term credentials \n" + " mechanism or with TURN REST API.\n" + " --check-origin-consistency The flag that sets the origin consistency check:\n" + " across the session, all requests must have the same\n" + " main ORIGIN attribute value (if the ORIGIN was\n" + " initially used by the session).\n" + " -q, --user-quota Per-user allocation quota: how many concurrent allocations a user can " + "create.\n" + " This option can also be set through the database, for a particular " + "realm.\n" + " -Q, --total-quota Total allocations quota: global limit on concurrent allocations.\n" + " This option can also be set through the database, for a particular " + "realm.\n" + " -s, --max-bps Default max bytes-per-second bandwidth a TURN session is " + "allowed to handle\n" + " (input and output network streams are treated separately). Anything " + "above\n" + " that limit will be dropped or temporary suppressed\n" + " (within the available buffer limits).\n" + " This option can also be set through the database, for a particular " + "realm.\n" + " -B, --bps-capacity Maximum server capacity.\n" + " Total bytes-per-second bandwidth the TURN server is allowed to " + "allocate\n" + " for the sessions, combined (input and output network streams are " + "treated separately).\n" + " -c Configuration file name (default - turnserver.conf).\n" #if !defined(TURN_NO_SQLITE) -" -b, , --db, --userdb SQLite database file name; default - /var/db/turndb or\n" -" /usr/local/var/db/turndb or /var/lib/turn/turndb.\n" + " -b, , --db, --userdb SQLite database file name; default - /var/db/turndb or\n" + " /usr/local/var/db/turndb or /var/lib/turn/turndb.\n" #endif #if !defined(TURN_NO_PQ) -" -e, --psql-userdb, --sql-userdb PostgreSQL database connection string, if used (default - empty, no PostreSQL DB used).\n" -" This database can be used for long-term credentials mechanism users,\n" -" and it can store the secret value(s) for secret-based timed authentication in TURN REST API.\n" -" See http://www.postgresql.org/docs/8.4/static/libpq-connect.html for 8.x PostgreSQL\n" -" versions format, see \n" -" http://www.postgresql.org/docs/9.2/static/libpq-connect.html#LIBPQ-CONNSTRING\n" -" for 9.x and newer connection string formats.\n" + " -e, --psql-userdb, --sql-userdb PostgreSQL database connection string, if used (default - " + "empty, no PostreSQL DB used).\n" + " This database can be used for long-term credentials mechanism users,\n" + " and it can store the secret value(s) for secret-based timed " + "authentication in TURN REST API.\n" + " See http://www.postgresql.org/docs/8.4/static/libpq-connect.html for " + "8.x PostgreSQL\n" + " versions format, see \n" + " " + "http://www.postgresql.org/docs/9.2/static/libpq-connect.html#LIBPQ-CONNSTRING\n" + " for 9.x and newer connection string formats.\n" #endif #if !defined(TURN_NO_MYSQL) -" -M, --mysql-userdb MySQL database connection string, if used (default - empty, no MySQL DB used).\n" -" This database can be used for long-term credentials mechanism users,\n" -" and it can store the secret value(s) for secret-based timed authentication in TURN REST API.\n" -" The connection string my be space-separated list of parameters:\n" -" \"host= dbname= user= \\\n password= port= connect_timeout= read_timeout=\".\n\n" -" The connection string parameters for the secure communications (SSL):\n" -" ca, capath, cert, key, cipher\n" -" (see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the\n" -" command options description).\n\n" -" All connection-string parameters are optional.\n\n" -" --secret-key-file This is the file path which contain secret key of aes encryption while using MySQL password encryption.\n" -" If you want to use in the MySQL connection string the password in encrypted format,\n" -" then set in this option the file path of the secret key. The key which is used to encrypt MySQL password.\n" -" Warning: If this option is set, then MySQL password must be set in \"mysql-userdb\" option in encrypted format!\n" -" If you want to use cleartext password then do not set this option!\n" + " -M, --mysql-userdb MySQL database connection string, if used (default - empty, no " + "MySQL DB used).\n" + " This database can be used for long-term credentials mechanism users,\n" + " and it can store the secret value(s) for secret-based timed " + "authentication in TURN REST API.\n" + " The connection string my be space-separated list of parameters:\n" + " \"host= dbname= user= " + "\\\n password= port= " + "connect_timeout= read_timeout=\".\n\n" + " The connection string parameters for the secure communications (SSL):\n" + " ca, capath, cert, key, cipher\n" + " (see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the\n" + " command options description).\n\n" + " All connection-string parameters are optional.\n\n" + " --secret-key-file This is the file path which contain secret key of aes encryption while " + "using MySQL password encryption.\n" + " If you want to use in the MySQL connection string the password in " + "encrypted format,\n" + " then set in this option the file path of the secret key. The key which " + "is used to encrypt MySQL password.\n" + " Warning: If this option is set, then MySQL password must be set in " + "\"mysql-userdb\" option in encrypted format!\n" + " If you want to use cleartext password then do not set this option!\n" #endif #if !defined(TURN_NO_MONGO) -" -J, --mongo-userdb MongoDB connection string, if used (default - empty, no MongoDB used).\n" -" This database can be used for long-term credentials mechanism users,\n" -" and it can store the secret value(s) for secret-based timed authentication in TURN REST API.\n" + " -J, --mongo-userdb MongoDB connection string, if used (default - empty, no " + "MongoDB used).\n" + " This database can be used for long-term credentials mechanism users,\n" + " and it can store the secret value(s) for secret-based timed " + "authentication in TURN REST API.\n" #endif #if !defined(TURN_NO_HIREDIS) -" -N, --redis-userdb Redis user database connection string, if used (default - empty, no Redis DB used).\n" -" This database can be used for long-term credentials mechanism users,\n" -" and it can store the secret value(s) for secret-based timed authentication in TURN REST API.\n" -" The connection string my be space-separated list of parameters:\n" -" \"host= dbname= \\\n password= port= connect_timeout=\".\n\n" -" All connection-string parameters are optional.\n\n" -" -O, --redis-statsdb Redis status and statistics database connection string, if used \n" -" (default - empty, no Redis stats DB used).\n" -" This database keeps allocations status information, and it can be also used for publishing\n" -" and delivering traffic and allocation event notifications.\n" -" The connection string has the same parameters as redis-userdb connection string.\n" + " -N, --redis-userdb Redis user database connection string, if used (default - " + "empty, no Redis DB used).\n" + " This database can be used for long-term credentials mechanism users,\n" + " and it can store the secret value(s) for secret-based timed " + "authentication in TURN REST API.\n" + " The connection string my be space-separated list of parameters:\n" + " \"host= dbname= \\\n " + " password= port= " + "connect_timeout=\".\n\n" + " All connection-string parameters are optional.\n\n" + " -O, --redis-statsdb Redis status and statistics database connection string, if " + "used \n" + " (default - empty, no Redis stats DB used).\n" + " This database keeps allocations status information, and it can be also " + "used for publishing\n" + " and delivering traffic and allocation event notifications.\n" + " The connection string has the same parameters as redis-userdb " + "connection string.\n" #endif #if !defined(TURN_NO_PROMETHEUS) -" --prometheus Enable prometheus metrics. It is disabled by default. If it is enabled it will listen on port 9641 under the path /metrics\n" -" also the path / on this port can be used as a health check\n" -" --prometheus-port Prometheus metrics port (Default: 9641).\n" -" --prometheus-username-labels When metrics are enabled, add labels with client usernames.\n" + " --prometheus Enable prometheus metrics. It is disabled by default. If it is " + "enabled it will listen on port 9641 under the path /metrics\n" + " also the path / on this port can be used as a health check\n" + " --prometheus-port Prometheus metrics port (Default: 9641).\n" + " --prometheus-username-labels When metrics are enabled, add labels with client usernames.\n" #endif -" --use-auth-secret TURN REST API flag.\n" -" Flag that sets a special authorization option that is based upon authentication secret\n" -" (TURN Server REST API, see https://github.com/coturn/coturn/blob/master/README.turnserver).\n" -" This option is used with timestamp.\n" -" --static-auth-secret 'Static' authentication secret value (a string) for TURN REST API only.\n" -" If not set, then the turn server will try to use the 'dynamic' value\n" -" in turn_secret table in user database (if present).\n" -" That database value can be changed on-the-fly\n" -" by a separate program, so this is why it is 'dynamic'.\n" -" Multiple shared secrets can be used (both in the database and in the \"static\" fashion).\n" -" --no-auth-pings Disable periodic health checks to 'dynamic' auth secret tables.\n" -" --no-dynamic-ip-list Do not use dynamic allowed/denied peer ip list.\n" -" --no-dynamic-realms Do not use dynamic realm assignment and options.\n" -" --server-name Server name used for\n" -" the oAuth authentication purposes.\n" -" The default value is the realm name.\n" -" --oauth Support oAuth authentication.\n" -" -n Do not use configuration file, take all parameters from the command line only.\n" -" --cert Certificate file, PEM format. Same file search rules\n" -" applied as for the configuration file.\n" -" If both --no-tls and --no_dtls options\n" -" are specified, then this parameter is not needed.\n" -" --pkey Private key file, PEM format. Same file search rules\n" -" applied as for the configuration file.\n" -" If both --no-tls and --no-dtls options\n" -" --pkey-pwd If the private key file is encrypted, then this password to be used.\n" -" --cipher-list <\"cipher-string\"> Allowed OpenSSL cipher list for TLS/DTLS connections.\n" -" Default value is \"DEFAULT\".\n" -" --CA-file CA file in OpenSSL format.\n" -" Forces TURN server to verify the client SSL certificates.\n" -" By default, no CA is set and no client certificate check is performed.\n" -" --ec-curve-name Curve name for EC ciphers, if supported by OpenSSL\n" -" library (TLS and DTLS). The default value is prime256v1,\n" -" if pre-OpenSSL 1.0.2 is used. With OpenSSL 1.0.2+,\n" -" an optimal curve will be automatically calculated, if not defined\n" -" by this option.\n" -" --dh566 Use 566 bits predefined DH TLS key. Default size of the predefined key is 2066.\n" -" --dh1066 Use 1066 bits predefined DH TLS key. Default size of the predefined key is 2066.\n" -" --dh-file Use custom DH TLS key, stored in PEM format in the file.\n" -" Flags --dh566 and --dh1066 are ignored when the DH key is taken from a file.\n" -" --no-tlsv1 Set TLSv1_1/DTLSv1.2 as a minimum supported protocol version.\n" -" With openssl-1.0.2 and below, do not allow TLSv1/DTLSv1 protocols.\n" -" --no-tlsv1_1 Set TLSv1_2/DTLSv1.2 as a minimum supported protocol version.\n" -" With openssl-1.0.2 and below, do not allow TLSv1.1 protocol.\n" -" --no-tlsv1_2 Set TLSv1_3/DTLSv1.2 as a minimum supported protocol version.\n" -" With openssl-1.0.2 and below, do not allow TLSv1.2/DTLSv1.2 protocols.\n" -" --no-udp Do not start UDP client listeners.\n" -" --no-tcp Do not start TCP client listeners.\n" -" --no-tls Do not start TLS client listeners.\n" -" --no-dtls Do not start DTLS client listeners.\n" -" --no-udp-relay Do not allow UDP relay endpoints, use only TCP relay option.\n" -" --no-tcp-relay Do not allow TCP relay endpoints, use only UDP relay options.\n" -" -l, --log-file Option to set the full path name of the log file.\n" -" By default, the turnserver tries to open a log file in\n" -" /var/log/turnserver/, /var/log, /var/tmp, /tmp and . (current) directories\n" -" (which open operation succeeds first that file will be used).\n" -" With this option you can set the definite log file name.\n" -" The special names are \"stdout\" and \"-\" - they will force everything\n" -" to the stdout; and \"syslog\" name will force all output to the syslog.\n" -" --no-stdout-log Flag to prevent stdout log messages.\n" -" By default, all log messages are going to both stdout and to\n" -" a log file. With this option everything will be going to the log file only\n" -" (unless the log file itself is stdout).\n" -" --syslog Output all log information into the system log (syslog), do not use the file output.\n" -" --syslog-facility Set syslog facility for syslog messages. Default is ''.\n" -" --simple-log This flag means that no log file rollover will be used, and the log file\n" -" name will be constructed as-is, without PID and date appendage.\n" -" This option can be used, for example, together with the logrotate tool.\n" -" --new-log-timestamp Enable full ISO-8601 timestamp in all logs.\n" -" --new-log-timestamp-format Set timestamp format (in strftime(1) format). Depends on --new-log-timestamp to be enabled.\n" -" --log-binding Log STUN binding request. It is now disabled by default to avoid DoS attacks.\n" -" --stale-nonce[=] Use extra security with nonce value having limited lifetime (default 600 secs).\n" -" --max-allocate-lifetime Set the maximum value for the allocation lifetime. Default to 3600 secs.\n" -" --channel-lifetime Set the lifetime for channel binding, default to 600 secs.\n" -" This value MUST not be changed for production purposes.\n" -" --permission-lifetime Set the value for the lifetime of the permission. Default to 300 secs.\n" -" This MUST not be changed for production purposes.\n" -" -S, --stun-only Option to set standalone STUN operation only, all TURN requests will be ignored.\n" -" --no-stun Option to suppress STUN functionality, only TURN requests will be processed.\n" -" --alternate-server Set the TURN server to redirect the allocate requests (UDP and TCP services).\n" -" Multiple alternate-server options can be set for load balancing purposes.\n" -" See the docs for more information.\n" -" --tls-alternate-server Set the TURN server to redirect the allocate requests (DTLS and TLS services).\n" -" Multiple alternate-server options can be set for load balancing purposes.\n" -" See the docs for more information.\n" -" -C, --rest-api-separator This is the timestamp/username separator symbol (character) in TURN REST API.\n" -" The default value is ':'.\n" -" --max-allocate-timeout= Max time, in seconds, allowed for full allocation establishment. Default is 60.\n" -" --allowed-peer-ip= Specifies an ip or range of ips that are explicitly allowed to connect to the \n" -" turn server. Multiple allowed-peer-ip can be set.\n" -" --denied-peer-ip= Specifies an ip or range of ips that are not allowed to connect to the turn server.\n" -" Multiple denied-peer-ip can be set.\n" -" --pidfile <\"pid-file-name\"> File name to store the pid of the process.\n" -" Default is /var/run/turnserver.pid (if superuser account is used) or\n" -" /var/tmp/turnserver.pid .\n" -" --acme-redirect Redirect ACME, i.e. HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to '$1'.\n" -" Default is '', i.e. no special handling for such requests.\n" -" --secure-stun Require authentication of the STUN Binding request.\n" -" By default, the clients are allowed anonymous access to the STUN Binding functionality.\n" -" --proc-user User name to run the turnserver process.\n" -" After the initialization, the turnserver process\n" -" will make an attempt to change the current user ID to that user.\n" -" --proc-group Group name to run the turnserver process.\n" -" After the initialization, the turnserver process\n" -" will make an attempt to change the current group ID to that group.\n" -" --mobility Mobility with ICE (MICE) specs support.\n" -" -K, --keep-address-family Deprecated in favor of --allocation-default-address-family!!\n" -" TURN server allocates address family according TURN\n" -" Client <=> Server communication address family.\n" -" !! It breaks RFC6156 section-4.2 (violates default IPv4) !!\n" -" -A --allocation-default-address-family= Default is IPv4\n" -" TURN server allocates address family according TURN client requested address family. \n" -" If address family is not requested explicitly by client, then it falls back to this default.\n" -" The standard RFC explicitly define actually that this default must be IPv4,\n" -" so use other option values with care!\n" -" --no-cli Turn OFF the CLI support. By default it is always ON.\n" -" --cli-ip= Local system IP address to be used for CLI server endpoint. Default value\n" -" is 127.0.0.1.\n" -" --cli-port= CLI server port. Default is 5766.\n" -" --cli-password= CLI access password. Default is empty (no password).\n" -" For the security reasons, it is recommended to use the encrypted\n" -" for of the password (see the -P command in the turnadmin utility).\n" -" The dollar signs in the encrypted form must be escaped.\n" -" --web-admin Enable Turn Web-admin support. By default it is disabled.\n" -" --web-admin-ip= Local system IP address to be used for Web-admin server endpoint. Default value\n" -" is 127.0.0.1.\n" -" --web-admin-port= Web-admin server port. Default is 8080.\n" -" --web-admin-listen-on-workers Enable for web-admin server to listens on STUN/TURN workers STUN/TURN ports.\n" -" By default it is disabled for security reasons!\n" -" (This behavior used to be the default behavior, and was enabled by default.)\n" -" --server-relay Server relay. NON-STANDARD AND DANGEROUS OPTION. Only for those applications\n" -" when we want to run server applications on the relay endpoints.\n" -" This option eliminates the IP permissions check on the packets\n" -" incoming to the relay endpoints.\n" -" --cli-max-output-sessions Maximum number of output sessions in ps CLI command.\n" -" This value can be changed on-the-fly in CLI. The default value is 256.\n" -" --ne=[1|2|3] Set network engine type for the process (for internal purposes).\n" -" --no-rfc5780 Disable RFC5780 (NAT behavior discovery).\n" -" Originally, if there are more than one listener address from the same\n" -" address family, then by default the NAT behavior discovery feature enabled.\n" -" This option disables this original behavior, because the NAT behavior discovery\n" -" adds attributes to response, and this increase the possibility of an amplification attack.\n" -" Strongly encouraged to use this option to decrease gain factor in STUN binding responses.\n" -" --no-stun-backward-compatibility Disable handling old STUN Binding requests and disable MAPPED-ADDRESS attribute\n" -" in binding response (use only the XOR-MAPPED-ADDRESS).\n" -" --response-origin-only-with-rfc5780 Only send RESPONSE-ORIGIN attribute in binding response if RFC5780 is enabled.\n" -" --version Print version (and exit).\n" -" -h Help\n" -"\n"; + " --use-auth-secret TURN REST API flag.\n" + " Flag that sets a special authorization option that is based upon " + "authentication secret\n" + " (TURN Server REST API, see " + "https://github.com/coturn/coturn/blob/master/README.turnserver).\n" + " This option is used with timestamp.\n" + " --static-auth-secret 'Static' authentication secret value (a string) for TURN REST " + "API only.\n" + " If not set, then the turn server will try to use the 'dynamic' value\n" + " in turn_secret table in user database (if present).\n" + " That database value can be changed on-the-fly\n" + " by a separate program, so this is why it is 'dynamic'.\n" + " Multiple shared secrets can be used (both in the database and in the " + "\"static\" fashion).\n" + " --no-auth-pings Disable periodic health checks to 'dynamic' auth secret tables.\n" + " --no-dynamic-ip-list Do not use dynamic allowed/denied peer ip list.\n" + " --no-dynamic-realms Do not use dynamic realm assignment and options.\n" + " --server-name Server name used for\n" + " the oAuth authentication purposes.\n" + " The default value is the realm name.\n" + " --oauth Support oAuth authentication.\n" + " -n Do not use configuration file, take all parameters from the " + "command line only.\n" + " --cert Certificate file, PEM format. Same file search rules\n" + " applied as for the configuration file.\n" + " If both --no-tls and --no_dtls options\n" + " are specified, then this parameter is not needed.\n" + " --pkey Private key file, PEM format. Same file search rules\n" + " applied as for the configuration file.\n" + " If both --no-tls and --no-dtls options\n" + " --pkey-pwd If the private key file is encrypted, then this password to be " + "used.\n" + " --cipher-list <\"cipher-string\"> Allowed OpenSSL cipher list for TLS/DTLS connections.\n" + " Default value is \"DEFAULT\".\n" + " --CA-file CA file in OpenSSL format.\n" + " Forces TURN server to verify the client SSL certificates.\n" + " By default, no CA is set and no client certificate check is " + "performed.\n" + " --ec-curve-name Curve name for EC ciphers, if supported by OpenSSL\n" + " library (TLS and DTLS). The default value is prime256v1,\n" + " if pre-OpenSSL 1.0.2 is used. With OpenSSL 1.0.2+,\n" + " an optimal curve will be automatically calculated, if not defined\n" + " by this option.\n" + " --dh566 Use 566 bits predefined DH TLS key. Default size of the predefined key " + "is 2066.\n" + " --dh1066 Use 1066 bits predefined DH TLS key. Default size of the predefined " + "key is 2066.\n" + " --dh-file Use custom DH TLS key, stored in PEM format in the file.\n" + " Flags --dh566 and --dh1066 are ignored when the DH key is taken from a " + "file.\n" + " --no-tlsv1 Set TLSv1_1/DTLSv1.2 as a minimum supported protocol version.\n" + " With openssl-1.0.2 and below, do not allow " + "TLSv1/DTLSv1 protocols.\n" + " --no-tlsv1_1 Set TLSv1_2/DTLSv1.2 as a minimum supported protocol version.\n" + " With openssl-1.0.2 and below, do not allow TLSv1.1 " + "protocol.\n" + " --no-tlsv1_2 Set TLSv1_3/DTLSv1.2 as a minimum supported protocol version.\n" + " With openssl-1.0.2 and below, do not allow " + "TLSv1.2/DTLSv1.2 protocols.\n" + " --no-udp Do not start UDP client listeners.\n" + " --no-tcp Do not start TCP client listeners.\n" + " --no-tls Do not start TLS client listeners.\n" + " --no-dtls Do not start DTLS client listeners.\n" + " --no-udp-relay Do not allow UDP relay endpoints, use only TCP relay option.\n" + " --no-tcp-relay Do not allow TCP relay endpoints, use only UDP relay options.\n" + " -l, --log-file Option to set the full path name of the log file.\n" + " By default, the turnserver tries to open a log file in\n" + " /var/log/turnserver/, /var/log, /var/tmp, /tmp and . (current) " + "directories\n" + " (which open operation succeeds first that file will be used).\n" + " With this option you can set the definite log file name.\n" + " The special names are \"stdout\" and \"-\" - they will force " + "everything\n" + " to the stdout; and \"syslog\" name will force all output to the " + "syslog.\n" + " --no-stdout-log Flag to prevent stdout log messages.\n" + " By default, all log messages are going to both stdout and to\n" + " a log file. With this option everything will be going to the log file " + "only\n" + " (unless the log file itself is stdout).\n" + " --syslog Output all log information into the system log (syslog), do not use " + "the file output.\n" + " --syslog-facility Set syslog facility for syslog messages. Default is ''.\n" + " --simple-log This flag means that no log file rollover will be used, and " + "the log file\n" + " name will be constructed as-is, without PID and date appendage.\n" + " This option can be used, for example, together with the logrotate " + "tool.\n" + " --new-log-timestamp Enable full ISO-8601 timestamp in all logs.\n" + " --new-log-timestamp-format Set timestamp format (in strftime(1) format). Depends on " + "--new-log-timestamp to be enabled.\n" + " --log-binding Log STUN binding request. It is now disabled by default to " + "avoid DoS attacks.\n" + " --stale-nonce[=] Use extra security with nonce value having limited lifetime (default " + "600 secs).\n" + " --max-allocate-lifetime Set the maximum value for the allocation lifetime. Default to 3600 " + "secs.\n" + " --channel-lifetime Set the lifetime for channel binding, default to 600 secs.\n" + " This value MUST not be changed for production purposes.\n" + " --permission-lifetime Set the value for the lifetime of the permission. Default to " + "300 secs.\n" + " This MUST not be changed for production purposes.\n" + " -S, --stun-only Option to set standalone STUN operation only, all TURN requests will " + "be ignored.\n" + " --no-stun Option to suppress STUN functionality, only TURN requests will " + "be processed.\n" + " --alternate-server Set the TURN server to redirect the allocate requests (UDP and " + "TCP services).\n" + " Multiple alternate-server options can be set for load balancing " + "purposes.\n" + " See the docs for more information.\n" + " --tls-alternate-server Set the TURN server to redirect the allocate requests (DTLS " + "and TLS services).\n" + " Multiple alternate-server options can be set for load balancing " + "purposes.\n" + " See the docs for more information.\n" + " -C, --rest-api-separator This is the timestamp/username separator symbol (character) in TURN " + "REST API.\n" + " The default value is ':'.\n" + " --max-allocate-timeout= Max time, in seconds, allowed for full allocation establishment. " + "Default is 60.\n" + " --allowed-peer-ip= Specifies an ip or range of ips that are explicitly allowed to " + "connect to the \n" + " turn server. Multiple allowed-peer-ip can be set.\n" + " --denied-peer-ip= Specifies an ip or range of ips that are not allowed to " + "connect to the turn server.\n" + " Multiple denied-peer-ip can be set.\n" + " --pidfile <\"pid-file-name\"> File name to store the pid of the process.\n" + " Default is /var/run/turnserver.pid (if superuser account is used) or\n" + " /var/tmp/turnserver.pid .\n" + " --acme-redirect Redirect ACME, i.e. HTTP GET requests matching " + "'^/.well-known/acme-challenge/(.*)' to '$1'.\n" + " Default is '', i.e. no special handling for such requests.\n" + " --secure-stun Require authentication of the STUN Binding request.\n" + " By default, the clients are allowed anonymous access to the STUN " + "Binding functionality.\n" + " --proc-user User name to run the turnserver process.\n" + " After the initialization, the turnserver process\n" + " will make an attempt to change the current user ID to that user.\n" + " --proc-group Group name to run the turnserver process.\n" + " After the initialization, the turnserver process\n" + " will make an attempt to change the current group ID to that group.\n" + " --mobility Mobility with ICE (MICE) specs support.\n" + " -K, --keep-address-family Deprecated in favor of --allocation-default-address-family!!\n" + " TURN server allocates address family according TURN\n" + " Client <=> Server communication address family.\n" + " !! It breaks RFC6156 section-4.2 (violates default IPv4) !!\n" + " -A --allocation-default-address-family= Default is IPv4\n" + " TURN server allocates address family according TURN client requested " + "address family. \n" + " If address family is not requested explicitly by client, then it falls " + "back to this default.\n" + " The standard RFC explicitly define actually that this default must be " + "IPv4,\n" + " so use other option values with care!\n" + " --no-cli Turn OFF the CLI support. By default it is always ON.\n" + " --cli-ip= Local system IP address to be used for CLI server endpoint. " + "Default value\n" + " is 127.0.0.1.\n" + " --cli-port= CLI server port. Default is 5766.\n" + " --cli-password= CLI access password. Default is empty (no password).\n" + " For the security reasons, it is recommended to use the encrypted\n" + " for of the password (see the -P command in the turnadmin utility).\n" + " The dollar signs in the encrypted form must be escaped.\n" + " --web-admin Enable Turn Web-admin support. By default it is disabled.\n" + " --web-admin-ip= Local system IP address to be used for Web-admin server " + "endpoint. Default value\n" + " is 127.0.0.1.\n" + " --web-admin-port= Web-admin server port. Default is 8080.\n" + " --web-admin-listen-on-workers Enable for web-admin server to listens on STUN/TURN workers " + "STUN/TURN ports.\n" + " By default it is disabled for security reasons!\n" + " (This behavior used to be the default behavior, and was enabled by " + "default.)\n" + " --server-relay Server relay. NON-STANDARD AND DANGEROUS OPTION. Only for " + "those applications\n" + " when we want to run server applications on the relay endpoints.\n" + " This option eliminates the IP permissions check on the packets\n" + " incoming to the relay endpoints.\n" + " --cli-max-output-sessions Maximum number of output sessions in ps CLI command.\n" + " This value can be changed on-the-fly in CLI. The default value is " + "256.\n" + " --ne=[1|2|3] Set network engine type for the process (for internal " + "purposes).\n" + " --no-rfc5780 Disable RFC5780 (NAT behavior discovery).\n" + " Originally, if there are more than one listener address from the same\n" + " address family, then by default the NAT behavior discovery feature " + "enabled.\n" + " This option disables this original behavior, because the NAT behavior " + "discovery\n" + " adds attributes to response, and this increase the possibility of an " + "amplification attack.\n" + " Strongly encouraged to use this option to decrease gain factor in STUN " + "binding responses.\n" + " --no-stun-backward-compatibility Disable handling old STUN Binding requests and disable MAPPED-ADDRESS " + "attribute\n" + " in binding response (use only the XOR-MAPPED-ADDRESS).\n" + " --response-origin-only-with-rfc5780 Only send RESPONSE-ORIGIN attribute in binding response if " + "RFC5780 is enabled.\n" + " --version Print version (and exit).\n" + " -h Help\n" + "\n"; -static char AdminUsage[] = "Usage: turnadmin [command] [options]\n" - "\nCommands:\n\n" - " -P, --generate-encrypted-password Generate and print to the standard\n" - " output an encrypted form of a password\n" - " (for web admin user or CLI). See wiki, README or man\n" - " pages for more detailed description.\n" - " -k, --key generate long-term credential mechanism key for a user\n" - " -a, --add add/update a long-term mechanism user\n" - " -A, --add-admin add/update a web admin user\n" - " -d, --delete delete a long-term mechanism user\n" - " -D, --delete-admin delete an admin user\n" - " -l, --list list all long-term mechanism users\n" - " -L, --list-admin list all admin users\n" - " -s, --set-secret= Add shared secret for TURN REST API\n" - " -S, --show-secret Show stored shared secrets for TURN REST API\n" - " -X, --delete-secret= Delete a shared secret\n" - " --delete-all-secrets Delete all shared secrets for REST API\n" - " -O, --add-origin Add origin-to-realm relation.\n" - " -R, --del-origin Delete origin-to-realm relation.\n" - " -I, --list-origins List origin-to-realm relations.\n" - " -g, --set-realm-option Set realm params: max-bps, total-quota, user-quota.\n" - " -G, --list-realm-options List realm params.\n" - " -E, --generate-encrypted-password-aes Generate and print to the standard\n" - " output an encrypted form of password with AES-128\n" - "\nOptions with mandatory values:\n\n" +static char AdminUsage[] = + "Usage: turnadmin [command] [options]\n" + "\nCommands:\n\n" + " -P, --generate-encrypted-password Generate and print to the standard\n" + " output an encrypted form of a password\n" + " (for web admin user or CLI). See wiki, README or man\n" + " pages for more detailed description.\n" + " -k, --key generate long-term credential mechanism key for a user\n" + " -a, --add add/update a long-term mechanism user\n" + " -A, --add-admin add/update a web admin user\n" + " -d, --delete delete a long-term mechanism user\n" + " -D, --delete-admin delete an admin user\n" + " -l, --list list all long-term mechanism users\n" + " -L, --list-admin list all admin users\n" + " -s, --set-secret= Add shared secret for TURN REST API\n" + " -S, --show-secret Show stored shared secrets for TURN REST API\n" + " -X, --delete-secret= Delete a shared secret\n" + " --delete-all-secrets Delete all shared secrets for REST API\n" + " -O, --add-origin Add origin-to-realm relation.\n" + " -R, --del-origin Delete origin-to-realm relation.\n" + " -I, --list-origins List origin-to-realm relations.\n" + " -g, --set-realm-option Set realm params: max-bps, total-quota, user-quota.\n" + " -G, --list-realm-options List realm params.\n" + " -E, --generate-encrypted-password-aes Generate and print to the standard\n" + " output an encrypted form of password with AES-128\n" + "\nOptions with mandatory values:\n\n" #if !defined(TURN_NO_SQLITE) - " -b, --db, --userdb SQLite database file, default value is /var/db/turndb or\n" - " /usr/local/var/db/turndb or /var/lib/turn/turndb.\n" + " -b, --db, --userdb SQLite database file, default value is /var/db/turndb or\n" + " /usr/local/var/db/turndb or /var/lib/turn/turndb.\n" #endif #if !defined(TURN_NO_PQ) - " -e, --psql-userdb, --sql-userdb PostgreSQL user database connection string, if PostgreSQL DB is used.\n" + " -e, --psql-userdb, --sql-userdb PostgreSQL user database connection string, if PostgreSQL DB is used.\n" #endif #if !defined(TURN_NO_MYSQL) - " -M, --mysql-userdb MySQL user database connection string, if MySQL DB is used.\n" + " -M, --mysql-userdb MySQL user database connection string, if MySQL DB is used.\n" #endif #if !defined(TURN_NO_MONGO) - " -J, --mongo-userdb MongoDB user database connection string, if MongoDB is used.\n" + " -J, --mongo-userdb MongoDB user database connection string, if MongoDB is used.\n" #endif #if !defined(TURN_NO_HIREDIS) - " -N, --redis-userdb Redis user database connection string, if Redis DB is used.\n" + " -N, --redis-userdb Redis user database connection string, if Redis DB is used.\n" #endif - " -u, --user Username\n" - " -r, --realm Realm\n" - " -p, --password Password\n" - " -x, --key-path Generates a 128 bit key into the given path.\n" - " -f, --file-key-path Contains a 128 bit key in the given path.\n" - " -v, --verify Verify a given base64 encrypted type password.\n" -#if !defined(TURN_NO_SQLITE) || !defined(TURN_NO_PQ) || !defined(TURN_NO_MYSQL) || !defined(TURN_NO_MONGO) || !defined(TURN_NO_HIREDIS) - " -o, --origin Origin\n" + " -u, --user Username\n" + " -r, --realm Realm\n" + " -p, --password Password\n" + " -x, --key-path Generates a 128 bit key into the given path.\n" + " -f, --file-key-path Contains a 128 bit key in the given path.\n" + " -v, --verify Verify a given base64 encrypted type password.\n" +#if !defined(TURN_NO_SQLITE) || !defined(TURN_NO_PQ) || !defined(TURN_NO_MYSQL) || !defined(TURN_NO_MONGO) || \ + !defined(TURN_NO_HIREDIS) + " -o, --origin Origin\n" #endif - " --max-bps Set value of realm's max-bps parameter.\n" - " Setting to zero value means removal of the option.\n" - " --total-quota Set value of realm's total-quota parameter.\n" - " Setting to zero value means removal of the option.\n" - " --user-quota Set value of realm's user-quota parameter.\n" - " Setting to zero value means removal of the option.\n" - " -h, --help Help\n"; + " --max-bps Set value of realm's max-bps parameter.\n" + " Setting to zero value means removal of the option.\n" + " --total-quota Set value of realm's total-quota parameter.\n" + " Setting to zero value means removal of the option.\n" + " --user-quota Set value of realm's user-quota parameter.\n" + " Setting to zero value means removal of the option.\n" + " -h, --help Help\n"; #define OPTIONS "c:d:p:L:E:X:i:m:l:r:u:b:B:e:M:J:N:O:q:Q:s:C:K:A:vVofhznaS" #define ADMIN_OPTIONS "PEgGORIHKYlLkaADSdb:e:M:J:N:u:r:p:s:X:o:h:x:v:f:" enum EXTRA_OPTS { - NO_UDP_OPT=256, - NO_TCP_OPT, - TCP_PROXY_PORT_OPT, - NO_TLS_OPT, - NO_DTLS_OPT, - NO_UDP_RELAY_OPT, - NO_TCP_RELAY_OPT, - TLS_PORT_OPT, - ALT_PORT_OPT, - ALT_TLS_PORT_OPT, - CERT_FILE_OPT, - PKEY_FILE_OPT, - PKEY_PWD_OPT, - MIN_PORT_OPT, - MAX_PORT_OPT, - STALE_NONCE_OPT, - MAX_ALLOCATE_LIFETIME_OPT, - CHANNEL_LIFETIME_OPT, - PERMISSION_LIFETIME_OPT, - PROMETHEUS_OPT, - PROMETHEUS_PORT_OPT, - PROMETHEUS_ENABLE_USERNAMES_OPT, - AUTH_SECRET_OPT, - NO_AUTH_PINGS_OPT, - NO_DYNAMIC_IP_LIST_OPT, - NO_DYNAMIC_REALMS_OPT, - DEL_ALL_AUTH_SECRETS_OPT, - STATIC_AUTH_SECRET_VAL_OPT, - AUTH_SECRET_TS_EXP, /* deprecated */ - NO_STDOUT_LOG_OPT, - SYSLOG_OPT, - SYSLOG_FACILITY_OPT, - SIMPLE_LOG_OPT, - NEW_LOG_TIMESTAMP_OPT, - NEW_LOG_TIMESTAMP_FORMAT_OPT, - AUX_SERVER_OPT, - UDP_SELF_BALANCE_OPT, - ALTERNATE_SERVER_OPT, - TLS_ALTERNATE_SERVER_OPT, - NO_MULTICAST_PEERS_OPT, - ALLOW_LOOPBACK_PEERS_OPT, - MAX_ALLOCATE_TIMEOUT_OPT, - ALLOWED_PEER_IPS, - DENIED_PEER_IPS, - CIPHER_LIST_OPT, - PIDFILE_OPT, - SECURE_STUN_OPT, - CA_FILE_OPT, - DH_FILE_OPT, - NO_STUN_OPT, - PROC_USER_OPT, - PROC_GROUP_OPT, - MOBILITY_OPT, - NO_CLI_OPT, - CLI_IP_OPT, - CLI_PORT_OPT, - CLI_PASSWORD_OPT, - WEB_ADMIN_OPT, - WEB_ADMIN_IP_OPT, - WEB_ADMIN_PORT_OPT, - WEB_ADMIN_LISTEN_ON_WORKERS_OPT, - SERVER_RELAY_OPT, - CLI_MAX_SESSIONS_OPT, - EC_CURVE_NAME_OPT, - DH566_OPT, - DH1066_OPT, - NE_TYPE_OPT, - NO_SSLV2_OPT, /*deprecated*/ - NO_SSLV3_OPT, /*deprecated*/ - NO_TLSV1_OPT, - NO_TLSV1_1_OPT, - NO_TLSV1_2_OPT, - CHECK_ORIGIN_CONSISTENCY_OPT, - ADMIN_MAX_BPS_OPT, - ADMIN_TOTAL_QUOTA_OPT, - ADMIN_USER_QUOTA_OPT, - SERVER_NAME_OPT, - OAUTH_OPT, - NO_SOFTWARE_ATTRIBUTE_OPT, - NO_HTTP_OPT, - SECRET_KEY_OPT, - ACME_REDIRECT_OPT, - LOG_BINDING_OPT, - NO_RFC5780, - NO_STUN_BACKWARD_COMPATIBILITY_OPT, - RESPONSE_ORIGIN_ONLY_WITH_RFC5780_OPT, - VERSION_OPT + NO_UDP_OPT = 256, + NO_TCP_OPT, + TCP_PROXY_PORT_OPT, + NO_TLS_OPT, + NO_DTLS_OPT, + NO_UDP_RELAY_OPT, + NO_TCP_RELAY_OPT, + TLS_PORT_OPT, + ALT_PORT_OPT, + ALT_TLS_PORT_OPT, + CERT_FILE_OPT, + PKEY_FILE_OPT, + PKEY_PWD_OPT, + MIN_PORT_OPT, + MAX_PORT_OPT, + STALE_NONCE_OPT, + MAX_ALLOCATE_LIFETIME_OPT, + CHANNEL_LIFETIME_OPT, + PERMISSION_LIFETIME_OPT, + PROMETHEUS_OPT, + PROMETHEUS_PORT_OPT, + PROMETHEUS_ENABLE_USERNAMES_OPT, + AUTH_SECRET_OPT, + NO_AUTH_PINGS_OPT, + NO_DYNAMIC_IP_LIST_OPT, + NO_DYNAMIC_REALMS_OPT, + DEL_ALL_AUTH_SECRETS_OPT, + STATIC_AUTH_SECRET_VAL_OPT, + AUTH_SECRET_TS_EXP, /* deprecated */ + NO_STDOUT_LOG_OPT, + SYSLOG_OPT, + SYSLOG_FACILITY_OPT, + SIMPLE_LOG_OPT, + NEW_LOG_TIMESTAMP_OPT, + NEW_LOG_TIMESTAMP_FORMAT_OPT, + AUX_SERVER_OPT, + UDP_SELF_BALANCE_OPT, + ALTERNATE_SERVER_OPT, + TLS_ALTERNATE_SERVER_OPT, + NO_MULTICAST_PEERS_OPT, + ALLOW_LOOPBACK_PEERS_OPT, + MAX_ALLOCATE_TIMEOUT_OPT, + ALLOWED_PEER_IPS, + DENIED_PEER_IPS, + CIPHER_LIST_OPT, + PIDFILE_OPT, + SECURE_STUN_OPT, + CA_FILE_OPT, + DH_FILE_OPT, + NO_STUN_OPT, + PROC_USER_OPT, + PROC_GROUP_OPT, + MOBILITY_OPT, + NO_CLI_OPT, + CLI_IP_OPT, + CLI_PORT_OPT, + CLI_PASSWORD_OPT, + WEB_ADMIN_OPT, + WEB_ADMIN_IP_OPT, + WEB_ADMIN_PORT_OPT, + WEB_ADMIN_LISTEN_ON_WORKERS_OPT, + SERVER_RELAY_OPT, + CLI_MAX_SESSIONS_OPT, + EC_CURVE_NAME_OPT, + DH566_OPT, + DH1066_OPT, + NE_TYPE_OPT, + NO_SSLV2_OPT, /*deprecated*/ + NO_SSLV3_OPT, /*deprecated*/ + NO_TLSV1_OPT, + NO_TLSV1_1_OPT, + NO_TLSV1_2_OPT, + CHECK_ORIGIN_CONSISTENCY_OPT, + ADMIN_MAX_BPS_OPT, + ADMIN_TOTAL_QUOTA_OPT, + ADMIN_USER_QUOTA_OPT, + SERVER_NAME_OPT, + OAUTH_OPT, + NO_SOFTWARE_ATTRIBUTE_OPT, + NO_HTTP_OPT, + SECRET_KEY_OPT, + ACME_REDIRECT_OPT, + LOG_BINDING_OPT, + NO_RFC5780, + NO_STUN_BACKWARD_COMPATIBILITY_OPT, + RESPONSE_ORIGIN_ONLY_WITH_RFC5780_OPT, + VERSION_OPT }; struct myoption { - const char *name; /* name of long option */ - int has_arg; /* whether option takes an argument */ - int *flag; /* if not NULL, set *flag to val when option found */ - int val; /* if flag is not NULL, value to set *flag to. */ - /* if flag is NULL, return value */ + const char *name; /* name of long option */ + int has_arg; /* whether option takes an argument */ + int *flag; /* if not NULL, set *flag to val when option found */ + int val; /* if flag is not NULL, value to set *flag to. */ + /* if flag is NULL, return value */ }; struct uoptions { - union { - const struct myoption *m; - const struct option *o; - } u; + union { + const struct myoption *m; + const struct option *o; + } u; }; static const struct myoption long_options[] = { - { "listening-device", required_argument, NULL, 'd' }, - { "listening-port", required_argument, NULL, 'p' }, - { "tls-listening-port", required_argument, NULL, TLS_PORT_OPT }, - { "alt-listening-port", required_argument, NULL, ALT_PORT_OPT }, - { "alt-tls-listening-port", required_argument, NULL, ALT_TLS_PORT_OPT }, - { "tcp-proxy-port", required_argument, NULL, TCP_PROXY_PORT_OPT }, - { "listening-ip", required_argument, NULL, 'L' }, - { "relay-device", required_argument, NULL, 'i' }, - { "relay-ip", required_argument, NULL, 'E' }, - { "external-ip", required_argument, NULL, 'X' }, - { "relay-threads", required_argument, NULL, 'm' }, - { "min-port", required_argument, NULL, MIN_PORT_OPT }, - { "max-port", required_argument, NULL, MAX_PORT_OPT }, - { "lt-cred-mech", optional_argument, NULL, 'a' }, - { "no-auth", optional_argument, NULL, 'z' }, - { "user", required_argument, NULL, 'u' }, - { "userdb", required_argument, NULL, 'b' }, - { "db", required_argument, NULL, 'b' }, + {"listening-device", required_argument, NULL, 'd'}, + {"listening-port", required_argument, NULL, 'p'}, + {"tls-listening-port", required_argument, NULL, TLS_PORT_OPT}, + {"alt-listening-port", required_argument, NULL, ALT_PORT_OPT}, + {"alt-tls-listening-port", required_argument, NULL, ALT_TLS_PORT_OPT}, + {"tcp-proxy-port", required_argument, NULL, TCP_PROXY_PORT_OPT}, + {"listening-ip", required_argument, NULL, 'L'}, + {"relay-device", required_argument, NULL, 'i'}, + {"relay-ip", required_argument, NULL, 'E'}, + {"external-ip", required_argument, NULL, 'X'}, + {"relay-threads", required_argument, NULL, 'm'}, + {"min-port", required_argument, NULL, MIN_PORT_OPT}, + {"max-port", required_argument, NULL, MAX_PORT_OPT}, + {"lt-cred-mech", optional_argument, NULL, 'a'}, + {"no-auth", optional_argument, NULL, 'z'}, + {"user", required_argument, NULL, 'u'}, + {"userdb", required_argument, NULL, 'b'}, + {"db", required_argument, NULL, 'b'}, #if !defined(TURN_NO_PQ) - { "psql-userdb", required_argument, NULL, 'e' }, - { "sql-userdb", required_argument, NULL, 'e' }, + {"psql-userdb", required_argument, NULL, 'e'}, + {"sql-userdb", required_argument, NULL, 'e'}, #endif #if !defined(TURN_NO_MYSQL) - { "mysql-userdb", required_argument, NULL, 'M' }, + {"mysql-userdb", required_argument, NULL, 'M'}, #endif #if !defined(TURN_NO_MONGO) - { "mongo-userdb", required_argument, NULL, 'J' }, + {"mongo-userdb", required_argument, NULL, 'J'}, #endif #if !defined(TURN_NO_HIREDIS) - { "redis-userdb", required_argument, NULL, 'N' }, - { "redis-statsdb", required_argument, NULL, 'O' }, + {"redis-userdb", required_argument, NULL, 'N'}, + {"redis-statsdb", required_argument, NULL, 'O'}, #endif #if !defined(TURN_NO_PROMETHEUS) - { "prometheus", optional_argument, NULL, PROMETHEUS_OPT }, - { "prometheus-port", optional_argument, NULL, PROMETHEUS_PORT_OPT }, - { "prometheus-username-labels", optional_argument, NULL, PROMETHEUS_ENABLE_USERNAMES_OPT }, + {"prometheus", optional_argument, NULL, PROMETHEUS_OPT}, + {"prometheus-port", optional_argument, NULL, PROMETHEUS_PORT_OPT}, + {"prometheus-username-labels", optional_argument, NULL, PROMETHEUS_ENABLE_USERNAMES_OPT}, #endif - { "use-auth-secret", optional_argument, NULL, AUTH_SECRET_OPT }, - { "static-auth-secret", required_argument, NULL, STATIC_AUTH_SECRET_VAL_OPT }, - { "no-auth-pings", optional_argument, NULL, NO_AUTH_PINGS_OPT }, - { "no-dynamic-ip-list", optional_argument, NULL, NO_DYNAMIC_IP_LIST_OPT }, - { "no-dynamic-realms", optional_argument, NULL, NO_DYNAMIC_REALMS_OPT }, -/* deprecated: */ { "secret-ts-exp-time", optional_argument, NULL, AUTH_SECRET_TS_EXP }, - { "realm", required_argument, NULL, 'r' }, - { "server-name", required_argument, NULL, SERVER_NAME_OPT }, - { "oauth", optional_argument, NULL, OAUTH_OPT }, - { "user-quota", required_argument, NULL, 'q' }, - { "total-quota", required_argument, NULL, 'Q' }, - { "max-bps", required_argument, NULL, 's' }, - { "bps-capacity", required_argument, NULL, 'B' }, - { "verbose", optional_argument, NULL, 'v' }, - { "Verbose", optional_argument, NULL, 'V' }, - { "daemon", optional_argument, NULL, 'o' }, -/* deprecated: */ { "prod", optional_argument, NULL, NO_SOFTWARE_ATTRIBUTE_OPT }, - { "no-software-attribute", optional_argument, NULL, NO_SOFTWARE_ATTRIBUTE_OPT }, - { "fingerprint", optional_argument, NULL, 'f' }, - { "check-origin-consistency", optional_argument, NULL, CHECK_ORIGIN_CONSISTENCY_OPT }, - { "no-udp", optional_argument, NULL, NO_UDP_OPT }, - { "no-tcp", optional_argument, NULL, NO_TCP_OPT }, - { "no-tls", optional_argument, NULL, NO_TLS_OPT }, - { "no-dtls", optional_argument, NULL, NO_DTLS_OPT }, - { "no-udp-relay", optional_argument, NULL, NO_UDP_RELAY_OPT }, - { "no-tcp-relay", optional_argument, NULL, NO_TCP_RELAY_OPT }, - { "stale-nonce", optional_argument, NULL, STALE_NONCE_OPT }, - { "max-allocate-lifetime", optional_argument, NULL, MAX_ALLOCATE_LIFETIME_OPT }, - { "channel-lifetime", optional_argument, NULL, CHANNEL_LIFETIME_OPT }, - { "permission-lifetime", optional_argument, NULL, PERMISSION_LIFETIME_OPT }, - { "stun-only", optional_argument, NULL, 'S' }, - { "no-stun", optional_argument, NULL, NO_STUN_OPT }, - { "cert", required_argument, NULL, CERT_FILE_OPT }, - { "pkey", required_argument, NULL, PKEY_FILE_OPT }, - { "pkey-pwd", required_argument, NULL, PKEY_PWD_OPT }, - { "log-file", required_argument, NULL, 'l' }, - { "no-stdout-log", optional_argument, NULL, NO_STDOUT_LOG_OPT }, - { "syslog", optional_argument, NULL, SYSLOG_OPT }, - { "simple-log", optional_argument, NULL, SIMPLE_LOG_OPT }, - { "new-log-timestamp", optional_argument, NULL, NEW_LOG_TIMESTAMP_OPT }, - { "new-log-timestamp-format", required_argument, NULL, NEW_LOG_TIMESTAMP_FORMAT_OPT }, - { "aux-server", required_argument, NULL, AUX_SERVER_OPT }, - { "udp-self-balance", optional_argument, NULL, UDP_SELF_BALANCE_OPT }, - { "alternate-server", required_argument, NULL, ALTERNATE_SERVER_OPT }, - { "tls-alternate-server", required_argument, NULL, TLS_ALTERNATE_SERVER_OPT }, - { "rest-api-separator", required_argument, NULL, 'C' }, - { "max-allocate-timeout", required_argument, NULL, MAX_ALLOCATE_TIMEOUT_OPT }, - { "no-multicast-peers", optional_argument, NULL, NO_MULTICAST_PEERS_OPT }, - { "allow-loopback-peers", optional_argument, NULL, ALLOW_LOOPBACK_PEERS_OPT }, - { "allowed-peer-ip", required_argument, NULL, ALLOWED_PEER_IPS }, - { "denied-peer-ip", required_argument, NULL, DENIED_PEER_IPS }, - { "cipher-list", required_argument, NULL, CIPHER_LIST_OPT }, - { "pidfile", required_argument, NULL, PIDFILE_OPT }, - { "secure-stun", optional_argument, NULL, SECURE_STUN_OPT }, - { "CA-file", required_argument, NULL, CA_FILE_OPT }, - { "dh-file", required_argument, NULL, DH_FILE_OPT }, - { "proc-user", required_argument, NULL, PROC_USER_OPT }, - { "proc-group", required_argument, NULL, PROC_GROUP_OPT }, - { "mobility", optional_argument, NULL, MOBILITY_OPT }, - { "no-cli", optional_argument, NULL, NO_CLI_OPT }, - { "cli-ip", required_argument, NULL, CLI_IP_OPT }, - { "cli-port", required_argument, NULL, CLI_PORT_OPT }, - { "cli-password", required_argument, NULL, CLI_PASSWORD_OPT }, - { "web-admin", optional_argument, NULL, WEB_ADMIN_OPT }, - { "web-admin-ip", required_argument, NULL, WEB_ADMIN_IP_OPT }, - { "web-admin-port", required_argument, NULL, WEB_ADMIN_PORT_OPT }, - { "web-admin-listen-on-workers", optional_argument, NULL, WEB_ADMIN_LISTEN_ON_WORKERS_OPT }, - { "server-relay", optional_argument, NULL, SERVER_RELAY_OPT }, - { "cli-max-output-sessions", required_argument, NULL, CLI_MAX_SESSIONS_OPT }, - { "ec-curve-name", required_argument, NULL, EC_CURVE_NAME_OPT }, - { "dh566", optional_argument, NULL, DH566_OPT }, - { "dh1066", optional_argument, NULL, DH1066_OPT }, - { "ne", required_argument, NULL, NE_TYPE_OPT }, - { "no-sslv2", optional_argument, NULL, NO_SSLV2_OPT }, /* deprecated */ - { "no-sslv3", optional_argument, NULL, NO_SSLV3_OPT }, /* deprecated */ - { "no-tlsv1", optional_argument, NULL, NO_TLSV1_OPT }, - { "no-tlsv1_1", optional_argument, NULL, NO_TLSV1_1_OPT }, - { "no-tlsv1_2", optional_argument, NULL, NO_TLSV1_2_OPT }, - { "secret-key-file", required_argument, NULL, SECRET_KEY_OPT }, - { "keep-address-family", optional_argument, NULL, 'K' }, - { "allocation-default-address-family", required_argument, NULL, 'A' }, - { "acme-redirect", required_argument, NULL, ACME_REDIRECT_OPT }, - { "log-binding", optional_argument, NULL, LOG_BINDING_OPT }, - { "no-rfc5780", optional_argument, NULL, NO_RFC5780 }, - { "no-stun-backward-compatibility", optional_argument, NULL, NO_STUN_BACKWARD_COMPATIBILITY_OPT }, - { "response-origin-only-with-rfc5780", optional_argument, NULL, RESPONSE_ORIGIN_ONLY_WITH_RFC5780_OPT }, - { "version", optional_argument, NULL, VERSION_OPT }, - { "syslog-facility", required_argument, NULL, SYSLOG_FACILITY_OPT }, - { NULL, no_argument, NULL, 0 } -}; + {"use-auth-secret", optional_argument, NULL, AUTH_SECRET_OPT}, + {"static-auth-secret", required_argument, NULL, STATIC_AUTH_SECRET_VAL_OPT}, + {"no-auth-pings", optional_argument, NULL, NO_AUTH_PINGS_OPT}, + {"no-dynamic-ip-list", optional_argument, NULL, NO_DYNAMIC_IP_LIST_OPT}, + {"no-dynamic-realms", optional_argument, NULL, NO_DYNAMIC_REALMS_OPT}, + /* deprecated: */ {"secret-ts-exp-time", optional_argument, NULL, AUTH_SECRET_TS_EXP}, + {"realm", required_argument, NULL, 'r'}, + {"server-name", required_argument, NULL, SERVER_NAME_OPT}, + {"oauth", optional_argument, NULL, OAUTH_OPT}, + {"user-quota", required_argument, NULL, 'q'}, + {"total-quota", required_argument, NULL, 'Q'}, + {"max-bps", required_argument, NULL, 's'}, + {"bps-capacity", required_argument, NULL, 'B'}, + {"verbose", optional_argument, NULL, 'v'}, + {"Verbose", optional_argument, NULL, 'V'}, + {"daemon", optional_argument, NULL, 'o'}, + /* deprecated: */ {"prod", optional_argument, NULL, NO_SOFTWARE_ATTRIBUTE_OPT}, + {"no-software-attribute", optional_argument, NULL, NO_SOFTWARE_ATTRIBUTE_OPT}, + {"fingerprint", optional_argument, NULL, 'f'}, + {"check-origin-consistency", optional_argument, NULL, CHECK_ORIGIN_CONSISTENCY_OPT}, + {"no-udp", optional_argument, NULL, NO_UDP_OPT}, + {"no-tcp", optional_argument, NULL, NO_TCP_OPT}, + {"no-tls", optional_argument, NULL, NO_TLS_OPT}, + {"no-dtls", optional_argument, NULL, NO_DTLS_OPT}, + {"no-udp-relay", optional_argument, NULL, NO_UDP_RELAY_OPT}, + {"no-tcp-relay", optional_argument, NULL, NO_TCP_RELAY_OPT}, + {"stale-nonce", optional_argument, NULL, STALE_NONCE_OPT}, + {"max-allocate-lifetime", optional_argument, NULL, MAX_ALLOCATE_LIFETIME_OPT}, + {"channel-lifetime", optional_argument, NULL, CHANNEL_LIFETIME_OPT}, + {"permission-lifetime", optional_argument, NULL, PERMISSION_LIFETIME_OPT}, + {"stun-only", optional_argument, NULL, 'S'}, + {"no-stun", optional_argument, NULL, NO_STUN_OPT}, + {"cert", required_argument, NULL, CERT_FILE_OPT}, + {"pkey", required_argument, NULL, PKEY_FILE_OPT}, + {"pkey-pwd", required_argument, NULL, PKEY_PWD_OPT}, + {"log-file", required_argument, NULL, 'l'}, + {"no-stdout-log", optional_argument, NULL, NO_STDOUT_LOG_OPT}, + {"syslog", optional_argument, NULL, SYSLOG_OPT}, + {"simple-log", optional_argument, NULL, SIMPLE_LOG_OPT}, + {"new-log-timestamp", optional_argument, NULL, NEW_LOG_TIMESTAMP_OPT}, + {"new-log-timestamp-format", required_argument, NULL, NEW_LOG_TIMESTAMP_FORMAT_OPT}, + {"aux-server", required_argument, NULL, AUX_SERVER_OPT}, + {"udp-self-balance", optional_argument, NULL, UDP_SELF_BALANCE_OPT}, + {"alternate-server", required_argument, NULL, ALTERNATE_SERVER_OPT}, + {"tls-alternate-server", required_argument, NULL, TLS_ALTERNATE_SERVER_OPT}, + {"rest-api-separator", required_argument, NULL, 'C'}, + {"max-allocate-timeout", required_argument, NULL, MAX_ALLOCATE_TIMEOUT_OPT}, + {"no-multicast-peers", optional_argument, NULL, NO_MULTICAST_PEERS_OPT}, + {"allow-loopback-peers", optional_argument, NULL, ALLOW_LOOPBACK_PEERS_OPT}, + {"allowed-peer-ip", required_argument, NULL, ALLOWED_PEER_IPS}, + {"denied-peer-ip", required_argument, NULL, DENIED_PEER_IPS}, + {"cipher-list", required_argument, NULL, CIPHER_LIST_OPT}, + {"pidfile", required_argument, NULL, PIDFILE_OPT}, + {"secure-stun", optional_argument, NULL, SECURE_STUN_OPT}, + {"CA-file", required_argument, NULL, CA_FILE_OPT}, + {"dh-file", required_argument, NULL, DH_FILE_OPT}, + {"proc-user", required_argument, NULL, PROC_USER_OPT}, + {"proc-group", required_argument, NULL, PROC_GROUP_OPT}, + {"mobility", optional_argument, NULL, MOBILITY_OPT}, + {"no-cli", optional_argument, NULL, NO_CLI_OPT}, + {"cli-ip", required_argument, NULL, CLI_IP_OPT}, + {"cli-port", required_argument, NULL, CLI_PORT_OPT}, + {"cli-password", required_argument, NULL, CLI_PASSWORD_OPT}, + {"web-admin", optional_argument, NULL, WEB_ADMIN_OPT}, + {"web-admin-ip", required_argument, NULL, WEB_ADMIN_IP_OPT}, + {"web-admin-port", required_argument, NULL, WEB_ADMIN_PORT_OPT}, + {"web-admin-listen-on-workers", optional_argument, NULL, WEB_ADMIN_LISTEN_ON_WORKERS_OPT}, + {"server-relay", optional_argument, NULL, SERVER_RELAY_OPT}, + {"cli-max-output-sessions", required_argument, NULL, CLI_MAX_SESSIONS_OPT}, + {"ec-curve-name", required_argument, NULL, EC_CURVE_NAME_OPT}, + {"dh566", optional_argument, NULL, DH566_OPT}, + {"dh1066", optional_argument, NULL, DH1066_OPT}, + {"ne", required_argument, NULL, NE_TYPE_OPT}, + {"no-sslv2", optional_argument, NULL, NO_SSLV2_OPT}, /* deprecated */ + {"no-sslv3", optional_argument, NULL, NO_SSLV3_OPT}, /* deprecated */ + {"no-tlsv1", optional_argument, NULL, NO_TLSV1_OPT}, + {"no-tlsv1_1", optional_argument, NULL, NO_TLSV1_1_OPT}, + {"no-tlsv1_2", optional_argument, NULL, NO_TLSV1_2_OPT}, + {"secret-key-file", required_argument, NULL, SECRET_KEY_OPT}, + {"keep-address-family", optional_argument, NULL, 'K'}, + {"allocation-default-address-family", required_argument, NULL, 'A'}, + {"acme-redirect", required_argument, NULL, ACME_REDIRECT_OPT}, + {"log-binding", optional_argument, NULL, LOG_BINDING_OPT}, + {"no-rfc5780", optional_argument, NULL, NO_RFC5780}, + {"no-stun-backward-compatibility", optional_argument, NULL, NO_STUN_BACKWARD_COMPATIBILITY_OPT}, + {"response-origin-only-with-rfc5780", optional_argument, NULL, RESPONSE_ORIGIN_ONLY_WITH_RFC5780_OPT}, + {"version", optional_argument, NULL, VERSION_OPT}, + {"syslog-facility", required_argument, NULL, SYSLOG_FACILITY_OPT}, + {NULL, no_argument, NULL, 0}}; static const struct myoption admin_long_options[] = { - {"generate-encrypted-password", no_argument, NULL, 'P' }, - {"generate-encrypted-password-aes", no_argument, NULL, 'E'}, - { "key", no_argument, NULL, 'k' }, - { "add", no_argument, NULL, 'a' }, - { "delete", no_argument, NULL, 'd' }, - { "list", no_argument, NULL, 'l' }, - { "list-admin", no_argument, NULL, 'L' }, - { "set-secret", required_argument, NULL, 's' }, - { "show-secret", no_argument, NULL, 'S' }, - { "delete-secret", required_argument, NULL, 'X' }, - { "delete-all-secrets", no_argument, NULL, DEL_ALL_AUTH_SECRETS_OPT }, - { "add-admin", no_argument, NULL, 'A' }, - { "delete-admin", no_argument, NULL, 'D' }, + {"generate-encrypted-password", no_argument, NULL, 'P'}, + {"generate-encrypted-password-aes", no_argument, NULL, 'E'}, + {"key", no_argument, NULL, 'k'}, + {"add", no_argument, NULL, 'a'}, + {"delete", no_argument, NULL, 'd'}, + {"list", no_argument, NULL, 'l'}, + {"list-admin", no_argument, NULL, 'L'}, + {"set-secret", required_argument, NULL, 's'}, + {"show-secret", no_argument, NULL, 'S'}, + {"delete-secret", required_argument, NULL, 'X'}, + {"delete-all-secrets", no_argument, NULL, DEL_ALL_AUTH_SECRETS_OPT}, + {"add-admin", no_argument, NULL, 'A'}, + {"delete-admin", no_argument, NULL, 'D'}, #if !defined(TURN_NO_SQLITE) - { "userdb", required_argument, NULL, 'b' }, - { "db", required_argument, NULL, 'b' }, + {"userdb", required_argument, NULL, 'b'}, + {"db", required_argument, NULL, 'b'}, #endif #if !defined(TURN_NO_PQ) - { "psql-userdb", required_argument, NULL, 'e' }, - { "sql-userdb", required_argument, NULL, 'e' }, + {"psql-userdb", required_argument, NULL, 'e'}, + {"sql-userdb", required_argument, NULL, 'e'}, #endif #if !defined(TURN_NO_MYSQL) - { "mysql-userdb", required_argument, NULL, 'M' }, + {"mysql-userdb", required_argument, NULL, 'M'}, #endif #if !defined(TURN_NO_MONGO) - { "mongo-userdb", required_argument, NULL, 'J' }, + {"mongo-userdb", required_argument, NULL, 'J'}, #endif #if !defined(TURN_NO_HIREDIS) - { "redis-userdb", required_argument, NULL, 'N' }, + {"redis-userdb", required_argument, NULL, 'N'}, #endif - { "user", required_argument, NULL, 'u' }, - { "realm", required_argument, NULL, 'r' }, - { "password", required_argument, NULL, 'p' }, - { "file-key-path", required_argument, NULL, 'f' }, - { "verify", required_argument, NULL, 'v' }, - { "key-path", required_argument, NULL, 'x'}, - { "add-origin", no_argument, NULL, 'O' }, - { "del-origin", no_argument, NULL, 'R' }, - { "list-origins", required_argument, NULL, 'I' }, - { "origin", required_argument, NULL, 'o' }, - { "set-realm-option", no_argument, NULL, 'g' }, - { "list-realm-option", no_argument, NULL, 'G' }, - { "user-quota", required_argument, NULL, ADMIN_USER_QUOTA_OPT }, - { "total-quota", required_argument, NULL, ADMIN_TOTAL_QUOTA_OPT }, - { "max-bps", required_argument, NULL, ADMIN_MAX_BPS_OPT }, - { "help", no_argument, NULL, 'h' }, - { NULL, no_argument, NULL, 0 } -}; + {"user", required_argument, NULL, 'u'}, + {"realm", required_argument, NULL, 'r'}, + {"password", required_argument, NULL, 'p'}, + {"file-key-path", required_argument, NULL, 'f'}, + {"verify", required_argument, NULL, 'v'}, + {"key-path", required_argument, NULL, 'x'}, + {"add-origin", no_argument, NULL, 'O'}, + {"del-origin", no_argument, NULL, 'R'}, + {"list-origins", required_argument, NULL, 'I'}, + {"origin", required_argument, NULL, 'o'}, + {"set-realm-option", no_argument, NULL, 'g'}, + {"list-realm-option", no_argument, NULL, 'G'}, + {"user-quota", required_argument, NULL, ADMIN_USER_QUOTA_OPT}, + {"total-quota", required_argument, NULL, ADMIN_TOTAL_QUOTA_OPT}, + {"max-bps", required_argument, NULL, ADMIN_MAX_BPS_OPT}, + {"help", no_argument, NULL, 'h'}, + {NULL, no_argument, NULL, 0}}; -int init_ctr(struct ctr_state *state, const unsigned char iv[8]){ - state->num = 0; - memset(state->ecount, 0, 16); - memset(state->ivec + 8, 0, 8); - memcpy(state->ivec, iv, 8); - return 1; +int init_ctr(struct ctr_state *state, const unsigned char iv[8]) { + state->num = 0; + memset(state->ecount, 0, 16); + memset(state->ivec + 8, 0, 8); + memcpy(state->ivec, iv, 8); + return 1; } -unsigned char *base64encode (const void *b64_encode_this, int encode_this_many_bytes){ - BIO *b64_bio, *mem_bio; //Declares two OpenSSL BIOs: a base64 filter and a memory BIO. - BUF_MEM *mem_bio_mem_ptr; //Pointer to a "memory BIO" structure holding our base64 data. - b64_bio = BIO_new(BIO_f_base64()); //Initialize our base64 filter BIO. - mem_bio = BIO_new(BIO_s_mem()); //Initialize our memory sink BIO. - BIO_push(b64_bio, mem_bio); //Link the BIOs by creating a filter-sink BIO chain. - BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); //No newlines every 64 characters or less. - BIO_write(b64_bio, b64_encode_this, encode_this_many_bytes); //Records base64 encoded data. - (void)BIO_flush(b64_bio); //Flush data. Necessary for b64 encoding, because of pad characters. - BIO_get_mem_ptr(mem_bio, &mem_bio_mem_ptr); //Store address of mem_bio's memory structure. - (void)BIO_set_close(mem_bio, BIO_NOCLOSE); //Permit access to mem_ptr after BIOs are destroyed. - BIO_free_all(b64_bio); //Destroys all BIOs in chain, starting with b64 (i.e. the 1st one). - BUF_MEM_grow(mem_bio_mem_ptr, (*mem_bio_mem_ptr).length + 1); //Makes space for end null. - (*mem_bio_mem_ptr).data[(*mem_bio_mem_ptr).length] = '\0'; //Adds null-terminator to tail. - return (unsigned char*)(*mem_bio_mem_ptr).data; //Returns base-64 encoded data. (See: "buf_mem_st" struct). +unsigned char *base64encode(const void *b64_encode_this, int encode_this_many_bytes) { + BIO *b64_bio, *mem_bio; // Declares two OpenSSL BIOs: a base64 filter and a memory BIO. + BUF_MEM *mem_bio_mem_ptr; // Pointer to a "memory BIO" structure holding our base64 data. + b64_bio = BIO_new(BIO_f_base64()); // Initialize our base64 filter BIO. + mem_bio = BIO_new(BIO_s_mem()); // Initialize our memory sink BIO. + BIO_push(b64_bio, mem_bio); // Link the BIOs by creating a filter-sink BIO chain. + BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); // No newlines every 64 characters or less. + BIO_write(b64_bio, b64_encode_this, encode_this_many_bytes); // Records base64 encoded data. + (void)BIO_flush(b64_bio); // Flush data. Necessary for b64 encoding, because of pad characters. + BIO_get_mem_ptr(mem_bio, &mem_bio_mem_ptr); // Store address of mem_bio's memory structure. + (void)BIO_set_close(mem_bio, BIO_NOCLOSE); // Permit access to mem_ptr after BIOs are destroyed. + BIO_free_all(b64_bio); // Destroys all BIOs in chain, starting with b64 (i.e. the 1st one). + BUF_MEM_grow(mem_bio_mem_ptr, (*mem_bio_mem_ptr).length + 1); // Makes space for end null. + (*mem_bio_mem_ptr).data[(*mem_bio_mem_ptr).length] = '\0'; // Adds null-terminator to tail. + return (unsigned char *)(*mem_bio_mem_ptr).data; // Returns base-64 encoded data. (See: "buf_mem_st" struct). } -void encrypt_aes_128(unsigned char* in, const unsigned char* mykey){ +void encrypt_aes_128(unsigned char *in, const unsigned char *mykey) { - int j=0,k=0; - int totalSize=0; - AES_KEY key; - unsigned char iv[8] = {0}; //changed - unsigned char out[1024]; //changed - AES_set_encrypt_key(mykey, 128, &key); - char total[256]; - int size=0; - struct ctr_state state; - init_ctr(&state, iv); + int j = 0, k = 0; + int totalSize = 0; + AES_KEY key; + unsigned char iv[8] = {0}; // changed + unsigned char out[1024]; // changed + AES_set_encrypt_key(mykey, 128, &key); + char total[256]; + int size = 0; + struct ctr_state state; + init_ctr(&state, iv); #if OPENSSL_VERSION_NUMBER >= 0x10100000L - CRYPTO_ctr128_encrypt(in, out, strlen((char*)in), &key, state.ivec, state.ecount, &state.num, (block128_f)AES_encrypt); + CRYPTO_ctr128_encrypt(in, out, strlen((char *)in), &key, state.ivec, state.ecount, &state.num, + (block128_f)AES_encrypt); #else - AES_ctr128_encrypt(in, out, strlen((char*)in), &key, state.ivec, state.ecount, &state.num); + AES_ctr128_encrypt(in, out, strlen((char *)in), &key, state.ivec, state.ecount, &state.num); #endif - totalSize += strlen((char*)in); - size = strlen((char*)in); - for (j = 0; j< size; j++) { - total[k++]=out[j]; + totalSize += strlen((char *)in); + size = strlen((char *)in); + for (j = 0; j < size; j++) { + total[k++] = out[j]; + } + + unsigned char *base64_encoded = base64encode(total, totalSize); + printf("%s\n", base64_encoded); +} +void generate_aes_128_key(char *filePath, unsigned char *returnedKey) { + int i; + int part; + FILE *fptr; + char key[16]; + struct timespec times; + clock_gettime(CLOCK_REALTIME, ×); + srand(times.tv_nsec); + + for (i = 0; i < 16; i++) { + part = (rand() % 3); + if (part == 0) { + key[i] = (rand() % 10) + 48; } - unsigned char *base64_encoded = base64encode(total, totalSize); - printf("%s\n",base64_encoded); - -} -void generate_aes_128_key(char* filePath, unsigned char* returnedKey){ - int i; - int part; - FILE* fptr; - char key[16]; - struct timespec times; - clock_gettime(CLOCK_REALTIME,×); - srand(times.tv_nsec); - - for (i = 0; i < 16; i++) { - part = (rand() % 3); - if(part == 0){ - key[i] = (rand() % 10) + 48; - } - - else if(part == 1){ - key[i] = (rand() % 26) + 65; - } - - else if(part == 2){ - key[i] = (rand() % 26) + 97; - } - } - fptr = fopen(filePath, "w"); - for(i = 0; i < 16; i++){ - fputc(key[i], fptr); - } - STRCPY((char*)returnedKey, key); - fclose(fptr); - - -} - -unsigned char *base64decode (const void *b64_decode_this, int decode_this_many_bytes){ - BIO *b64_bio, *mem_bio; //Declares two OpenSSL BIOs: a base64 filter and a memory BIO. - unsigned char *base64_decoded = (unsigned char*)calloc( (decode_this_many_bytes*3)/4+1, sizeof(char) ); //+1 = null. - b64_bio = BIO_new(BIO_f_base64()); //Initialize our base64 filter BIO. - mem_bio = BIO_new(BIO_s_mem()); //Initialize our memory source BIO. - BIO_write(mem_bio, b64_decode_this, decode_this_many_bytes); //Base64 data saved in source. - BIO_push(b64_bio, mem_bio); //Link the BIOs by creating a filter-source BIO chain. - BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); //Don't require trailing newlines. - int decoded_byte_index = 0; //Index where the next base64_decoded byte should be written. - while ( 0 < BIO_read(b64_bio, base64_decoded+decoded_byte_index, 1) ){ //Read byte-by-byte. - decoded_byte_index++; //Increment the index until read of BIO decoded data is complete. - } //Once we're done reading decoded data, BIO_read returns -1 even though there's no error. - BIO_free_all(b64_bio); //Destroys all BIOs in chain, starting with b64 (i.e. the 1st one). - return base64_decoded; //Returns base-64 decoded data with trailing null terminator. -} -int decodedTextSize(char *input){ - int i=0; - int result=0,padding=0; - int size=strlen(input); - for (i = 0; i < size; ++i) { - if(input[i]=='='){ - padding++; - } + else if (part == 1) { + key[i] = (rand() % 26) + 65; } - result=(strlen(input)/4*3)-padding; - return result; -} -void decrypt_aes_128(char* in, const unsigned char* mykey){ - unsigned char iv[8] = {0}; - AES_KEY key; - unsigned char outdata[256]; - AES_set_encrypt_key(mykey, 128, &key); - int newTotalSize=decodedTextSize(in); - int bytes_to_decode = strlen(in); - unsigned char *encryptedText = base64decode(in, bytes_to_decode); - char last[1024]=""; - struct ctr_state state; - init_ctr(&state, iv); - memset(outdata,'\0', sizeof(outdata)); + else if (part == 2) { + key[i] = (rand() % 26) + 97; + } + } + fptr = fopen(filePath, "w"); + for (i = 0; i < 16; i++) { + fputc(key[i], fptr); + } + STRCPY((char *)returnedKey, key); + fclose(fptr); +} + +unsigned char *base64decode(const void *b64_decode_this, int decode_this_many_bytes) { + BIO *b64_bio, *mem_bio; // Declares two OpenSSL BIOs: a base64 filter and a memory BIO. + unsigned char *base64_decoded = + (unsigned char *)calloc((decode_this_many_bytes * 3) / 4 + 1, sizeof(char)); //+1 = null. + b64_bio = BIO_new(BIO_f_base64()); // Initialize our base64 filter BIO. + mem_bio = BIO_new(BIO_s_mem()); // Initialize our memory source BIO. + BIO_write(mem_bio, b64_decode_this, decode_this_many_bytes); // Base64 data saved in source. + BIO_push(b64_bio, mem_bio); // Link the BIOs by creating a filter-source BIO chain. + BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); // Don't require trailing newlines. + int decoded_byte_index = 0; // Index where the next base64_decoded byte should be written. + while (0 < BIO_read(b64_bio, base64_decoded + decoded_byte_index, 1)) { // Read byte-by-byte. + decoded_byte_index++; // Increment the index until read of BIO decoded data is complete. + } // Once we're done reading decoded data, BIO_read returns -1 even though there's no error. + BIO_free_all(b64_bio); // Destroys all BIOs in chain, starting with b64 (i.e. the 1st one). + return base64_decoded; // Returns base-64 decoded data with trailing null terminator. +} +int decodedTextSize(char *input) { + int i = 0; + int result = 0, padding = 0; + int size = strlen(input); + for (i = 0; i < size; ++i) { + if (input[i] == '=') { + padding++; + } + } + result = (strlen(input) / 4 * 3) - padding; + return result; +} +void decrypt_aes_128(char *in, const unsigned char *mykey) { + + unsigned char iv[8] = {0}; + AES_KEY key; + unsigned char outdata[256]; + AES_set_encrypt_key(mykey, 128, &key); + int newTotalSize = decodedTextSize(in); + int bytes_to_decode = strlen(in); + unsigned char *encryptedText = base64decode(in, bytes_to_decode); + char last[1024] = ""; + struct ctr_state state; + init_ctr(&state, iv); + memset(outdata, '\0', sizeof(outdata)); #if OPENSSL_VERSION_NUMBER >= 0x10100000L - CRYPTO_ctr128_encrypt(encryptedText,outdata,newTotalSize,&key, state.ivec, state.ecount, &state.num, (block128_f)AES_encrypt); + CRYPTO_ctr128_encrypt(encryptedText, outdata, newTotalSize, &key, state.ivec, state.ecount, &state.num, + (block128_f)AES_encrypt); #else - AES_ctr128_encrypt(encryptedText, outdata, newTotalSize, &key, state.ivec, state.ecount, &state.num); + AES_ctr128_encrypt(encryptedText, outdata, newTotalSize, &key, state.ivec, state.ecount, &state.num); #endif - strcat(last,(char*)outdata); - printf("%s\n",last); + strcat(last, (char *)outdata); + printf("%s\n", last); } -static int get_int_value(const char* s, int default_value) -{ - if (!s || !(s[0])) - return default_value; - return atoi(s); +static int get_int_value(const char *s, int default_value) { + if (!s || !(s[0])) + return default_value; + return atoi(s); } -static int get_bool_value(const char* s) -{ - if(!s || !(s[0])) return 1; - if(s[0]=='0' || s[0]=='n' || s[0]=='N' || s[0]=='f' || s[0]=='F') return 0; - if(s[0]=='y' || s[0]=='Y' || s[0]=='t' || s[0]=='T') return 1; - if(s[0]>'0' && s[0]<='9') return 1; - if(!strcmp(s,"off") || !strcmp(s,"OFF") || !strcmp(s,"Off")) return 0; - if(!strcmp(s,"on") || !strcmp(s,"ON") || !strcmp(s,"On")) return 1; - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown boolean value: %s. You can use on/off, yes/no, 1/0, true/false.\n",s); - exit(-1); +static int get_bool_value(const char *s) { + if (!s || !(s[0])) + return 1; + if (s[0] == '0' || s[0] == 'n' || s[0] == 'N' || s[0] == 'f' || s[0] == 'F') + return 0; + if (s[0] == 'y' || s[0] == 'Y' || s[0] == 't' || s[0] == 'T') + return 1; + if (s[0] > '0' && s[0] <= '9') + return 1; + if (!strcmp(s, "off") || !strcmp(s, "OFF") || !strcmp(s, "Off")) + return 0; + if (!strcmp(s, "on") || !strcmp(s, "ON") || !strcmp(s, "On")) + return 1; + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown boolean value: %s. You can use on/off, yes/no, 1/0, true/false.\n", s); + exit(-1); } -static void set_option(int c, char *value) -{ - if(value && value[0]=='=') { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: option -%c is possibly used incorrectly. The short form of the option must be used as this: -%c , no \'equals\' sign may be used, that sign is used only with long form options (like --user=).\n",(char)c,(char)c); +static void set_option(int c, char *value) { + if (value && value[0] == '=') { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, + "WARNING: option -%c is possibly used incorrectly. The short form of the option must be used as " + "this: -%c , no \'equals\' sign may be used, that sign is used only with long form options " + "(like --user=).\n", + (char)c, (char)c); } switch (c) { - case 'K': - if (get_bool_value(value)) - turn_params.allocation_default_address_family = ALLOCATION_DEFAULT_ADDRESS_FAMILY_KEEP; - break; - case 'A': - if (value && strlen(value) > 0) { - if(*value == '=') ++value; - if (!strcmp(value, "ipv6")) { - turn_params.allocation_default_address_family = ALLOCATION_DEFAULT_ADDRESS_FAMILY_IPV6; - } else if (!strcmp(value,"keep")) { - turn_params.allocation_default_address_family = ALLOCATION_DEFAULT_ADDRESS_FAMILY_KEEP; - } else if (!strcmp(value, "ipv4")) { - turn_params.allocation_default_address_family = ALLOCATION_DEFAULT_ADDRESS_FAMILY_IPV4; - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: invalid allocation_default_address_family parameter\n"); - } - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: invalid allocation_default_address_family parameter\n"); - } - break; + case 'K': + if (get_bool_value(value)) + turn_params.allocation_default_address_family = ALLOCATION_DEFAULT_ADDRESS_FAMILY_KEEP; + break; + case 'A': + if (value && strlen(value) > 0) { + if (*value == '=') + ++value; + if (!strcmp(value, "ipv6")) { + turn_params.allocation_default_address_family = ALLOCATION_DEFAULT_ADDRESS_FAMILY_IPV6; + } else if (!strcmp(value, "keep")) { + turn_params.allocation_default_address_family = ALLOCATION_DEFAULT_ADDRESS_FAMILY_KEEP; + } else if (!strcmp(value, "ipv4")) { + turn_params.allocation_default_address_family = ALLOCATION_DEFAULT_ADDRESS_FAMILY_IPV4; + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: invalid allocation_default_address_family parameter\n"); + } + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: invalid allocation_default_address_family parameter\n"); + } + break; case SERVER_NAME_OPT: - STRCPY(turn_params.oauth_server_name,value); - break; + STRCPY(turn_params.oauth_server_name, value); + break; case OAUTH_OPT: - if( ENC_ALG_NUM == 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: option --oauth is not supported; ignored.\n"); - } else { - turn_params.oauth = get_bool_value(value); - } - break; + if (ENC_ALG_NUM == 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: option --oauth is not supported; ignored.\n"); + } else { + turn_params.oauth = get_bool_value(value); + } + break; case NO_SSLV2_OPT: - //deprecated - break; + // deprecated + break; case NO_SSLV3_OPT: - //deprecated - break; + // deprecated + break; case NO_TLSV1_OPT: - turn_params.no_tlsv1 = get_bool_value(value); - break; + turn_params.no_tlsv1 = get_bool_value(value); + break; case NO_TLSV1_1_OPT: - turn_params.no_tlsv1_1 = get_bool_value(value); - break; + turn_params.no_tlsv1_1 = get_bool_value(value); + break; case NO_TLSV1_2_OPT: - turn_params.no_tlsv1_2 = get_bool_value(value); - break; - case NE_TYPE_OPT: - { - int ne = atoi(value); - if((ne<(int)NEV_MIN)||(ne>(int)NEV_MAX)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: wrong version of the network engine: %d\n",ne); - } - turn_params.net_engine_version = (NET_ENG_VERSION)ne; - } - break; + turn_params.no_tlsv1_2 = get_bool_value(value); + break; + case NE_TYPE_OPT: { + int ne = atoi(value); + if ((ne < (int)NEV_MIN) || (ne > (int)NEV_MAX)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: wrong version of the network engine: %d\n", ne); + } + turn_params.net_engine_version = (NET_ENG_VERSION)ne; + } break; case DH566_OPT: - if(get_bool_value(value)) - turn_params.dh_key_size = DH_566; - break; + if (get_bool_value(value)) + turn_params.dh_key_size = DH_566; + break; case DH1066_OPT: - if(get_bool_value(value)) - turn_params.dh_key_size = DH_1066; - break; + if (get_bool_value(value)) + turn_params.dh_key_size = DH_1066; + break; case EC_CURVE_NAME_OPT: - STRCPY(turn_params.ec_curve_name,value); - break; + STRCPY(turn_params.ec_curve_name, value); + break; case CLI_MAX_SESSIONS_OPT: - cli_max_output_sessions = atoi(value); - break; + cli_max_output_sessions = atoi(value); + break; case SERVER_RELAY_OPT: - turn_params.server_relay = get_bool_value(value); - break; + turn_params.server_relay = get_bool_value(value); + break; case MOBILITY_OPT: - turn_params.mobility = get_bool_value(value); - break; + turn_params.mobility = get_bool_value(value); + break; case NO_CLI_OPT: - use_cli = !get_bool_value(value); - break; + use_cli = !get_bool_value(value); + break; case CLI_IP_OPT: - if(make_ioa_addr((const uint8_t*)value,0,&cli_addr)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot set cli address: %s\n",value); - } else{ - cli_addr_set = 1; - } - break; + if (make_ioa_addr((const uint8_t *)value, 0, &cli_addr) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot set cli address: %s\n", value); + } else { + cli_addr_set = 1; + } + break; case CLI_PORT_OPT: - cli_port = atoi(value); - break; + cli_port = atoi(value); + break; case CLI_PASSWORD_OPT: - STRCPY(cli_password,value); - break; + STRCPY(cli_password, value); + break; case WEB_ADMIN_OPT: - use_web_admin = get_bool_value(value); - break; + use_web_admin = get_bool_value(value); + break; case WEB_ADMIN_IP_OPT: - if(make_ioa_addr((const uint8_t*)value, 0, &web_admin_addr) < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot set web-admin address: %s\n", value); - } else { - web_admin_addr_set = 1; - } - break; + if (make_ioa_addr((const uint8_t *)value, 0, &web_admin_addr) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot set web-admin address: %s\n", value); + } else { + web_admin_addr_set = 1; + } + break; case WEB_ADMIN_PORT_OPT: - web_admin_port = atoi(value); - break; + web_admin_port = atoi(value); + break; case WEB_ADMIN_LISTEN_ON_WORKERS_OPT: - turn_params.web_admin_listen_on_workers = get_bool_value(value); - break; + turn_params.web_admin_listen_on_workers = get_bool_value(value); + break; #if defined(WINDOWS) - //TODO: implement it!!! + // TODO: implement it!!! #else case PROC_USER_OPT: { - struct passwd* pwd = getpwnam(value); - if(!pwd) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown user name: %s\n",value); - exit(-1); - } else { - procuserid = pwd->pw_uid; - procuserid_set = 1; - STRCPY(procusername,value); - } - } - break; - case PROC_GROUP_OPT: { - struct group* gr = getgrnam(value); - if(!gr) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown group name: %s\n",value); - exit(-1); - } else { - procgroupid = gr->gr_gid; - procgroupid_set = 1; - STRCPY(procgroupname,value); - } - } - break; -#endif - case 'i': - STRCPY(turn_params.relay_ifname, value); - break; - case 'm': - if(atoi(value)>MAX_NUMBER_OF_GENERAL_RELAY_SERVERS) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: max number of relay threads is 128.\n"); - turn_params.general_relay_servers_number = MAX_NUMBER_OF_GENERAL_RELAY_SERVERS; - } else if(atoi(value)<=0) { - turn_params.general_relay_servers_number = 0; - } else { - turn_params.general_relay_servers_number = atoi(value); - } - break; - case 'd': - STRCPY(turn_params.listener_ifname, value); - break; - case 'p': - turn_params.listener_port = atoi(value); - break; - case TLS_PORT_OPT: - turn_params.tls_listener_port = atoi(value); - break; - case ALT_PORT_OPT: - turn_params.alt_listener_port = atoi(value); - break; - case ALT_TLS_PORT_OPT: - turn_params.alt_tls_listener_port = atoi(value); - break; - case TCP_PROXY_PORT_OPT: - turn_params.tcp_proxy_port = atoi(value); - turn_params.tcp_use_proxy = 1; - break; - case MIN_PORT_OPT: - turn_params.min_port = atoi(value); - break; - case MAX_PORT_OPT: - turn_params.max_port = atoi(value); - break; - case SECURE_STUN_OPT: - turn_params.secure_stun = get_bool_value(value); - break; - case NO_MULTICAST_PEERS_OPT: - turn_params.no_multicast_peers = get_bool_value(value); - break; - case ALLOW_LOOPBACK_PEERS_OPT: - turn_params.allow_loopback_peers = get_bool_value(value); - break; - case STALE_NONCE_OPT: - turn_params.stale_nonce = get_int_value(value, STUN_DEFAULT_NONCE_EXPIRATION_TIME); - break; - case MAX_ALLOCATE_LIFETIME_OPT: - turn_params.max_allocate_lifetime = get_int_value(value, STUN_DEFAULT_MAX_ALLOCATE_LIFETIME); - break; - case CHANNEL_LIFETIME_OPT: - turn_params.channel_lifetime = get_int_value(value, STUN_DEFAULT_CHANNEL_LIFETIME); - break; - case PERMISSION_LIFETIME_OPT: - turn_params.permission_lifetime = get_int_value(value, STUN_DEFAULT_PERMISSION_LIFETIME); - break; - case MAX_ALLOCATE_TIMEOUT_OPT: - TURN_MAX_ALLOCATE_TIMEOUT = atoi(value); - TURN_MAX_ALLOCATE_TIMEOUT_STUN_ONLY = atoi(value); - break; - case 'S': - turn_params.stun_only = get_bool_value(value); - break; - case NO_STUN_OPT: - turn_params.no_stun = get_bool_value(value); - break; - case 'L': - add_listener_addr(value); - break; - case 'E': - add_relay_addr(value); - break; - case 'X': - if(value) { - char *div = strchr(value,'/'); - if(div) { - char *nval=strdup(value); - div = strchr(nval,'/'); - div[0]=0; - ++div; - ioa_addr apub,apriv; - if(make_ioa_addr((const uint8_t*)nval,0,&apub)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"-X : Wrong address format: %s\n",nval); - } else { - if(make_ioa_addr((const uint8_t*)div,0,&apriv)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"-X : Wrong address format: %s\n",div); - } else { - ioa_addr_add_mapping(&apub,&apriv); - if (add_ip_list_range((const char *)div, NULL, &turn_params.ip_whitelist) == 0) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Whitelisting external-ip private part: %s\n", div); - } - } - free(nval); - } else { - if(turn_params.external_ip) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "You cannot define external IP more than once in the configuration\n"); - } else { - turn_params.external_ip = (ioa_addr*)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(ioa_addr)); - if(make_ioa_addr((const uint8_t*)value,0,turn_params.external_ip)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"-X : Wrong address format: %s\n",value); - free(turn_params.external_ip); - turn_params.external_ip = NULL; - } - } - } - } - break; - case 'v': - if(turn_params.verbose != TURN_VERBOSE_EXTRA){ - if(get_bool_value(value)) { - turn_params.verbose = TURN_VERBOSE_NORMAL; - } else { - turn_params.verbose = TURN_VERBOSE_NONE; - } - } - break; - case 'V': - if(get_bool_value(value)) { - turn_params.verbose = TURN_VERBOSE_EXTRA; - } - break; - case 'o': - turn_params.turn_daemon = get_bool_value(value); - break; - case 'a': - if (get_bool_value(value)) { - turn_params.ct = TURN_CREDENTIALS_LONG_TERM; - use_lt_credentials=1; - use_ltc=1; - } else { - turn_params.ct = TURN_CREDENTIALS_UNDEFINED; - use_lt_credentials=0; - } - break; - case 'z': - if (!get_bool_value(value)) { - turn_params.ct = TURN_CREDENTIALS_UNDEFINED; - anon_credentials = 0; - } else { - turn_params.ct = TURN_CREDENTIALS_NONE; - anon_credentials = 1; - } - break; - case NO_SOFTWARE_ATTRIBUTE_OPT: - turn_params.no_software_attribute = get_bool_value(value); - break; - case 'f': - turn_params.fingerprint = get_bool_value(value); - break; - case 'u': - add_static_user_account(value); - break; - case 'b': - { -#if defined(TURN_NO_SQLITE) - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: Options -b, --userdb and --db are not supported because SQLite is not supported in this build.\n"); -#else - STRCPY(turn_params.default_users_db.persistent_users_db.userdb, value); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_SQLITE; + struct passwd *pwd = getpwnam(value); + if (!pwd) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown user name: %s\n", value); + exit(-1); + } else { + procuserid = pwd->pw_uid; + procuserid_set = 1; + STRCPY(procusername, value); + } + } break; + case PROC_GROUP_OPT: { + struct group *gr = getgrnam(value); + if (!gr) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown group name: %s\n", value); + exit(-1); + } else { + procgroupid = gr->gr_gid; + procgroupid_set = 1; + STRCPY(procgroupname, value); + } + } break; #endif + case 'i': + STRCPY(turn_params.relay_ifname, value); + break; + case 'm': + if (atoi(value) > MAX_NUMBER_OF_GENERAL_RELAY_SERVERS) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: max number of relay threads is 128.\n"); + turn_params.general_relay_servers_number = MAX_NUMBER_OF_GENERAL_RELAY_SERVERS; + } else if (atoi(value) <= 0) { + turn_params.general_relay_servers_number = 0; + } else { + turn_params.general_relay_servers_number = atoi(value); + } + break; + case 'd': + STRCPY(turn_params.listener_ifname, value); + break; + case 'p': + turn_params.listener_port = atoi(value); + break; + case TLS_PORT_OPT: + turn_params.tls_listener_port = atoi(value); + break; + case ALT_PORT_OPT: + turn_params.alt_listener_port = atoi(value); + break; + case ALT_TLS_PORT_OPT: + turn_params.alt_tls_listener_port = atoi(value); + break; + case TCP_PROXY_PORT_OPT: + turn_params.tcp_proxy_port = atoi(value); + turn_params.tcp_use_proxy = 1; + break; + case MIN_PORT_OPT: + turn_params.min_port = atoi(value); + break; + case MAX_PORT_OPT: + turn_params.max_port = atoi(value); + break; + case SECURE_STUN_OPT: + turn_params.secure_stun = get_bool_value(value); + break; + case NO_MULTICAST_PEERS_OPT: + turn_params.no_multicast_peers = get_bool_value(value); + break; + case ALLOW_LOOPBACK_PEERS_OPT: + turn_params.allow_loopback_peers = get_bool_value(value); + break; + case STALE_NONCE_OPT: + turn_params.stale_nonce = get_int_value(value, STUN_DEFAULT_NONCE_EXPIRATION_TIME); + break; + case MAX_ALLOCATE_LIFETIME_OPT: + turn_params.max_allocate_lifetime = get_int_value(value, STUN_DEFAULT_MAX_ALLOCATE_LIFETIME); + break; + case CHANNEL_LIFETIME_OPT: + turn_params.channel_lifetime = get_int_value(value, STUN_DEFAULT_CHANNEL_LIFETIME); + break; + case PERMISSION_LIFETIME_OPT: + turn_params.permission_lifetime = get_int_value(value, STUN_DEFAULT_PERMISSION_LIFETIME); + break; + case MAX_ALLOCATE_TIMEOUT_OPT: + TURN_MAX_ALLOCATE_TIMEOUT = atoi(value); + TURN_MAX_ALLOCATE_TIMEOUT_STUN_ONLY = atoi(value); + break; + case 'S': + turn_params.stun_only = get_bool_value(value); + break; + case NO_STUN_OPT: + turn_params.no_stun = get_bool_value(value); + break; + case 'L': + add_listener_addr(value); + break; + case 'E': + add_relay_addr(value); + break; + case 'X': + if (value) { + char *div = strchr(value, '/'); + if (div) { + char *nval = strdup(value); + div = strchr(nval, '/'); + div[0] = 0; + ++div; + ioa_addr apub, apriv; + if (make_ioa_addr((const uint8_t *)nval, 0, &apub) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "-X : Wrong address format: %s\n", nval); + } else { + if (make_ioa_addr((const uint8_t *)div, 0, &apriv) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "-X : Wrong address format: %s\n", div); + } else { + ioa_addr_add_mapping(&apub, &apriv); + if (add_ip_list_range((const char *)div, NULL, &turn_params.ip_whitelist) == 0) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Whitelisting external-ip private part: %s\n", div); + } } - break; + free(nval); + } else { + if (turn_params.external_ip) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "You cannot define external IP more than once in the configuration\n"); + } else { + turn_params.external_ip = + (ioa_addr *)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(ioa_addr)); + if (make_ioa_addr((const uint8_t *)value, 0, turn_params.external_ip) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "-X : Wrong address format: %s\n", value); + free(turn_params.external_ip); + turn_params.external_ip = NULL; + } + } + } + } + break; + case 'v': + if (turn_params.verbose != TURN_VERBOSE_EXTRA) { + if (get_bool_value(value)) { + turn_params.verbose = TURN_VERBOSE_NORMAL; + } else { + turn_params.verbose = TURN_VERBOSE_NONE; + } + } + break; + case 'V': + if (get_bool_value(value)) { + turn_params.verbose = TURN_VERBOSE_EXTRA; + } + break; + case 'o': + turn_params.turn_daemon = get_bool_value(value); + break; + case 'a': + if (get_bool_value(value)) { + turn_params.ct = TURN_CREDENTIALS_LONG_TERM; + use_lt_credentials = 1; + use_ltc = 1; + } else { + turn_params.ct = TURN_CREDENTIALS_UNDEFINED; + use_lt_credentials = 0; + } + break; + case 'z': + if (!get_bool_value(value)) { + turn_params.ct = TURN_CREDENTIALS_UNDEFINED; + anon_credentials = 0; + } else { + turn_params.ct = TURN_CREDENTIALS_NONE; + anon_credentials = 1; + } + break; + case NO_SOFTWARE_ATTRIBUTE_OPT: + turn_params.no_software_attribute = get_bool_value(value); + break; + case 'f': + turn_params.fingerprint = get_bool_value(value); + break; + case 'u': + add_static_user_account(value); + break; + case 'b': { +#if defined(TURN_NO_SQLITE) + TURN_LOG_FUNC( + TURN_LOG_LEVEL_WARNING, + "WARNING: Options -b, --userdb and --db are not supported because SQLite is not supported in this build.\n"); +#else + STRCPY(turn_params.default_users_db.persistent_users_db.userdb, value); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_SQLITE; +#endif + } break; #if !defined(TURN_NO_PQ) - case 'e': - STRCPY(turn_params.default_users_db.persistent_users_db.userdb, value); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_PQ; - break; + case 'e': + STRCPY(turn_params.default_users_db.persistent_users_db.userdb, value); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_PQ; + break; #endif #if !defined(TURN_NO_MYSQL) - case 'M': - STRCPY(turn_params.default_users_db.persistent_users_db.userdb, value); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MYSQL; - break; + case 'M': + STRCPY(turn_params.default_users_db.persistent_users_db.userdb, value); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MYSQL; + break; #endif #if !defined(TURN_NO_MONGO) - case 'J': - STRCPY(turn_params.default_users_db.persistent_users_db.userdb, value); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MONGO; - break; + case 'J': + STRCPY(turn_params.default_users_db.persistent_users_db.userdb, value); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MONGO; + break; #endif #if !defined(TURN_NO_HIREDIS) - case 'N': - STRCPY(turn_params.default_users_db.persistent_users_db.userdb, value); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_REDIS; - break; - case 'O': - STRCPY(turn_params.redis_statsdb.connection_string, value); - turn_params.use_redis_statsdb = 1; - break; + case 'N': + STRCPY(turn_params.default_users_db.persistent_users_db.userdb, value); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_REDIS; + break; + case 'O': + STRCPY(turn_params.redis_statsdb.connection_string, value); + turn_params.use_redis_statsdb = 1; + break; #endif - case PROMETHEUS_OPT: - turn_params.prometheus = 1; - break; - case PROMETHEUS_PORT_OPT: - turn_params.prometheus_port = atoi(value); - break; - case PROMETHEUS_ENABLE_USERNAMES_OPT: - turn_params.prometheus_username_labels = 1; - break; - case AUTH_SECRET_OPT: - turn_params.use_auth_secret_with_timestamp = 1; - use_tltc = 1; - turn_params.ct = TURN_CREDENTIALS_LONG_TERM; - use_lt_credentials = 1; - break; - case NO_AUTH_PINGS_OPT: - turn_params.no_auth_pings = 1; - break; - case NO_DYNAMIC_IP_LIST_OPT: - turn_params.no_dynamic_ip_list = 1; - break; - case NO_DYNAMIC_REALMS_OPT: - turn_params.no_dynamic_realms = 1; - break; - case STATIC_AUTH_SECRET_VAL_OPT: - add_to_secrets_list(&turn_params.default_users_db.ram_db.static_auth_secrets,value); - turn_params.use_auth_secret_with_timestamp = 1; - use_tltc = 1; - turn_params.ct = TURN_CREDENTIALS_LONG_TERM; - use_lt_credentials = 1; - break; - case AUTH_SECRET_TS_EXP: - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: Option --secret-ts-exp-time deprecated and has no effect.\n"); - break; - case 'r': - set_default_realm_name(value); - break; - case 'q': - turn_params.user_quota = (vint)atoi(value); - get_realm(NULL)->options.perf_options.user_quota = atoi(value); - break; - case 'Q': - turn_params.total_quota = (vint)atoi(value); - get_realm(NULL)->options.perf_options.total_quota = atoi(value); - break; - case 's': - turn_params.max_bps = (band_limit_t)strtoul(value,NULL,10); - get_realm(NULL)->options.perf_options.max_bps = (band_limit_t)strtoul(value,NULL,10); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%lu bytes per second allowed per session\n",(unsigned long)turn_params.max_bps); - break; - case 'B': - turn_params.bps_capacity = (band_limit_t)strtoul(value,NULL,10); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%lu bytes per second allowed, combined server capacity\n",(unsigned long)turn_params.bps_capacity); - break; - case CHECK_ORIGIN_CONSISTENCY_OPT: - turn_params.check_origin = get_bool_value(value); - break; - case NO_UDP_OPT: - turn_params.no_udp = get_bool_value(value); - break; - case NO_TCP_OPT: - turn_params.no_tcp = get_bool_value(value); - break; - case NO_UDP_RELAY_OPT: - turn_params.no_udp_relay = get_bool_value(value); - break; - case NO_TCP_RELAY_OPT: - turn_params.no_tcp_relay = get_bool_value(value); - break; - case NO_TLS_OPT: + case PROMETHEUS_OPT: + turn_params.prometheus = 1; + break; + case PROMETHEUS_PORT_OPT: + turn_params.prometheus_port = atoi(value); + break; + case PROMETHEUS_ENABLE_USERNAMES_OPT: + turn_params.prometheus_username_labels = 1; + break; + case AUTH_SECRET_OPT: + turn_params.use_auth_secret_with_timestamp = 1; + use_tltc = 1; + turn_params.ct = TURN_CREDENTIALS_LONG_TERM; + use_lt_credentials = 1; + break; + case NO_AUTH_PINGS_OPT: + turn_params.no_auth_pings = 1; + break; + case NO_DYNAMIC_IP_LIST_OPT: + turn_params.no_dynamic_ip_list = 1; + break; + case NO_DYNAMIC_REALMS_OPT: + turn_params.no_dynamic_realms = 1; + break; + case STATIC_AUTH_SECRET_VAL_OPT: + add_to_secrets_list(&turn_params.default_users_db.ram_db.static_auth_secrets, value); + turn_params.use_auth_secret_with_timestamp = 1; + use_tltc = 1; + turn_params.ct = TURN_CREDENTIALS_LONG_TERM; + use_lt_credentials = 1; + break; + case AUTH_SECRET_TS_EXP: + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: Option --secret-ts-exp-time deprecated and has no effect.\n"); + break; + case 'r': + set_default_realm_name(value); + break; + case 'q': + turn_params.user_quota = (vint)atoi(value); + get_realm(NULL)->options.perf_options.user_quota = atoi(value); + break; + case 'Q': + turn_params.total_quota = (vint)atoi(value); + get_realm(NULL)->options.perf_options.total_quota = atoi(value); + break; + case 's': + turn_params.max_bps = (band_limit_t)strtoul(value, NULL, 10); + get_realm(NULL)->options.perf_options.max_bps = (band_limit_t)strtoul(value, NULL, 10); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%lu bytes per second allowed per session\n", + (unsigned long)turn_params.max_bps); + break; + case 'B': + turn_params.bps_capacity = (band_limit_t)strtoul(value, NULL, 10); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%lu bytes per second allowed, combined server capacity\n", + (unsigned long)turn_params.bps_capacity); + break; + case CHECK_ORIGIN_CONSISTENCY_OPT: + turn_params.check_origin = get_bool_value(value); + break; + case NO_UDP_OPT: + turn_params.no_udp = get_bool_value(value); + break; + case NO_TCP_OPT: + turn_params.no_tcp = get_bool_value(value); + break; + case NO_UDP_RELAY_OPT: + turn_params.no_udp_relay = get_bool_value(value); + break; + case NO_TCP_RELAY_OPT: + turn_params.no_tcp_relay = get_bool_value(value); + break; + case NO_TLS_OPT: #if !TLS_SUPPORTED - turn_params.no_tls = 1; + turn_params.no_tls = 1; #else - turn_params.no_tls = get_bool_value(value); + turn_params.no_tls = get_bool_value(value); #endif - break; - case NO_DTLS_OPT: + break; + case NO_DTLS_OPT: #if DTLS_SUPPORTED - turn_params.no_dtls = get_bool_value(value); + turn_params.no_dtls = get_bool_value(value); #else - turn_params.no_dtls = 1; + turn_params.no_dtls = 1; #endif - break; - case CERT_FILE_OPT: - STRCPY(turn_params.cert_file,value); - break; - case CA_FILE_OPT: - STRCPY(turn_params.ca_cert_file,value); - break; - case DH_FILE_OPT: - STRCPY(turn_params.dh_file,value); - break; - case SECRET_KEY_OPT: - STRCPY(turn_params.secret_key_file,value); - break; - case PKEY_FILE_OPT: - STRCPY(turn_params.pkey_file,value); - break; - case PKEY_PWD_OPT: - STRCPY(turn_params.tls_password,value); - break; - case ALTERNATE_SERVER_OPT: - add_alternate_server(value); - break; - case AUX_SERVER_OPT: - add_aux_server(value); - break; - case UDP_SELF_BALANCE_OPT: - turn_params.udp_self_balance = get_bool_value(value); - break; - case TLS_ALTERNATE_SERVER_OPT: - add_tls_alternate_server(value); - break; - case ALLOWED_PEER_IPS: - if (add_ip_list_range(value, NULL, &turn_params.ip_whitelist) == 0) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "White listing: %s\n", value); - break; - case DENIED_PEER_IPS: - if (add_ip_list_range(value, NULL, &turn_params.ip_blacklist) == 0) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Black listing: %s\n", value); - break; - case CIPHER_LIST_OPT: - STRCPY(turn_params.cipher_list,value); - break; - case PIDFILE_OPT: - STRCPY(turn_params.pidfile,value); - break; - case ACME_REDIRECT_OPT: - STRCPY(turn_params.acme_redirect,value); - break; - case 'C': - if(value && *value) { - turn_params.rest_api_separator=*value; - } - break; - case LOG_BINDING_OPT: - turn_params.log_binding = get_bool_value(value); - break; - case NO_RFC5780: - turn_params.rfc5780 = 0; - break; - case NO_STUN_BACKWARD_COMPATIBILITY_OPT: - turn_params.no_stun_backward_compatibility = get_bool_value(value); - break; - case RESPONSE_ORIGIN_ONLY_WITH_RFC5780_OPT: - turn_params.response_origin_only_with_rfc5780 = get_bool_value(value); - break; + break; + case CERT_FILE_OPT: + STRCPY(turn_params.cert_file, value); + break; + case CA_FILE_OPT: + STRCPY(turn_params.ca_cert_file, value); + break; + case DH_FILE_OPT: + STRCPY(turn_params.dh_file, value); + break; + case SECRET_KEY_OPT: + STRCPY(turn_params.secret_key_file, value); + break; + case PKEY_FILE_OPT: + STRCPY(turn_params.pkey_file, value); + break; + case PKEY_PWD_OPT: + STRCPY(turn_params.tls_password, value); + break; + case ALTERNATE_SERVER_OPT: + add_alternate_server(value); + break; + case AUX_SERVER_OPT: + add_aux_server(value); + break; + case UDP_SELF_BALANCE_OPT: + turn_params.udp_self_balance = get_bool_value(value); + break; + case TLS_ALTERNATE_SERVER_OPT: + add_tls_alternate_server(value); + break; + case ALLOWED_PEER_IPS: + if (add_ip_list_range(value, NULL, &turn_params.ip_whitelist) == 0) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "White listing: %s\n", value); + break; + case DENIED_PEER_IPS: + if (add_ip_list_range(value, NULL, &turn_params.ip_blacklist) == 0) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Black listing: %s\n", value); + break; + case CIPHER_LIST_OPT: + STRCPY(turn_params.cipher_list, value); + break; + case PIDFILE_OPT: + STRCPY(turn_params.pidfile, value); + break; + case ACME_REDIRECT_OPT: + STRCPY(turn_params.acme_redirect, value); + break; + case 'C': + if (value && *value) { + turn_params.rest_api_separator = *value; + } + break; + case LOG_BINDING_OPT: + turn_params.log_binding = get_bool_value(value); + break; + case NO_RFC5780: + turn_params.rfc5780 = 0; + break; + case NO_STUN_BACKWARD_COMPATIBILITY_OPT: + turn_params.no_stun_backward_compatibility = get_bool_value(value); + break; + case RESPONSE_ORIGIN_ONLY_WITH_RFC5780_OPT: + turn_params.response_origin_only_with_rfc5780 = get_bool_value(value); + break; - /* these options have been already taken care of before: */ - case 'l': - case NO_STDOUT_LOG_OPT: - case SYSLOG_OPT: - case SIMPLE_LOG_OPT: - case NEW_LOG_TIMESTAMP_OPT: - case NEW_LOG_TIMESTAMP_FORMAT_OPT: - case SYSLOG_FACILITY_OPT: - case 'c': - case 'n': - case 'h': - break; - default: - fprintf(stderr,"\n%s\n", Usage); - exit(-1); + /* these options have been already taken care of before: */ + case 'l': + case NO_STDOUT_LOG_OPT: + case SYSLOG_OPT: + case SIMPLE_LOG_OPT: + case NEW_LOG_TIMESTAMP_OPT: + case NEW_LOG_TIMESTAMP_FORMAT_OPT: + case SYSLOG_FACILITY_OPT: + case 'c': + case 'n': + case 'h': + break; + default: + fprintf(stderr, "\n%s\n", Usage); + exit(-1); } if (turn_params.default_users_db.persistent_users_db.userdb[0]) { - char *userdb_sanitized = sanitize_userdb_string(turn_params.default_users_db.persistent_users_db.userdb); - STRCPY(turn_params.default_users_db.persistent_users_db.userdb_sanitized, userdb_sanitized); - free(userdb_sanitized); + char *userdb_sanitized = sanitize_userdb_string(turn_params.default_users_db.persistent_users_db.userdb); + STRCPY(turn_params.default_users_db.persistent_users_db.userdb_sanitized, userdb_sanitized); + free(userdb_sanitized); } if (turn_params.redis_statsdb.connection_string[0]) { - char *connection_string = sanitize_userdb_string(turn_params.redis_statsdb.connection_string); - STRCPY(turn_params.redis_statsdb.connection_string_sanitized, connection_string); - free(connection_string); + char *connection_string = sanitize_userdb_string(turn_params.redis_statsdb.connection_string); + STRCPY(turn_params.redis_statsdb.connection_string_sanitized, connection_string); + free(connection_string); } } -static int parse_arg_string(char *sarg, int *c, char **value) -{ - int i = 0; - char *name = sarg; - while(*sarg) { - if((*sarg==' ') || (*sarg=='=') || (*sarg=='\t')) { - *sarg=0; - do { - ++sarg; - } while((*sarg==' ') || (*sarg=='=') || (*sarg=='\t')); - *value = sarg; - break; - } - ++sarg; - *value=sarg; - } +static int parse_arg_string(char *sarg, int *c, char **value) { + int i = 0; + char *name = sarg; + while (*sarg) { + if ((*sarg == ' ') || (*sarg == '=') || (*sarg == '\t')) { + *sarg = 0; + do { + ++sarg; + } while ((*sarg == ' ') || (*sarg == '=') || (*sarg == '\t')); + *value = sarg; + break; + } + ++sarg; + *value = sarg; + } + if (value && *value && **value == '\"') { + *value += 1; + size_t len = strlen(*value); + while (len > 0 && (((*value)[len - 1] == '\n') || ((*value)[len - 1] == '\r') || ((*value)[len - 1] == ' ') || + ((*value)[len - 1] == '\t'))) { + (*value)[--len] = 0; + } + if (len > 0 && (*value)[len - 1] == '\"') { + (*value)[--len] = 0; + } + } - if(value && *value && **value=='\"') { - *value += 1; - size_t len = strlen(*value); - while(len>0 && ( - ((*value)[len-1]=='\n') || - ((*value)[len-1]=='\r') || - ((*value)[len-1]==' ') || - ((*value)[len-1]=='\t') - ) ) { - (*value)[--len]=0; - } - if(len>0 && (*value)[len-1]=='\"') { - (*value)[--len]=0; - } - } + while (long_options[i].name) { + if (strcmp(long_options[i].name, name)) { + ++i; + continue; + } + *c = long_options[i].val; + return 0; + } - while(long_options[i].name) { - if(strcmp(long_options[i].name,name)) { - ++i; - continue; - } - *c=long_options[i].val; - return 0; - } - - return -1; + return -1; } -static void read_config_file(int argc, char **argv, int pass) -{ - static char config_file[1025] = DEFAULT_CONFIG_FILE; +static void read_config_file(int argc, char **argv, int pass) { + static char config_file[1025] = DEFAULT_CONFIG_FILE; - if(pass == 0) { + if (pass == 0) { - if (argv) { - int i = 0; - for (i = 0; i < argc; i++) { - if (!strcmp(argv[i], "-c")) { - if (i < argc - 1) { - STRCPY(config_file, argv[i + 1]); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Wrong usage of -c option\n"); - } - } else if (!strcmp(argv[i], "-n")) { - turn_params.do_not_use_config_file = 1; - config_file[0]=0; - return; - } else if (!strcmp(argv[i], "-h")) { - printf("\n%s\n",Usage); - exit(0); - } else if (!strcmp(argv[i], "--version")) { - printf("%s\n",TURN_SERVER_VERSION); - exit(0); - } - } - } - } + if (argv) { + int i = 0; + for (i = 0; i < argc; i++) { + if (!strcmp(argv[i], "-c")) { + if (i < argc - 1) { + STRCPY(config_file, argv[i + 1]); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Wrong usage of -c option\n"); + } + } else if (!strcmp(argv[i], "-n")) { + turn_params.do_not_use_config_file = 1; + config_file[0] = 0; + return; + } else if (!strcmp(argv[i], "-h")) { + printf("\n%s\n", Usage); + exit(0); + } else if (!strcmp(argv[i], "--version")) { + printf("%s\n", TURN_SERVER_VERSION); + exit(0); + } + } + } + } - if (!turn_params.do_not_use_config_file && config_file[0]) { + if (!turn_params.do_not_use_config_file && config_file[0]) { - FILE *f = NULL; - char *full_path_to_config_file = NULL; + FILE *f = NULL; + char *full_path_to_config_file = NULL; - full_path_to_config_file = find_config_file(config_file, pass); - if (full_path_to_config_file) - f = fopen(full_path_to_config_file, "r"); + full_path_to_config_file = find_config_file(config_file, pass); + if (full_path_to_config_file) + f = fopen(full_path_to_config_file, "r"); - if (f) { + if (f) { - char sbuf[1025]; - char sarg[1035]; + char sbuf[1025]; + char sarg[1035]; - for (;;) { - char *s = fgets(sbuf, sizeof(sbuf) - 1, f); - if (!s) - break; - s = skip_blanks(s); - if (s[0] == '#') - continue; - if (!s[0]) - continue; - size_t slen = strlen(s); + for (;;) { + char *s = fgets(sbuf, sizeof(sbuf) - 1, f); + if (!s) + break; + s = skip_blanks(s); + if (s[0] == '#') + continue; + if (!s[0]) + continue; + size_t slen = strlen(s); - // strip white-spaces from config file lines end - while (slen && isspace(s[slen - 1])) - s[--slen] = 0; - if (slen) { - int c = 0; - char *value = NULL; - STRCPY(sarg, s); - if (parse_arg_string(sarg, &c, &value) < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Bad configuration format: %s\n", - sarg); - } else if((pass == 0) && (c == 'l')) { - set_logfile(value); - } else if((pass==0) && (c==NO_STDOUT_LOG_OPT)) { - set_no_stdout_log(get_bool_value(value)); - } else if((pass==0) && (c==SYSLOG_OPT)) { - set_log_to_syslog(get_bool_value(value)); - } else if((pass==0) && (c==SIMPLE_LOG_OPT)) { - set_simple_log(get_bool_value(value)); - } else if ((pass==0) && (c==NEW_LOG_TIMESTAMP_OPT)) { - use_new_log_timestamp_format=1; - } else if ((pass==0) && (c==NEW_LOG_TIMESTAMP_FORMAT_OPT)) { - set_turn_log_timestamp_format(value); - } else if((pass==0) && (c==SYSLOG_FACILITY_OPT)) { - set_syslog_facility(value); - } else if((pass == 1) && (c != 'u')) { - set_option(c, value); - } else if((pass == 2) && (c == 'u')) { - set_option(c, value); - } - if (s[slen - 1] == 59) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Check config! The following line ends with semicolon: \"%s\" \n",s); - } + // strip white-spaces from config file lines end + while (slen && isspace(s[slen - 1])) + s[--slen] = 0; + if (slen) { + int c = 0; + char *value = NULL; + STRCPY(sarg, s); + if (parse_arg_string(sarg, &c, &value) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Bad configuration format: %s\n", sarg); + } else if ((pass == 0) && (c == 'l')) { + set_logfile(value); + } else if ((pass == 0) && (c == NO_STDOUT_LOG_OPT)) { + set_no_stdout_log(get_bool_value(value)); + } else if ((pass == 0) && (c == SYSLOG_OPT)) { + set_log_to_syslog(get_bool_value(value)); + } else if ((pass == 0) && (c == SIMPLE_LOG_OPT)) { + set_simple_log(get_bool_value(value)); + } else if ((pass == 0) && (c == NEW_LOG_TIMESTAMP_OPT)) { + use_new_log_timestamp_format = 1; + } else if ((pass == 0) && (c == NEW_LOG_TIMESTAMP_FORMAT_OPT)) { + set_turn_log_timestamp_format(value); + } else if ((pass == 0) && (c == SYSLOG_FACILITY_OPT)) { + set_syslog_facility(value); + } else if ((pass == 1) && (c != 'u')) { + set_option(c, value); + } else if ((pass == 2) && (c == 'u')) { + set_option(c, value); + } + if (s[slen - 1] == 59) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Check config! The following line ends with semicolon: \"%s\" \n", s); + } + } + } - } - } + fclose(f); - fclose(f); + } else + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, + "WARNING: Cannot find config file: %s. Default and command-line settings will be used.\n", + config_file); - } else - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: Cannot find config file: %s. Default and command-line settings will be used.\n", - config_file); - - if (full_path_to_config_file) { - free(full_path_to_config_file); - full_path_to_config_file = NULL; - } - } + if (full_path_to_config_file) { + free(full_path_to_config_file); + full_path_to_config_file = NULL; + } + } } -static int disconnect_database(void) -{ - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->disconnect) { - dbd->disconnect(); - } - return 0; +static int disconnect_database(void) { + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->disconnect) { + dbd->disconnect(); + } + return 0; } -static int adminmain(int argc, char **argv) -{ - int c = 0; - int rc = 0; +static int adminmain(int argc, char **argv) { + int c = 0; + int rc = 0; - TURNADMIN_COMMAND_TYPE ct = TA_COMMAND_UNKNOWN; + TURNADMIN_COMMAND_TYPE ct = TA_COMMAND_UNKNOWN; - int is_admin = 0; - FILE* fptr; - unsigned char generated_key[16]; //changed + int is_admin = 0; + FILE *fptr; + unsigned char generated_key[16]; // changed - uint8_t user[STUN_MAX_USERNAME_SIZE+1]="\0"; - uint8_t realm[STUN_MAX_REALM_SIZE+1]="\0"; - uint8_t pwd[STUN_MAX_PWD_SIZE+1]="\0"; - uint8_t secret[AUTH_SECRET_SIZE+1]="\0"; - uint8_t origin[STUN_MAX_ORIGIN_SIZE+1]="\0"; - perf_options_t po = {(band_limit_t)-1,-1,-1}; + uint8_t user[STUN_MAX_USERNAME_SIZE + 1] = "\0"; + uint8_t realm[STUN_MAX_REALM_SIZE + 1] = "\0"; + uint8_t pwd[STUN_MAX_PWD_SIZE + 1] = "\0"; + uint8_t secret[AUTH_SECRET_SIZE + 1] = "\0"; + uint8_t origin[STUN_MAX_ORIGIN_SIZE + 1] = "\0"; + perf_options_t po = {(band_limit_t)-1, -1, -1}; - struct uoptions uo; - uo.u.m = admin_long_options; + struct uoptions uo; + uo.u.m = admin_long_options; - int print_enc_password = 0; - int print_enc_aes_password = 0; + int print_enc_password = 0; + int print_enc_aes_password = 0; - while (((c = getopt_long(argc, argv, ADMIN_OPTIONS, uo.u.o, NULL)) != -1)) { - switch (c){ - case 'P': - if(pwd[0]) { - char result[257]; - generate_new_enc_password((char*)pwd, result); - printf("%s\n",result); - exit(0); - } - print_enc_password = 1; - break; - case 'E': - print_enc_aes_password = 1; - break; - case 'g': - ct = TA_SET_REALM_OPTION; - break; - case 'G': - ct = TA_LIST_REALM_OPTIONS; - break; - case ADMIN_USER_QUOTA_OPT: - po.user_quota = (vint)atoi(optarg); - break; - case ADMIN_TOTAL_QUOTA_OPT: - po.total_quota = (vint)atoi(optarg); - break; - case ADMIN_MAX_BPS_OPT: - po.max_bps = (vint)atoi(optarg); - break; - case 'O': - ct = TA_ADD_ORIGIN; - break; - case 'R': - ct = TA_DEL_ORIGIN; - break; - case 'I': - ct = TA_LIST_ORIGINS; - break; - case 'o': - STRCPY(origin,optarg); - break; - case 'k': - ct = TA_PRINT_KEY; - break; - case 'a': - ct = TA_UPDATE_USER; - break; - case 'd': - ct = TA_DELETE_USER; - break; - case 'A': - ct = TA_UPDATE_USER; - is_admin = 1; - break; - case 'D': - ct = TA_DELETE_USER; - is_admin = 1; - break; - case 'l': - ct = TA_LIST_USERS; - break; - case 'L': - ct = TA_LIST_USERS; - is_admin = 1; - break; - case 's': - ct = TA_SET_SECRET; - STRCPY(secret,optarg); - break; - case 'S': - ct = TA_SHOW_SECRET; - break; - case 'X': - ct = TA_DEL_SECRET; - if(optarg) - STRCPY(secret,optarg); - break; - case DEL_ALL_AUTH_SECRETS_OPT: - ct = TA_DEL_SECRET; - break; + while (((c = getopt_long(argc, argv, ADMIN_OPTIONS, uo.u.o, NULL)) != -1)) { + switch (c) { + case 'P': + if (pwd[0]) { + char result[257]; + generate_new_enc_password((char *)pwd, result); + printf("%s\n", result); + exit(0); + } + print_enc_password = 1; + break; + case 'E': + print_enc_aes_password = 1; + break; + case 'g': + ct = TA_SET_REALM_OPTION; + break; + case 'G': + ct = TA_LIST_REALM_OPTIONS; + break; + case ADMIN_USER_QUOTA_OPT: + po.user_quota = (vint)atoi(optarg); + break; + case ADMIN_TOTAL_QUOTA_OPT: + po.total_quota = (vint)atoi(optarg); + break; + case ADMIN_MAX_BPS_OPT: + po.max_bps = (vint)atoi(optarg); + break; + case 'O': + ct = TA_ADD_ORIGIN; + break; + case 'R': + ct = TA_DEL_ORIGIN; + break; + case 'I': + ct = TA_LIST_ORIGINS; + break; + case 'o': + STRCPY(origin, optarg); + break; + case 'k': + ct = TA_PRINT_KEY; + break; + case 'a': + ct = TA_UPDATE_USER; + break; + case 'd': + ct = TA_DELETE_USER; + break; + case 'A': + ct = TA_UPDATE_USER; + is_admin = 1; + break; + case 'D': + ct = TA_DELETE_USER; + is_admin = 1; + break; + case 'l': + ct = TA_LIST_USERS; + break; + case 'L': + ct = TA_LIST_USERS; + is_admin = 1; + break; + case 's': + ct = TA_SET_SECRET; + STRCPY(secret, optarg); + break; + case 'S': + ct = TA_SHOW_SECRET; + break; + case 'X': + ct = TA_DEL_SECRET; + if (optarg) + STRCPY(secret, optarg); + break; + case DEL_ALL_AUTH_SECRETS_OPT: + ct = TA_DEL_SECRET; + break; #if !defined(TURN_NO_SQLITE) - case 'b': - STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_SQLITE; - break; + case 'b': + STRCPY(turn_params.default_users_db.persistent_users_db.userdb, optarg); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_SQLITE; + break; #endif #if !defined(TURN_NO_PQ) - case 'e': - STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_PQ; - break; + case 'e': + STRCPY(turn_params.default_users_db.persistent_users_db.userdb, optarg); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_PQ; + break; #endif #if !defined(TURN_NO_MYSQL) - case 'M': - STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MYSQL; - break; + case 'M': + STRCPY(turn_params.default_users_db.persistent_users_db.userdb, optarg); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MYSQL; + break; #endif #if !defined(TURN_NO_MONGO) - case 'J': - STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MONGO; - break; + case 'J': + STRCPY(turn_params.default_users_db.persistent_users_db.userdb, optarg); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MONGO; + break; #endif #if !defined(TURN_NO_HIREDIS) - case 'N': - STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_REDIS; - break; + case 'N': + STRCPY(turn_params.default_users_db.persistent_users_db.userdb, optarg); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_REDIS; + break; #endif - case 'u': - STRCPY(user,optarg); - if(!is_secure_string((uint8_t*)user,1)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name structure or symbols, choose another name: %s\n",user); - exit(-1); - } - if(SASLprep((uint8_t*)user)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name: %s\n",user); - exit(-1); - } - break; - case 'r': - set_default_realm_name(optarg); - STRCPY(realm,optarg); - if(SASLprep((uint8_t*)realm)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong realm: %s\n",realm); - exit(-1); - } - break; - case 'p': - STRCPY(pwd,optarg); - if(SASLprep((uint8_t*)pwd)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong password: %s\n",pwd); - exit(-1); - } - if(print_enc_password) { - char result[257]; - generate_new_enc_password((char*)pwd, result); - printf("%s\n",result); - exit(0); - } - if(print_enc_aes_password){ - encrypt_aes_128(pwd, generated_key); - exit(0); - } - break; - case 'x': - generate_aes_128_key(optarg, generated_key); - exit(0); - break; - case 'f': - fptr = fopen((char*)optarg, "r"); - if(fptr == NULL){ - printf("No such file like %s\n", (char*)optarg); - } - else{ - fseek (fptr, 0, SEEK_SET); - rc = fread(generated_key, sizeof(char), 16, fptr); - if( rc == 0 ){ - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: Secret-Key file is empty\n",__FUNCTION__); - } - else{ - if( rc != 16 ){ - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: Secret-Key length is not enough\n",__FUNCTION__); - } - } - fclose (fptr); - } - break; - case 'v': - decrypt_aes_128((char*)optarg, generated_key); - exit(0); - case 'h': - printf("\n%s\n", AdminUsage); - exit(0); - break; - default: - fprintf(stderr,"\n%s\n", AdminUsage); - exit(-1); - } - } + case 'u': + STRCPY(user, optarg); + if (!is_secure_string((uint8_t *)user, 1)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name structure or symbols, choose another name: %s\n", user); + exit(-1); + } + if (SASLprep((uint8_t *)user) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name: %s\n", user); + exit(-1); + } + break; + case 'r': + set_default_realm_name(optarg); + STRCPY(realm, optarg); + if (SASLprep((uint8_t *)realm) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong realm: %s\n", realm); + exit(-1); + } + break; + case 'p': + STRCPY(pwd, optarg); + if (SASLprep((uint8_t *)pwd) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong password: %s\n", pwd); + exit(-1); + } + if (print_enc_password) { + char result[257]; + generate_new_enc_password((char *)pwd, result); + printf("%s\n", result); + exit(0); + } + if (print_enc_aes_password) { + encrypt_aes_128(pwd, generated_key); + exit(0); + } + break; + case 'x': + generate_aes_128_key(optarg, generated_key); + exit(0); + break; + case 'f': + fptr = fopen((char *)optarg, "r"); + if (fptr == NULL) { + printf("No such file like %s\n", (char *)optarg); + } else { + fseek(fptr, 0, SEEK_SET); + rc = fread(generated_key, sizeof(char), 16, fptr); + if (rc == 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: Secret-Key file is empty\n", __FUNCTION__); + } else { + if (rc != 16) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: Secret-Key length is not enough\n", __FUNCTION__); + } + } + fclose(fptr); + } + break; + case 'v': + decrypt_aes_128((char *)optarg, generated_key); + exit(0); + case 'h': + printf("\n%s\n", AdminUsage); + exit(0); + break; + default: + fprintf(stderr, "\n%s\n", AdminUsage); + exit(-1); + } + } #if !defined(TURN_NO_SQLITE) - if(!strlen(turn_params.default_users_db.persistent_users_db.userdb) && (turn_params.default_users_db.userdb_type == TURN_USERDB_TYPE_SQLITE)) - strncpy(turn_params.default_users_db.persistent_users_db.userdb,DEFAULT_USERDB_FILE, TURN_LONG_STRING_SIZE); + if (!strlen(turn_params.default_users_db.persistent_users_db.userdb) && + (turn_params.default_users_db.userdb_type == TURN_USERDB_TYPE_SQLITE)) + strncpy(turn_params.default_users_db.persistent_users_db.userdb, DEFAULT_USERDB_FILE, TURN_LONG_STRING_SIZE); #endif - if(ct == TA_COMMAND_UNKNOWN) { - fprintf(stderr,"\n%s\n", AdminUsage); - exit(-1); - } + if (ct == TA_COMMAND_UNKNOWN) { + fprintf(stderr, "\n%s\n", AdminUsage); + exit(-1); + } - argc -= optind; - argv += optind; + argc -= optind; + argv += optind; - if(argc != 0) { - fprintf(stderr,"\n%s\n", AdminUsage); - exit(-1); - } + if (argc != 0) { + fprintf(stderr, "\n%s\n", AdminUsage); + exit(-1); + } - int result = adminuser(user, realm, pwd, secret, origin, ct, &po, is_admin); + int result = adminuser(user, realm, pwd, secret, origin, ct, &po, is_admin); - disconnect_database(); + disconnect_database(); - return result; + return result; } -static void print_features(unsigned long mfn) -{ - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\nRFC 3489/5389/5766/5780/6062/6156 STUN/TURN Server\nVersion %s\n",TURN_SOFTWARE); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\nMax number of open files/sockets allowed for this process: %lu\n",mfn); - if(turn_params.net_engine_version == NEV_UDP_SOCKET_PER_ENDPOINT) - mfn = mfn/3; - else - mfn = mfn/2; - mfn = ((unsigned long)(mfn/500))*500; - if(mfn<500) - mfn = 500; - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\nDue to the open files/sockets limitation,\nmax supported number of TURN Sessions possible is: %lu (approximately)\n",mfn); +static void print_features(unsigned long mfn) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\nRFC 3489/5389/5766/5780/6062/6156 STUN/TURN Server\nVersion %s\n", + TURN_SOFTWARE); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\nMax number of open files/sockets allowed for this process: %lu\n", mfn); + if (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_ENDPOINT) + mfn = mfn / 3; + else + mfn = mfn / 2; + mfn = ((unsigned long)(mfn / 500)) * 500; + if (mfn < 500) + mfn = 500; + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, + "\nDue to the open files/sockets limitation,\nmax supported number of TURN Sessions possible is: %lu " + "(approximately)\n", + mfn); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n\n==== Show him the instruments, Practical Frost: ====\n\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n\n==== Show him the instruments, Practical Frost: ====\n\n"); - /* - Frost stepped forward and opened the polished case with a theatrical - flourish. It was a masterful piece of craftsmanship. As the lid was - pulled back, the many trays inside lifted and fanned out, displaying - Glokta’s tools in all their gruesome glory. There were blades of every - size and shape, needles curved and straight, bottles of oil and acid, - nails and screws, clamps and pliers, saws, hammers, chisels. Metal, wood - and glass glittered in the bright lamplight, all polished to mirror - brightness and honed to a murderous sharpness. - */ + /* + Frost stepped forward and opened the polished case with a theatrical + flourish. It was a masterful piece of craftsmanship. As the lid was + pulled back, the many trays inside lifted and fanned out, displaying + Glokta’s tools in all their gruesome glory. There were blades of every + size and shape, needles curved and straight, bottles of oil and acid, + nails and screws, clamps and pliers, saws, hammers, chisels. Metal, wood + and glass glittered in the bright lamplight, all polished to mirror + brightness and honed to a murderous sharpness. + */ #if !TLS_SUPPORTED - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS is not supported\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS is not supported\n"); #else - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS supported\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS supported\n"); #endif #if !DTLS_SUPPORTED - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS is not supported\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS is not supported\n"); #else - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS supported\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS supported\n"); #if DTLSv1_2_SUPPORTED - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS 1.2 supported\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS 1.2 supported\n"); #else - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS 1.2 is not supported\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS 1.2 is not supported\n"); #endif #endif #if ALPN_SUPPORTED - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TURN/STUN ALPN supported\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TURN/STUN ALPN supported\n"); #else - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TURN/STUN ALPN is not supported\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TURN/STUN ALPN is not supported\n"); #endif - if(ENC_ALG_NUM == 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Third-party authorization (oAuth) is not supported\n"); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Third-party authorization (oAuth) supported\n"); + if (ENC_ALG_NUM == 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Third-party authorization (oAuth) is not supported\n"); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Third-party authorization (oAuth) supported\n"); #if defined(TURN_NO_GCM) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "GCM (AEAD) is not supported\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "GCM (AEAD) is not supported\n"); #else - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "GCM (AEAD) supported\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "GCM (AEAD) supported\n"); #endif - } + } - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "OpenSSL compile-time version: %s (0x%lx)\n",OPENSSL_VERSION_TEXT,OPENSSL_VERSION_NUMBER); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "OpenSSL compile-time version: %s (0x%lx)\n", OPENSSL_VERSION_TEXT, + OPENSSL_VERSION_NUMBER); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n"); #if !defined(TURN_NO_SQLITE) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SQLite supported, default database location is %s\n",DEFAULT_USERDB_FILE); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SQLite supported, default database location is %s\n", DEFAULT_USERDB_FILE); #else - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SQLite is not supported\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SQLite is not supported\n"); #endif #if !defined(TURN_NO_HIREDIS) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Redis supported\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Redis supported\n"); #else - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Redis is not supported\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Redis is not supported\n"); #endif #if !defined(TURN_NO_PQ) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "PostgreSQL supported\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "PostgreSQL supported\n"); #else - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "PostgreSQL is not supported\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "PostgreSQL is not supported\n"); #endif #if !defined(TURN_NO_MYSQL) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MySQL supported\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MySQL supported\n"); #else - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MySQL is not supported\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MySQL is not supported\n"); #endif #if !defined(TURN_NO_MONGO) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MongoDB supported\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MongoDB supported\n"); #else - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MongoDB is not supported\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MongoDB is not supported\n"); #endif - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n"); - - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Default Net Engine version: %d (%s)\n\n=====================================================\n\n", (int)turn_params.net_engine_version, turn_params.net_engine_version_txt[(int)turn_params.net_engine_version]); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, + "Default Net Engine version: %d (%s)\n\n=====================================================\n\n", + (int)turn_params.net_engine_version, + turn_params.net_engine_version_txt[(int)turn_params.net_engine_version]); } -#if defined(__linux__) || defined(__LINUX__) || defined(__linux) || defined(linux__) || defined(LINUX) || defined(__LINUX) || defined(LINUX__) +#if defined(__linux__) || defined(__LINUX__) || defined(__linux) || defined(linux__) || defined(LINUX) || \ + defined(__LINUX) || defined(LINUX__) #include #endif -static void set_network_engine(void) -{ - if(turn_params.net_engine_version != NEV_UNKNOWN) - return; - turn_params.net_engine_version = NEV_UDP_SOCKET_PER_ENDPOINT; +static void set_network_engine(void) { + if (turn_params.net_engine_version != NEV_UNKNOWN) + return; + turn_params.net_engine_version = NEV_UDP_SOCKET_PER_ENDPOINT; #if defined(SO_REUSEPORT) -#if defined(__linux__) || defined(__LINUX__) || defined(__linux) || defined(linux__) || defined(LINUX) || defined(__LINUX) || defined(LINUX__) - turn_params.net_engine_version = NEV_UDP_SOCKET_PER_THREAD; -#else /* BSD ? */ - turn_params.net_engine_version = NEV_UDP_SOCKET_PER_SESSION; +#if defined(__linux__) || defined(__LINUX__) || defined(__linux) || defined(linux__) || defined(LINUX) || \ + defined(__LINUX) || defined(LINUX__) + turn_params.net_engine_version = NEV_UDP_SOCKET_PER_THREAD; +#else /* BSD ? */ + turn_params.net_engine_version = NEV_UDP_SOCKET_PER_SESSION; #endif /* Linux */ -#else /* defined(SO_REUSEPORT) */ -#if defined(__linux__) || defined(__LINUX__) || defined(__linux) || defined(linux__) || defined(LINUX) || defined(__LINUX) || defined(LINUX__) -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) - //net_engine_version = NEV_UDP_SOCKET_PER_SESSION; - turn_params.net_engine_version = NEV_UDP_SOCKET_PER_ENDPOINT; +#else /* defined(SO_REUSEPORT) */ +#if defined(__linux__) || defined(__LINUX__) || defined(__linux) || defined(linux__) || defined(LINUX) || \ + defined(__LINUX) || defined(LINUX__) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33) + // net_engine_version = NEV_UDP_SOCKET_PER_SESSION; + turn_params.net_engine_version = NEV_UDP_SOCKET_PER_ENDPOINT; #else - turn_params.net_engine_version = NEV_UDP_SOCKET_PER_ENDPOINT; + turn_params.net_engine_version = NEV_UDP_SOCKET_PER_ENDPOINT; #endif /* Linux version */ #endif /* Linux */ #endif /* defined(SO_REUSEPORT) */ - } -static void drop_privileges(void) -{ +static void drop_privileges(void) { #if defined(WINDOWS) - //TODO: implement it!!! + // TODO: implement it!!! #else - setgroups(0, NULL); - if(procgroupid_set) { - if(getgid() != procgroupid) { - if (setgid(procgroupid) != 0) { - perror("setgid: Unable to change group privileges"); - exit(-1); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "New GID: %s(%lu)\n", procgroupname, (unsigned long)procgroupid); - } - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Keep GID: %s(%lu)\n", procgroupname, (unsigned long)procgroupid); - } - } + setgroups(0, NULL); + if (procgroupid_set) { + if (getgid() != procgroupid) { + if (setgid(procgroupid) != 0) { + perror("setgid: Unable to change group privileges"); + exit(-1); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "New GID: %s(%lu)\n", procgroupname, (unsigned long)procgroupid); + } + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Keep GID: %s(%lu)\n", procgroupname, (unsigned long)procgroupid); + } + } - if(procuserid_set) { - if(procuserid != getuid()) { - if (setuid(procuserid) != 0) { - perror("setuid: Unable to change user privileges"); - exit(-1); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "New UID: %s(%lu)\n", procusername, (unsigned long)procuserid); - } - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Keep UID: %s(%lu)\n", procusername, (unsigned long)procuserid); - } - } + if (procuserid_set) { + if (procuserid != getuid()) { + if (setuid(procuserid) != 0) { + perror("setuid: Unable to change user privileges"); + exit(-1); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "New UID: %s(%lu)\n", procusername, (unsigned long)procuserid); + } + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Keep UID: %s(%lu)\n", procusername, (unsigned long)procuserid); + } + } #endif } -static void init_domain(void) -{ +static void init_domain(void) { #if !defined(TURN_NO_GETDOMAINNAME) - if (getdomainname(turn_params.domain, sizeof(turn_params.domain) - 1) < 0) { - turn_params.domain[0] = 0; - } else if (!strcmp(turn_params.domain, "(none)")) { - turn_params.domain[0] = 0; - } + if (getdomainname(turn_params.domain, sizeof(turn_params.domain) - 1) < 0) { + turn_params.domain[0] = 0; + } else if (!strcmp(turn_params.domain, "(none)")) { + turn_params.domain[0] = 0; + } #endif } -int main(int argc, char **argv) -{ - int c = 0; +int main(int argc, char **argv) { + int c = 0; - IS_TURN_SERVER = 1; + IS_TURN_SERVER = 1; - TURN_MUTEX_INIT(&turn_params.tls_mutex); + TURN_MUTEX_INIT(&turn_params.tls_mutex); - set_execdir(); + set_execdir(); - init_super_memory(); + init_super_memory(); - init_domain(); - create_default_realm(); + init_domain(); + create_default_realm(); - init_turn_server_addrs_list(&turn_params.alternate_servers_list); - init_turn_server_addrs_list(&turn_params.tls_alternate_servers_list); - init_turn_server_addrs_list(&turn_params.aux_servers_list); + init_turn_server_addrs_list(&turn_params.alternate_servers_list); + init_turn_server_addrs_list(&turn_params.tls_alternate_servers_list); + init_turn_server_addrs_list(&turn_params.aux_servers_list); - set_network_engine(); + set_network_engine(); - init_listener(); - init_secrets_list(&turn_params.default_users_db.ram_db.static_auth_secrets); - init_dynamic_ip_lists(); + init_listener(); + init_secrets_list(&turn_params.default_users_db.ram_db.static_auth_secrets); + init_dynamic_ip_lists(); - if (!strstr(argv[0], "turnadmin")) { + if (!strstr(argv[0], "turnadmin")) { - struct uoptions uo; - uo.u.m = long_options; + struct uoptions uo; + uo.u.m = long_options; - while (((c = getopt_long(argc, argv, OPTIONS, uo.u.o, NULL)) != -1)) { - switch (c){ - case 'l': - set_logfile(optarg); - break; - case NO_STDOUT_LOG_OPT: - set_no_stdout_log(get_bool_value(optarg)); - break; - case SYSLOG_OPT: - set_log_to_syslog(get_bool_value(optarg)); - break; - case SIMPLE_LOG_OPT: - set_simple_log(get_bool_value(optarg)); - break; - case NEW_LOG_TIMESTAMP_OPT: - use_new_log_timestamp_format=1; - break; - case NEW_LOG_TIMESTAMP_FORMAT_OPT: - set_turn_log_timestamp_format(optarg); - break; - case SYSLOG_FACILITY_OPT: - set_syslog_facility(optarg); - break; - default: - ; - } - } - } + while (((c = getopt_long(argc, argv, OPTIONS, uo.u.o, NULL)) != -1)) { + switch (c) { + case 'l': + set_logfile(optarg); + break; + case NO_STDOUT_LOG_OPT: + set_no_stdout_log(get_bool_value(optarg)); + break; + case SYSLOG_OPT: + set_log_to_syslog(get_bool_value(optarg)); + break; + case SIMPLE_LOG_OPT: + set_simple_log(get_bool_value(optarg)); + break; + case NEW_LOG_TIMESTAMP_OPT: + use_new_log_timestamp_format = 1; + break; + case NEW_LOG_TIMESTAMP_FORMAT_OPT: + set_turn_log_timestamp_format(optarg); + break; + case SYSLOG_FACILITY_OPT: + set_syslog_facility(optarg); + break; + default:; + } + } + } - optind = 0; + optind = 0; #if !TLS_SUPPORTED - turn_params.no_tls = 1; + turn_params.no_tls = 1; #endif #if !DTLS_SUPPORTED - turn_params.no_dtls = 1; + turn_params.no_dtls = 1; #endif - { - int cpus = get_system_number_of_cpus(); - if (0 < cpus) - turn_params.cpus = get_system_number_of_cpus(); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "System cpu num is %lu\n", turn_params.cpus); - if (turn_params.cpus < DEFAULT_CPUS_NUMBER) - turn_params.cpus = DEFAULT_CPUS_NUMBER; - else if (turn_params.cpus > MAX_NUMBER_OF_GENERAL_RELAY_SERVERS) - turn_params.cpus = MAX_NUMBER_OF_GENERAL_RELAY_SERVERS; + { + int cpus = get_system_number_of_cpus(); + if (0 < cpus) + turn_params.cpus = get_system_number_of_cpus(); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "System cpu num is %lu\n", turn_params.cpus); + if (turn_params.cpus < DEFAULT_CPUS_NUMBER) + turn_params.cpus = DEFAULT_CPUS_NUMBER; + else if (turn_params.cpus > MAX_NUMBER_OF_GENERAL_RELAY_SERVERS) + turn_params.cpus = MAX_NUMBER_OF_GENERAL_RELAY_SERVERS; - turn_params.general_relay_servers_number = (turnserver_id)turn_params.cpus; - } + turn_params.general_relay_servers_number = (turnserver_id)turn_params.cpus; + } - memset(&turn_params.default_users_db, 0, sizeof(default_users_db_t)); - turn_params.default_users_db.ram_db.static_accounts = ur_string_map_create(free); + memset(&turn_params.default_users_db, 0, sizeof(default_users_db_t)); + turn_params.default_users_db.ram_db.static_accounts = ur_string_map_create(free); - if(strstr(argv[0], "turnadmin")) - return adminmain(argc,argv); - // Zero pass apply the log options. - read_config_file(argc,argv,0); - // First pass read other config options - read_config_file(argc,argv,1); + if (strstr(argv[0], "turnadmin")) + return adminmain(argc, argv); + // Zero pass apply the log options. + read_config_file(argc, argv, 0); + // First pass read other config options + read_config_file(argc, argv, 1); - struct uoptions uo; - uo.u.m = long_options; + struct uoptions uo; + uo.u.m = long_options; - while (((c = getopt_long(argc, argv, OPTIONS, uo.u.o, NULL)) != -1)) { - if(c != 'u') - set_option(c,optarg); - } + while (((c = getopt_long(argc, argv, OPTIONS, uo.u.o, NULL)) != -1)) { + if (c != 'u') + set_option(c, optarg); + } - // Second pass read -u options - read_config_file(argc,argv,2); + // Second pass read -u options + read_config_file(argc, argv, 2); - { - unsigned long mfn = set_system_parameters(1); + { + unsigned long mfn = set_system_parameters(1); - print_features(mfn); - } + print_features(mfn); + } - if(!get_realm(NULL)->options.name[0]) { - STRCPY(get_realm(NULL)->options.name,turn_params.domain); - } + if (!get_realm(NULL)->options.name[0]) { + STRCPY(get_realm(NULL)->options.name, turn_params.domain); + } - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Domain name: %s\n",turn_params.domain); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Default realm: %s\n",get_realm(NULL)->options.name); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Domain name: %s\n", turn_params.domain); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Default realm: %s\n", get_realm(NULL)->options.name); - if(turn_params.acme_redirect[0]) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect URL: %s\n",turn_params.acme_redirect); - } - if(turn_params.oauth && turn_params.oauth_server_name[0]) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "oAuth server name: %s\n",turn_params.oauth_server_name); - } + if (turn_params.acme_redirect[0]) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect URL: %s\n", turn_params.acme_redirect); + } + if (turn_params.oauth && turn_params.oauth_server_name[0]) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "oAuth server name: %s\n", turn_params.oauth_server_name); + } - optind = 0; + optind = 0; - while (((c = getopt_long(argc, argv, OPTIONS, uo.u.o, NULL)) != -1)) { - if(c == 'u') { - set_option(c,optarg); - } - } + while (((c = getopt_long(argc, argv, OPTIONS, uo.u.o, NULL)) != -1)) { + if (c == 'u') { + set_option(c, optarg); + } + } - if(turn_params.bps_capacity && !(turn_params.max_bps)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nCONFIG ERROR: If you set the --bps-capacity option, then you must set --max-bps options, too.\n"); - exit(-1); - } + if (turn_params.bps_capacity && !(turn_params.max_bps)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, + "\nCONFIG ERROR: If you set the --bps-capacity option, then you must set --max-bps options, too.\n"); + exit(-1); + } - if(turn_params.no_udp_relay && turn_params.no_tcp_relay) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nCONFIG ERROR: --no-udp-relay and --no-tcp-relay options cannot be used together.\n"); - exit(-1); - } + if (turn_params.no_udp_relay && turn_params.no_tcp_relay) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, + "\nCONFIG ERROR: --no-udp-relay and --no-tcp-relay options cannot be used together.\n"); + exit(-1); + } - if(turn_params.no_udp_relay) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\nCONFIG: --no-udp-relay: UDP relay endpoints are not allowed.\n"); - } + if (turn_params.no_udp_relay) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\nCONFIG: --no-udp-relay: UDP relay endpoints are not allowed.\n"); + } - if(turn_params.no_tcp_relay) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\nCONFIG: --no-tcp-relay: TCP relay endpoints are not allowed.\n"); - } + if (turn_params.no_tcp_relay) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\nCONFIG: --no-tcp-relay: TCP relay endpoints are not allowed.\n"); + } - if(turn_params.server_relay) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "\nCONFIG: WARNING: --server-relay: NON-STANDARD AND DANGEROUS OPTION.\n"); - } + if (turn_params.server_relay) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "\nCONFIG: WARNING: --server-relay: NON-STANDARD AND DANGEROUS OPTION.\n"); + } #if !defined(TURN_NO_SQLITE) - if(!strlen(turn_params.default_users_db.persistent_users_db.userdb) && (turn_params.default_users_db.userdb_type == TURN_USERDB_TYPE_SQLITE)) - strncpy(turn_params.default_users_db.persistent_users_db.userdb,DEFAULT_USERDB_FILE, TURN_LONG_STRING_SIZE); + if (!strlen(turn_params.default_users_db.persistent_users_db.userdb) && + (turn_params.default_users_db.userdb_type == TURN_USERDB_TYPE_SQLITE)) + strncpy(turn_params.default_users_db.persistent_users_db.userdb, DEFAULT_USERDB_FILE, TURN_LONG_STRING_SIZE); #endif - argc -= optind; - argv += optind; + argc -= optind; + argv += optind; - if(argc>0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nCONFIGURATION ALERT: Unknown argument: %s\n",argv[argc-1]); - } + if (argc > 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nCONFIGURATION ALERT: Unknown argument: %s\n", argv[argc - 1]); + } - if(use_lt_credentials && anon_credentials) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nCONFIG ERROR: -a and -z options cannot be used together.\n"); - exit(-1); - } + if (use_lt_credentials && anon_credentials) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nCONFIG ERROR: -a and -z options cannot be used together.\n"); + exit(-1); + } - if(use_ltc && use_tltc) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "\nCONFIGURATION ALERT: You specified --lt-cred-mech and --use-auth-secret in the same time.\n" - "Be aware that you could not mix the username/password and the shared secret based auth methods. \n" - "Shared secret overrides username/password based auth method. Check your configuration!\n"); - } + if (use_ltc && use_tltc) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, + "\nCONFIGURATION ALERT: You specified --lt-cred-mech and --use-auth-secret in the same time.\n" + "Be aware that you could not mix the username/password and the shared secret based auth methods. \n" + "Shared secret overrides username/password based auth method. Check your configuration!\n"); + } - if(turn_params.allow_loopback_peers) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "CONFIG WARNING: allow_loopback_peers opens a possible security vulnerability. Do not use in production!!\n"); - if(cli_password[0]==0 && use_cli) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nCONFIG ERROR: allow_loopback_peers and empty cli password cannot be used together.\n"); - exit(-1); - } + if (turn_params.allow_loopback_peers) { + TURN_LOG_FUNC( + TURN_LOG_LEVEL_WARNING, + "CONFIG WARNING: allow_loopback_peers opens a possible security vulnerability. Do not use in production!!\n"); + if (cli_password[0] == 0 && use_cli) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, + "\nCONFIG ERROR: allow_loopback_peers and empty cli password cannot be used together.\n"); + exit(-1); + } + } + + if (use_cli && cli_password[0] == 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nCONFIG ERROR: Empty cli-password, and so telnet cli interface is disabled! " + "Please set a non empty cli-password!\n"); + use_cli = 0; + } + + if (!use_lt_credentials && !anon_credentials) { + if (turn_params.default_users_db.ram_db.users_number) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, + "\nCONFIGURATION ALERT: you specified long-term user accounts, (-u option) \n but you did " + "not specify the long-term credentials option\n (-a or --lt-cred-mech option).\n I am " + "turning --lt-cred-mech ON for you, but double-check your configuration.\n"); + turn_params.ct = TURN_CREDENTIALS_LONG_TERM; + use_lt_credentials = 1; + } else { + turn_params.ct = TURN_CREDENTIALS_NONE; + use_lt_credentials = 0; + } + } + + if (use_lt_credentials) { + if (!get_realm(NULL)->options.name[0]) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, + "\nCONFIGURATION ALERT: you did specify the long-term credentials usage\n but you did not specify " + "the default realm option (-r option).\n Check your configuration.\n"); + } + } + + if (anon_credentials) { + if (turn_params.default_users_db.ram_db.users_number) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, + "\nCONFIGURATION ALERT: you specified user accounts, (-u option) \n but you also specified the " + "anonymous user access option (-z or --no-auth option).\n User accounts will be ignored.\n"); + turn_params.ct = TURN_CREDENTIALS_NONE; + use_lt_credentials = 0; + } + } + + openssl_setup(); + + int local_listeners = 0; + if (!turn_params.listener.addrs_number) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "NO EXPLICIT LISTENER ADDRESS(ES) ARE CONFIGURED\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "===========Discovering listener addresses: =========\n"); + int maddrs = make_local_listeners_list(); + if ((maddrs < 1) || !turn_params.listener.addrs_number) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot configure any meaningful IP listener address\n", __FUNCTION__); + fprintf(stderr, "\n%s\n", Usage); + exit(-1); + } + local_listeners = 1; + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "=====================================================\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Total: %d 'real' addresses discovered\n", maddrs); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "=====================================================\n"); + } + + if (!turn_params.relays_number) { + if (!local_listeners && turn_params.listener.addrs_number && turn_params.listener.addrs) { + size_t la = 0; + for (la = 0; la < turn_params.listener.addrs_number; la++) { + if (turn_params.listener.addrs[la]) { + add_relay_addr(turn_params.listener.addrs[la]); } + } + } + if (!turn_params.relays_number) { + turn_params.default_relays = 1; + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "NO EXPLICIT RELAY ADDRESS(ES) ARE CONFIGURED\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "===========Discovering relay addresses: =============\n"); + if (make_local_relays_list(0, AF_INET) < 1) { + make_local_relays_list(1, AF_INET); + } + if (make_local_relays_list(0, AF_INET6) < 1) { + make_local_relays_list(1, AF_INET6); + } + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "=====================================================\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Total: %d relay addresses discovered\n", (int)turn_params.relays_number); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "=====================================================\n"); + } - if(use_cli && cli_password[0]==0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nCONFIG ERROR: Empty cli-password, and so telnet cli interface is disabled! Please set a non empty cli-password!\n"); - use_cli = 0; - } + if (!turn_params.relays_number) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: You must specify the relay address(es)\n", __FUNCTION__); + fprintf(stderr, "\n%s\n", Usage); + exit(-1); + } + } - if(!use_lt_credentials && !anon_credentials) { - if(turn_params.default_users_db.ram_db.users_number) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "\nCONFIGURATION ALERT: you specified long-term user accounts, (-u option) \n but you did not specify the long-term credentials option\n (-a or --lt-cred-mech option).\n I am turning --lt-cred-mech ON for you, but double-check your configuration.\n"); - turn_params.ct = TURN_CREDENTIALS_LONG_TERM; - use_lt_credentials=1; - } else { - turn_params.ct = TURN_CREDENTIALS_NONE; - use_lt_credentials=0; - } - } + if (turn_params.external_ip && turn_params.relay_addrs) { + size_t ir = 0; + for (ir = 0; ir < turn_params.relays_number; ++ir) { + if (turn_params.relay_addrs[ir]) { + const char *sra = (const char *)turn_params.relay_addrs[ir]; + if ((strstr(sra, "127.0.0.1") != sra) && (strstr(sra, "::1") != sra)) { + ioa_addr ra; + if (make_ioa_addr((const uint8_t *)sra, 0, &ra) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "-X : Wrong address format: %s\n", sra); + } else if (ra.ss.sa_family == turn_params.external_ip->ss.sa_family) { + ioa_addr_add_mapping(turn_params.external_ip, &ra); + } + } + } + } + } - if(use_lt_credentials) { - if(!get_realm(NULL)->options.name[0]) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "\nCONFIGURATION ALERT: you did specify the long-term credentials usage\n but you did not specify the default realm option (-r option).\n Check your configuration.\n"); - } - } - - if(anon_credentials) { - if(turn_params.default_users_db.ram_db.users_number) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "\nCONFIGURATION ALERT: you specified user accounts, (-u option) \n but you also specified the anonymous user access option (-z or --no-auth option).\n User accounts will be ignored.\n"); - turn_params.ct = TURN_CREDENTIALS_NONE; - use_lt_credentials=0; - } - } - - openssl_setup(); - - int local_listeners = 0; - if (!turn_params.listener.addrs_number) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "NO EXPLICIT LISTENER ADDRESS(ES) ARE CONFIGURED\n"); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "===========Discovering listener addresses: =========\n"); - int maddrs = make_local_listeners_list(); - if((maddrs<1) || !turn_params.listener.addrs_number) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot configure any meaningful IP listener address\n", __FUNCTION__); - fprintf(stderr,"\n%s\n", Usage); - exit(-1); - } - local_listeners = 1; - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "=====================================================\n"); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Total: %d 'real' addresses discovered\n",maddrs); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "=====================================================\n"); - } - - if (!turn_params.relays_number) { - if(!local_listeners && turn_params.listener.addrs_number && turn_params.listener.addrs) { - size_t la = 0; - for(la=0;lass.sa_family) { - ioa_addr_add_mapping(turn_params.external_ip,&ra); - } - } - } - } - } - - if (socket_init()) return -1; + if (socket_init()) + return -1; #if defined(WINDOWS) - //TODO: implement deamon!!! use windows server + // TODO: implement deamon!!! use windows server #else - if(turn_params.turn_daemon) { + if (turn_params.turn_daemon) { #if !defined(TURN_HAS_DAEMON) - pid_t pid = fork(); - if(pid>0) - exit(0); - if(pid<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: Cannot start daemon process\n"); - exit(-1); - } + pid_t pid = fork(); + if (pid > 0) + exit(0); + if (pid < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: Cannot start daemon process\n"); + exit(-1); + } #else - if(daemon(1,0)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: Cannot start daemon process\n"); - exit(-1); - } - reset_rtpprintf(); + if (daemon(1, 0) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: Cannot start daemon process\n"); + exit(-1); + } + reset_rtpprintf(); #endif - } + } - if(turn_params.pidfile[0]) { + if (turn_params.pidfile[0]) { - char s[2049]; - FILE *f = fopen(turn_params.pidfile,"w"); - if(f) { - STRCPY(s,turn_params.pidfile); - } else { - snprintf(s,sizeof(s),"Cannot create pid file: %s",turn_params.pidfile); - perror(s); - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "%s\n", s); + char s[2049]; + FILE *f = fopen(turn_params.pidfile, "w"); + if (f) { + STRCPY(s, turn_params.pidfile); + } else { + snprintf(s, sizeof(s), "Cannot create pid file: %s", turn_params.pidfile); + perror(s); + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "%s\n", s); - { - const char *pfs[] = {"/var/run/turnserver.pid", - "/var/spool/turnserver.pid", - "/var/turnserver.pid", - "/var/tmp/turnserver.pid", - "/tmp/turnserver.pid", - "turnserver.pid", - NULL}; - const char **ppfs = pfs; - while(*ppfs) { - f = fopen(*ppfs,"w"); - if(f) { - STRCPY(s,*ppfs); - break; - } else { - ++ppfs; - } - } - } - } + { + const char *pfs[] = {"/var/run/turnserver.pid", + "/var/spool/turnserver.pid", + "/var/turnserver.pid", + "/var/tmp/turnserver.pid", + "/tmp/turnserver.pid", + "turnserver.pid", + NULL}; + const char **ppfs = pfs; + while (*ppfs) { + f = fopen(*ppfs, "w"); + if (f) { + STRCPY(s, *ppfs); + break; + } else { + ++ppfs; + } + } + } + } - if(f) { - fprintf(f,"%lu\n",(unsigned long)getpid()); - fclose(f); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "pid file created: %s\n", s); - } - } + if (f) { + fprintf(f, "%lu\n", (unsigned long)getpid()); + fclose(f); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "pid file created: %s\n", s); + } + } #endif - setup_server(); + setup_server(); #if defined(WINDOWS) - //TODO: implement it!!! add windows server + // TODO: implement it!!! add windows server #else - struct event *ev = evsignal_new(turn_params.listener.event_base, SIGUSR2, reload_ssl_certs, NULL); - event_add(ev, NULL); + struct event *ev = evsignal_new(turn_params.listener.event_base, SIGUSR2, reload_ssl_certs, NULL); + event_add(ev, NULL); #endif - drop_privileges(); - start_prometheus_server(); + drop_privileges(); + start_prometheus_server(); - run_listener_server(&(turn_params.listener)); + run_listener_server(&(turn_params.listener)); - disconnect_database(); + disconnect_database(); - return 0; + return 0; } ////////// OpenSSL locking //////////////////////////////////////// -#if defined(OPENSSL_THREADS) +#if defined(OPENSSL_THREADS) #if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0 -//array larger than anything that OpenSSL may need: +// array larger than anything that OpenSSL may need: static TURN_MUTEX_DECLARE(mutex_buf[256]); static int mutex_buf_initialized = 0; @@ -3143,624 +3241,602 @@ void coturn_locking_function(int mode, int n, const char *file, int line); void coturn_locking_function(int mode, int n, const char *file, int line) { UNUSED_ARG(file); UNUSED_ARG(line); - if(mutex_buf_initialized && (n < CRYPTO_num_locks())) { - if (mode & CRYPTO_LOCK) - TURN_MUTEX_LOCK(&(mutex_buf[n])); - else - TURN_MUTEX_UNLOCK(&(mutex_buf[n])); + if (mutex_buf_initialized && (n < CRYPTO_num_locks())) { + if (mode & CRYPTO_LOCK) + TURN_MUTEX_LOCK(&(mutex_buf[n])); + else + TURN_MUTEX_UNLOCK(&(mutex_buf[n])); } } void coturn_id_function(CRYPTO_THREADID *ctid); -void coturn_id_function(CRYPTO_THREADID *ctid) -{ - UNUSED_ARG(ctid); - CRYPTO_THREADID_set_numeric(ctid, (unsigned long)pthread_self()); +void coturn_id_function(CRYPTO_THREADID *ctid) { + UNUSED_ARG(ctid); + CRYPTO_THREADID_set_numeric(ctid, (unsigned long)pthread_self()); } static int THREAD_setup(void) { - int i; - for (i = 0; i < CRYPTO_num_locks(); i++) { - TURN_MUTEX_INIT(&(mutex_buf[i])); - } + int i; + for (i = 0; i < CRYPTO_num_locks(); i++) { + TURN_MUTEX_INIT(&(mutex_buf[i])); + } - mutex_buf_initialized = 1; - CRYPTO_THREADID_set_callback(coturn_id_function); - CRYPTO_set_locking_callback(coturn_locking_function); - return 1; + mutex_buf_initialized = 1; + CRYPTO_THREADID_set_callback(coturn_id_function); + CRYPTO_set_locking_callback(coturn_locking_function); + return 1; } int THREAD_cleanup(void) { - int i; + int i; - if (!mutex_buf_initialized) - return 0; + if (!mutex_buf_initialized) + return 0; - CRYPTO_THREADID_set_callback(NULL); - CRYPTO_set_locking_callback(NULL); - for (i = 0; i < CRYPTO_num_locks(); i++) { - TURN_MUTEX_DESTROY(&(mutex_buf[i])); - } + CRYPTO_THREADID_set_callback(NULL); + CRYPTO_set_locking_callback(NULL); + for (i = 0; i < CRYPTO_num_locks(); i++) { + TURN_MUTEX_DESTROY(&(mutex_buf[i])); + } - mutex_buf_initialized = 0; + mutex_buf_initialized = 0; return 1; } #else -static int THREAD_setup(void) { - return 1; -} +static int THREAD_setup(void) { return 1; } int THREAD_cleanup(void); -int THREAD_cleanup(void){ - return 1; -} +int THREAD_cleanup(void) { return 1; } #endif /* OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0 */ #endif /* defined(OPENSSL_THREADS) */ -static void adjust_key_file_name(char *fn, const char* file_title, int critical) -{ - char *full_path_to_file = NULL; +static void adjust_key_file_name(char *fn, const char *file_title, int critical) { + char *full_path_to_file = NULL; - if(!fn[0]) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"\nERROR: you must set the %s file parameter\n",file_title); - goto keyerr; - } else { + if (!fn[0]) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nERROR: you must set the %s file parameter\n", file_title); + goto keyerr; + } else { - full_path_to_file = find_config_file(fn, 1); - { - FILE *f = full_path_to_file ? fopen(full_path_to_file,"r") : NULL; - if(!f) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"WARNING: cannot find %s file: %s (1)\n",file_title,fn); - goto keyerr; - } else { - fclose(f); - } - } + full_path_to_file = find_config_file(fn, 1); + { + FILE *f = full_path_to_file ? fopen(full_path_to_file, "r") : NULL; + if (!f) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: cannot find %s file: %s (1)\n", file_title, fn); + goto keyerr; + } else { + fclose(f); + } + } - if(!full_path_to_file) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"WARNING: cannot find %s file: %s (2)\n",file_title,fn); - goto keyerr; - } + if (!full_path_to_file) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: cannot find %s file: %s (2)\n", file_title, fn); + goto keyerr; + } - strncpy(fn,full_path_to_file,sizeof(turn_params.cert_file)-1); - fn[sizeof(turn_params.cert_file)-1]=0; + strncpy(fn, full_path_to_file, sizeof(turn_params.cert_file) - 1); + fn[sizeof(turn_params.cert_file) - 1] = 0; - free(full_path_to_file); - return; - } + free(full_path_to_file); + return; + } - keyerr: - { - if(critical) { - turn_params.no_tls = 1; - turn_params.no_dtls = 1; - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"WARNING: cannot start TLS and DTLS listeners because %s file is not set properly\n",file_title); - } - if(full_path_to_file) - free(full_path_to_file); - return; - } +keyerr : { + if (critical) { + turn_params.no_tls = 1; + turn_params.no_dtls = 1; + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, + "WARNING: cannot start TLS and DTLS listeners because %s file is not set properly\n", file_title); + } + if (full_path_to_file) + free(full_path_to_file); + return; +} } -static void adjust_key_file_names(void) -{ - if(turn_params.ca_cert_file[0]) - adjust_key_file_name(turn_params.ca_cert_file,"CA",1); - adjust_key_file_name(turn_params.cert_file,"certificate",1); - adjust_key_file_name(turn_params.pkey_file,"private key",1); - if(turn_params.dh_file[0]) - adjust_key_file_name(turn_params.dh_file,"DH key",0); +static void adjust_key_file_names(void) { + if (turn_params.ca_cert_file[0]) + adjust_key_file_name(turn_params.ca_cert_file, "CA", 1); + adjust_key_file_name(turn_params.cert_file, "certificate", 1); + adjust_key_file_name(turn_params.pkey_file, "private key", 1); + if (turn_params.dh_file[0]) + adjust_key_file_name(turn_params.dh_file, "DH key", 0); } static DH *get_dh566(void) { + unsigned char dh566_p[] = {0x36, 0x53, 0xA8, 0x9C, 0x3C, 0xF1, 0xD1, 0x1B, 0x2D, 0xA2, 0x64, 0xDE, 0x59, 0x3B, 0xE3, + 0x8C, 0x27, 0x74, 0xC2, 0xBE, 0x9B, 0x6D, 0x56, 0xE7, 0xDF, 0xFF, 0x67, 0x6A, 0xD2, 0x0C, + 0xE8, 0x9E, 0x52, 0x00, 0x05, 0xB3, 0x53, 0xF7, 0x1C, 0x41, 0xB2, 0xAC, 0x38, 0x16, 0x32, + 0x3A, 0x8E, 0x90, 0x6C, 0x7E, 0xD1, 0x44, 0xCB, 0xF9, 0x2D, 0x1E, 0x4A, 0x9A, 0x32, 0x81, + 0x58, 0xE1, 0xE1, 0x17, 0xC1, 0x9C, 0xF1, 0x1E, 0x96, 0x2D, 0x5F}; - unsigned char dh566_p[] = { - 0x36,0x53,0xA8,0x9C,0x3C,0xF1,0xD1,0x1B,0x2D,0xA2,0x64,0xDE, - 0x59,0x3B,0xE3,0x8C,0x27,0x74,0xC2,0xBE,0x9B,0x6D,0x56,0xE7, - 0xDF,0xFF,0x67,0x6A,0xD2,0x0C,0xE8,0x9E,0x52,0x00,0x05,0xB3, - 0x53,0xF7,0x1C,0x41,0xB2,0xAC,0x38,0x16,0x32,0x3A,0x8E,0x90, - 0x6C,0x7E,0xD1,0x44,0xCB,0xF9,0x2D,0x1E,0x4A,0x9A,0x32,0x81, - 0x58,0xE1,0xE1,0x17,0xC1,0x9C,0xF1,0x1E,0x96,0x2D,0x5F - }; + // -----BEGIN DH PARAMETERS----- + // MEwCRzZTqJw88dEbLaJk3lk744wndMK+m21W59//Z2rSDOieUgAFs1P3HEGyrDgW + // MjqOkGx+0UTL+S0eSpoygVjh4RfBnPEeli1fAgEF + // -----END DH PARAMETERS----- -// -----BEGIN DH PARAMETERS----- -//MEwCRzZTqJw88dEbLaJk3lk744wndMK+m21W59//Z2rSDOieUgAFs1P3HEGyrDgW -//MjqOkGx+0UTL+S0eSpoygVjh4RfBnPEeli1fAgEF -// -----END DH PARAMETERS----- + unsigned char dh566_g[] = {0x05}; + DH *dh; - unsigned char dh566_g[] = { 0x05 }; - DH *dh; - - if ((dh = DH_new()) == NULL ) - return (NULL ); + if ((dh = DH_new()) == NULL) + return (NULL); #if OPENSSL_VERSION_NUMBER < 0x10100000L - dh->p = BN_bin2bn(dh566_p, sizeof(dh566_p), NULL ); - dh->g = BN_bin2bn(dh566_g, sizeof(dh566_g), NULL ); - if ((dh->p == NULL )|| (dh->g == NULL)){ DH_free(dh); return(NULL);} + dh->p = BN_bin2bn(dh566_p, sizeof(dh566_p), NULL); + dh->g = BN_bin2bn(dh566_g, sizeof(dh566_g), NULL); + if ((dh->p == NULL) || (dh->g == NULL)) { + DH_free(dh); + return (NULL); + } #else - DH_set0_pqg(dh, BN_bin2bn(dh566_p, sizeof(dh566_p), NULL ), NULL, BN_bin2bn(dh566_g, sizeof(dh566_g), NULL )); + DH_set0_pqg(dh, BN_bin2bn(dh566_p, sizeof(dh566_p), NULL), NULL, BN_bin2bn(dh566_g, sizeof(dh566_g), NULL)); #endif - return (dh); + return (dh); } static DH *get_dh1066(void) { - unsigned char dh1066_p[] = { - 0x02,0x0E,0x26,0x6F,0xAA,0x9F,0xA8,0xE5,0x3F,0x70,0x88,0xF1, - 0xA9,0x29,0xAE,0x1A,0x2B,0xA8,0x2F,0xE8,0xE5,0x0E,0x81,0x78, - 0xD7,0x12,0x41,0xDC,0xE2,0xD5,0x10,0x6F,0x8A,0x35,0x23,0xCE, - 0x66,0x93,0x67,0x14,0xEA,0x0A,0x61,0xD4,0x43,0x63,0x5C,0xDF, - 0xDE,0xF5,0xB9,0xC6,0xB4,0x8C,0xBA,0x1A,0x25,0x9F,0x73,0x0F, - 0x1E,0x1A,0x97,0x42,0x2E,0x60,0x9E,0x4C,0x3C,0x70,0x6A,0xFB, - 0xDD,0xAA,0x7A,0x48,0xA5,0x1E,0x87,0xC8,0xA3,0x5E,0x26,0x40, - 0x1B,0xDE,0x08,0x5E,0xA2,0xB8,0xE8,0x76,0x43,0xE8,0xF1,0x4B, - 0x35,0x4C,0x38,0x92,0xB9,0xFF,0x61,0xE6,0x6C,0xBA,0xF9,0x16, - 0x36,0x3C,0x69,0x2D,0x57,0x90,0x62,0x8A,0xD0,0xD4,0xFB,0xB2, - 0x5A,0x61,0x99,0xA9,0xE8,0x93,0x80,0xA2,0xB7,0xDC,0xB1,0x6A, - 0xAF,0xE3 - }; + unsigned char dh1066_p[] = {0x02, 0x0E, 0x26, 0x6F, 0xAA, 0x9F, 0xA8, 0xE5, 0x3F, 0x70, 0x88, 0xF1, 0xA9, 0x29, 0xAE, + 0x1A, 0x2B, 0xA8, 0x2F, 0xE8, 0xE5, 0x0E, 0x81, 0x78, 0xD7, 0x12, 0x41, 0xDC, 0xE2, 0xD5, + 0x10, 0x6F, 0x8A, 0x35, 0x23, 0xCE, 0x66, 0x93, 0x67, 0x14, 0xEA, 0x0A, 0x61, 0xD4, 0x43, + 0x63, 0x5C, 0xDF, 0xDE, 0xF5, 0xB9, 0xC6, 0xB4, 0x8C, 0xBA, 0x1A, 0x25, 0x9F, 0x73, 0x0F, + 0x1E, 0x1A, 0x97, 0x42, 0x2E, 0x60, 0x9E, 0x4C, 0x3C, 0x70, 0x6A, 0xFB, 0xDD, 0xAA, 0x7A, + 0x48, 0xA5, 0x1E, 0x87, 0xC8, 0xA3, 0x5E, 0x26, 0x40, 0x1B, 0xDE, 0x08, 0x5E, 0xA2, 0xB8, + 0xE8, 0x76, 0x43, 0xE8, 0xF1, 0x4B, 0x35, 0x4C, 0x38, 0x92, 0xB9, 0xFF, 0x61, 0xE6, 0x6C, + 0xBA, 0xF9, 0x16, 0x36, 0x3C, 0x69, 0x2D, 0x57, 0x90, 0x62, 0x8A, 0xD0, 0xD4, 0xFB, 0xB2, + 0x5A, 0x61, 0x99, 0xA9, 0xE8, 0x93, 0x80, 0xA2, 0xB7, 0xDC, 0xB1, 0x6A, 0xAF, 0xE3}; -// -----BEGIN DH PARAMETERS----- -// MIGMAoGGAg4mb6qfqOU/cIjxqSmuGiuoL+jlDoF41xJB3OLVEG+KNSPOZpNnFOoK -// YdRDY1zf3vW5xrSMuholn3MPHhqXQi5gnkw8cGr73ap6SKUeh8ijXiZAG94IXqK4 -// 6HZD6PFLNUw4krn/YeZsuvkWNjxpLVeQYorQ1PuyWmGZqeiTgKK33LFqr+MCAQI= -// -----END DH PARAMETERS----- + // -----BEGIN DH PARAMETERS----- + // MIGMAoGGAg4mb6qfqOU/cIjxqSmuGiuoL+jlDoF41xJB3OLVEG+KNSPOZpNnFOoK + // YdRDY1zf3vW5xrSMuholn3MPHhqXQi5gnkw8cGr73ap6SKUeh8ijXiZAG94IXqK4 + // 6HZD6PFLNUw4krn/YeZsuvkWNjxpLVeQYorQ1PuyWmGZqeiTgKK33LFqr+MCAQI= + // -----END DH PARAMETERS----- - unsigned char dh1066_g[] = { 0x02 }; - DH *dh; + unsigned char dh1066_g[] = {0x02}; + DH *dh; - if ((dh = DH_new()) == NULL ) - return (NULL ); + if ((dh = DH_new()) == NULL) + return (NULL); #if OPENSSL_VERSION_NUMBER < 0x10100000L - dh->p = BN_bin2bn(dh1066_p, sizeof(dh1066_p), NULL ); - dh->g = BN_bin2bn(dh1066_g, sizeof(dh1066_g), NULL ); - if ((dh->p == NULL )|| (dh->g == NULL)){ DH_free(dh); return(NULL);} + dh->p = BN_bin2bn(dh1066_p, sizeof(dh1066_p), NULL); + dh->g = BN_bin2bn(dh1066_g, sizeof(dh1066_g), NULL); + if ((dh->p == NULL) || (dh->g == NULL)) { + DH_free(dh); + return (NULL); + } #else - DH_set0_pqg(dh, BN_bin2bn(dh1066_p, sizeof(dh1066_p), NULL ), NULL, BN_bin2bn(dh1066_g, sizeof(dh1066_g), NULL )); + DH_set0_pqg(dh, BN_bin2bn(dh1066_p, sizeof(dh1066_p), NULL), NULL, BN_bin2bn(dh1066_g, sizeof(dh1066_g), NULL)); #endif - return (dh); + return (dh); } static DH *get_dh2066(void) { - unsigned char dh2066_p[] = { - 0x03,0x31,0x77,0x20,0x58,0xA6,0x69,0xA3,0x9D,0x2D,0x5E,0xE0, - 0x5C,0x46,0x82,0x0F,0x9E,0x80,0xF0,0x00,0x2A,0xF9,0x0F,0x62, - 0x1F,0x89,0xCE,0x7D,0x2A,0xFD,0xC5,0x9A,0x7C,0x6A,0x60,0x2C, - 0xF1,0xDD,0xD4,0x4D,0x6B,0xCD,0xE9,0x95,0xDB,0x42,0x97,0xBA, - 0xE4,0xAF,0x41,0x38,0x8F,0x57,0x31,0xA4,0x39,0xDD,0x31,0xC3, - 0x6F,0x98,0x0E,0xE3,0xB1,0x43,0xD1,0x36,0xB0,0x01,0x28,0x42, - 0x71,0xD3,0xB0,0x36,0xA0,0x47,0x99,0x25,0x9B,0x32,0xF5,0x86, - 0xB1,0x13,0x5C,0x24,0x8D,0x8D,0x7F,0xE2,0x7F,0x9A,0xC1,0x52, - 0x58,0xC0,0x63,0xAA,0x00,0x7C,0x1F,0x11,0xBD,0xAC,0x4C,0x2D, - 0xE0,0xA2,0x9D,0x4E,0x21,0xE4,0x0B,0xCD,0x24,0x92,0xD2,0x37, - 0x27,0x84,0x59,0x90,0x46,0x2F,0xD5,0xB9,0x27,0x93,0x18,0x88, - 0xBD,0x91,0x5B,0x87,0x55,0x56,0xD8,0x1B,0xE4,0xCF,0x1C,0xAA, - 0xBC,0xCF,0x80,0x1E,0x35,0x2D,0xB1,0xBC,0x35,0x31,0x92,0x62, - 0x3C,0x91,0x8D,0x62,0xDA,0xCF,0x83,0x63,0x12,0x4B,0x30,0x80, - 0xEE,0x82,0x3C,0x2C,0xD2,0x17,0x13,0x1F,0xF9,0x62,0x33,0x5C, - 0x63,0xD8,0x75,0x5B,0xAA,0x16,0x5A,0x36,0x49,0x17,0x77,0xB7, - 0x74,0xBD,0x3E,0x3F,0x98,0x20,0x59,0x5E,0xC7,0x72,0xE8,0xA3, - 0x89,0x21,0xB4,0x3C,0x25,0xF4,0xF4,0x21,0x96,0x5A,0xA6,0x77, - 0xFF,0x2C,0x3A,0xFC,0x98,0x5F,0xC1,0xBF,0x2A,0xCF,0xB8,0x62, - 0x67,0x23,0xE8,0x2F,0xCC,0x7B,0x32,0x1B,0x6B,0x33,0x67,0x0A, - 0xCB,0xD0,0x1F,0x65,0xD7,0x84,0x54,0xF6,0xF1,0x88,0xB5,0xBB, - 0x0C,0x63,0x65,0x34,0xE4,0x66,0x4B - }; + unsigned char dh2066_p[] = { + 0x03, 0x31, 0x77, 0x20, 0x58, 0xA6, 0x69, 0xA3, 0x9D, 0x2D, 0x5E, 0xE0, 0x5C, 0x46, 0x82, 0x0F, 0x9E, 0x80, 0xF0, + 0x00, 0x2A, 0xF9, 0x0F, 0x62, 0x1F, 0x89, 0xCE, 0x7D, 0x2A, 0xFD, 0xC5, 0x9A, 0x7C, 0x6A, 0x60, 0x2C, 0xF1, 0xDD, + 0xD4, 0x4D, 0x6B, 0xCD, 0xE9, 0x95, 0xDB, 0x42, 0x97, 0xBA, 0xE4, 0xAF, 0x41, 0x38, 0x8F, 0x57, 0x31, 0xA4, 0x39, + 0xDD, 0x31, 0xC3, 0x6F, 0x98, 0x0E, 0xE3, 0xB1, 0x43, 0xD1, 0x36, 0xB0, 0x01, 0x28, 0x42, 0x71, 0xD3, 0xB0, 0x36, + 0xA0, 0x47, 0x99, 0x25, 0x9B, 0x32, 0xF5, 0x86, 0xB1, 0x13, 0x5C, 0x24, 0x8D, 0x8D, 0x7F, 0xE2, 0x7F, 0x9A, 0xC1, + 0x52, 0x58, 0xC0, 0x63, 0xAA, 0x00, 0x7C, 0x1F, 0x11, 0xBD, 0xAC, 0x4C, 0x2D, 0xE0, 0xA2, 0x9D, 0x4E, 0x21, 0xE4, + 0x0B, 0xCD, 0x24, 0x92, 0xD2, 0x37, 0x27, 0x84, 0x59, 0x90, 0x46, 0x2F, 0xD5, 0xB9, 0x27, 0x93, 0x18, 0x88, 0xBD, + 0x91, 0x5B, 0x87, 0x55, 0x56, 0xD8, 0x1B, 0xE4, 0xCF, 0x1C, 0xAA, 0xBC, 0xCF, 0x80, 0x1E, 0x35, 0x2D, 0xB1, 0xBC, + 0x35, 0x31, 0x92, 0x62, 0x3C, 0x91, 0x8D, 0x62, 0xDA, 0xCF, 0x83, 0x63, 0x12, 0x4B, 0x30, 0x80, 0xEE, 0x82, 0x3C, + 0x2C, 0xD2, 0x17, 0x13, 0x1F, 0xF9, 0x62, 0x33, 0x5C, 0x63, 0xD8, 0x75, 0x5B, 0xAA, 0x16, 0x5A, 0x36, 0x49, 0x17, + 0x77, 0xB7, 0x74, 0xBD, 0x3E, 0x3F, 0x98, 0x20, 0x59, 0x5E, 0xC7, 0x72, 0xE8, 0xA3, 0x89, 0x21, 0xB4, 0x3C, 0x25, + 0xF4, 0xF4, 0x21, 0x96, 0x5A, 0xA6, 0x77, 0xFF, 0x2C, 0x3A, 0xFC, 0x98, 0x5F, 0xC1, 0xBF, 0x2A, 0xCF, 0xB8, 0x62, + 0x67, 0x23, 0xE8, 0x2F, 0xCC, 0x7B, 0x32, 0x1B, 0x6B, 0x33, 0x67, 0x0A, 0xCB, 0xD0, 0x1F, 0x65, 0xD7, 0x84, 0x54, + 0xF6, 0xF1, 0x88, 0xB5, 0xBB, 0x0C, 0x63, 0x65, 0x34, 0xE4, 0x66, 0x4B}; -// -----BEGIN DH PARAMETERS----- -//MIIBCgKCAQMDMXcgWKZpo50tXuBcRoIPnoDwACr5D2Ific59Kv3FmnxqYCzx3dRN -//a83pldtCl7rkr0E4j1cxpDndMcNvmA7jsUPRNrABKEJx07A2oEeZJZsy9YaxE1wk -//jY1/4n+awVJYwGOqAHwfEb2sTC3gop1OIeQLzSSS0jcnhFmQRi/VuSeTGIi9kVuH -//VVbYG+TPHKq8z4AeNS2xvDUxkmI8kY1i2s+DYxJLMIDugjws0hcTH/liM1xj2HVb -//qhZaNkkXd7d0vT4/mCBZXsdy6KOJIbQ8JfT0IZZapnf/LDr8mF/BvyrPuGJnI+gv -//zHsyG2szZwrL0B9l14RU9vGItbsMY2U05GZLAgEF -// -----END DH PARAMETERS----- + // -----BEGIN DH PARAMETERS----- + // MIIBCgKCAQMDMXcgWKZpo50tXuBcRoIPnoDwACr5D2Ific59Kv3FmnxqYCzx3dRN + // a83pldtCl7rkr0E4j1cxpDndMcNvmA7jsUPRNrABKEJx07A2oEeZJZsy9YaxE1wk + // jY1/4n+awVJYwGOqAHwfEb2sTC3gop1OIeQLzSSS0jcnhFmQRi/VuSeTGIi9kVuH + // VVbYG+TPHKq8z4AeNS2xvDUxkmI8kY1i2s+DYxJLMIDugjws0hcTH/liM1xj2HVb + // qhZaNkkXd7d0vT4/mCBZXsdy6KOJIbQ8JfT0IZZapnf/LDr8mF/BvyrPuGJnI+gv + // zHsyG2szZwrL0B9l14RU9vGItbsMY2U05GZLAgEF + // -----END DH PARAMETERS----- - unsigned char dh2066_g[] = { 0x05 }; - DH *dh; + unsigned char dh2066_g[] = {0x05}; + DH *dh; - if ((dh = DH_new()) == NULL ) - return (NULL ); + if ((dh = DH_new()) == NULL) + return (NULL); #if OPENSSL_VERSION_NUMBER < 0x10100000L - dh->p = BN_bin2bn(dh2066_p, sizeof(dh2066_p), NULL ); - dh->g = BN_bin2bn(dh2066_g, sizeof(dh2066_g), NULL ); - if ((dh->p == NULL )|| (dh->g == NULL)){ DH_free(dh); return(NULL);} + dh->p = BN_bin2bn(dh2066_p, sizeof(dh2066_p), NULL); + dh->g = BN_bin2bn(dh2066_g, sizeof(dh2066_g), NULL); + if ((dh->p == NULL) || (dh->g == NULL)) { + DH_free(dh); + return (NULL); + } #else - DH_set0_pqg(dh, BN_bin2bn(dh2066_p, sizeof(dh2066_p), NULL ), NULL, BN_bin2bn(dh2066_g, sizeof(dh2066_g), NULL )); + DH_set0_pqg(dh, BN_bin2bn(dh2066_p, sizeof(dh2066_p), NULL), NULL, BN_bin2bn(dh2066_g, sizeof(dh2066_g), NULL)); #endif - return (dh); + return (dh); } -static int pem_password_func(char *buf, int size, int rwflag, void *password) -{ - UNUSED_ARG(rwflag); +static int pem_password_func(char *buf, int size, int rwflag, void *password) { + UNUSED_ARG(rwflag); - strncpy(buf, (char * )(password), size); - buf[size - 1] = 0; - return (strlen(buf)); + strncpy(buf, (char *)(password), size); + buf[size - 1] = 0; + return (strlen(buf)); } #if ALPN_SUPPORTED -static int ServerALPNCallback(SSL *ssl, - const unsigned char **out, - unsigned char *outlen, - const unsigned char *in, - unsigned int inlen, - void *arg) { +static int ServerALPNCallback(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, + unsigned int inlen, void *arg) { - UNUSED_ARG(ssl); - UNUSED_ARG(arg); + UNUSED_ARG(ssl); + UNUSED_ARG(arg); - unsigned char sa_len = (unsigned char)strlen(STUN_ALPN); - unsigned char ta_len = (unsigned char)strlen(TURN_ALPN); - unsigned char ha_len = (unsigned char)strlen(HTTP_ALPN); + unsigned char sa_len = (unsigned char)strlen(STUN_ALPN); + unsigned char ta_len = (unsigned char)strlen(TURN_ALPN); + unsigned char ha_len = (unsigned char)strlen(HTTP_ALPN); - int found_http = 0; + int found_http = 0; - const unsigned char *ptr = in; - while(ptr < (in+inlen)) { - unsigned char current_len = *ptr; - if(ptr+1+current_len > in+inlen) - break; - if((!turn_params.no_stun) && (current_len == sa_len) && (memcmp(ptr+1,STUN_ALPN,sa_len)==0)) { - *out = ptr+1; - *outlen = sa_len; - SSL_set_app_data(ssl,STUN_ALPN); - return SSL_TLSEXT_ERR_OK; - } - if((!turn_params.stun_only) && (current_len == ta_len) && (memcmp(ptr+1,TURN_ALPN,ta_len)==0)) { - *out = ptr+1; - *outlen = ta_len; - SSL_set_app_data(ssl,TURN_ALPN); - return SSL_TLSEXT_ERR_OK; - } - if((current_len == ha_len) && (memcmp(ptr+1,HTTP_ALPN,ha_len)==0)) { - *out = ptr+1; - *outlen = ha_len; - SSL_set_app_data(ssl,HTTP_ALPN); - found_http = 1; - } - ptr += 1 + current_len; - } + const unsigned char *ptr = in; + while (ptr < (in + inlen)) { + unsigned char current_len = *ptr; + if (ptr + 1 + current_len > in + inlen) + break; + if ((!turn_params.no_stun) && (current_len == sa_len) && (memcmp(ptr + 1, STUN_ALPN, sa_len) == 0)) { + *out = ptr + 1; + *outlen = sa_len; + SSL_set_app_data(ssl, STUN_ALPN); + return SSL_TLSEXT_ERR_OK; + } + if ((!turn_params.stun_only) && (current_len == ta_len) && (memcmp(ptr + 1, TURN_ALPN, ta_len) == 0)) { + *out = ptr + 1; + *outlen = ta_len; + SSL_set_app_data(ssl, TURN_ALPN); + return SSL_TLSEXT_ERR_OK; + } + if ((current_len == ha_len) && (memcmp(ptr + 1, HTTP_ALPN, ha_len) == 0)) { + *out = ptr + 1; + *outlen = ha_len; + SSL_set_app_data(ssl, HTTP_ALPN); + found_http = 1; + } + ptr += 1 + current_len; + } - if(found_http) - return SSL_TLSEXT_ERR_OK; + if (found_http) + return SSL_TLSEXT_ERR_OK; - return SSL_TLSEXT_ERR_NOACK; //??? + return SSL_TLSEXT_ERR_NOACK; //??? } #endif -static void set_ctx(SSL_CTX** out, const char *protocol, const SSL_METHOD* method) -{ - SSL_CTX* ctx = SSL_CTX_new(method); - int err = 0; - int rc = 0; +static void set_ctx(SSL_CTX **out, const char *protocol, const SSL_METHOD *method) { + SSL_CTX *ctx = SSL_CTX_new(method); + int err = 0; + int rc = 0; #if ALPN_SUPPORTED - SSL_CTX_set_alpn_select_cb(ctx, ServerALPNCallback, NULL); + SSL_CTX_set_alpn_select_cb(ctx, ServerALPNCallback, NULL); #endif - SSL_CTX_set_default_passwd_cb_userdata(ctx, turn_params.tls_password); + SSL_CTX_set_default_passwd_cb_userdata(ctx, turn_params.tls_password); - SSL_CTX_set_default_passwd_cb(ctx, pem_password_func); + SSL_CTX_set_default_passwd_cb(ctx, pem_password_func); - if(!(turn_params.cipher_list[0])) - strncpy(turn_params.cipher_list,DEFAULT_CIPHER_LIST,TURN_LONG_STRING_SIZE); + if (!(turn_params.cipher_list[0])) + strncpy(turn_params.cipher_list, DEFAULT_CIPHER_LIST, TURN_LONG_STRING_SIZE); - SSL_CTX_set_cipher_list(ctx, turn_params.cipher_list); - SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); + SSL_CTX_set_cipher_list(ctx, turn_params.cipher_list); + SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); - if (!SSL_CTX_use_certificate_chain_file(ctx, turn_params.cert_file)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: no certificate found\n", protocol); - err = 1; - } else { - print_abs_file_name(protocol, ": Certificate", turn_params.cert_file); - } + if (!SSL_CTX_use_certificate_chain_file(ctx, turn_params.cert_file)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: no certificate found\n", protocol); + err = 1; + } else { + print_abs_file_name(protocol, ": Certificate", turn_params.cert_file); + } - if (!SSL_CTX_use_PrivateKey_file(ctx, turn_params.pkey_file, SSL_FILETYPE_PEM)) { - if (!SSL_CTX_use_RSAPrivateKey_file(ctx, turn_params.pkey_file, SSL_FILETYPE_PEM)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: no valid private key found, or invalid private key password provided\n", protocol); - err = 1; - } else { - print_abs_file_name(protocol, ": Private RSA key", turn_params.pkey_file); - } - } else { - print_abs_file_name(protocol, ": Private key", turn_params.pkey_file); - } + if (!SSL_CTX_use_PrivateKey_file(ctx, turn_params.pkey_file, SSL_FILETYPE_PEM)) { + if (!SSL_CTX_use_RSAPrivateKey_file(ctx, turn_params.pkey_file, SSL_FILETYPE_PEM)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, + "%s: ERROR: no valid private key found, or invalid private key password provided\n", protocol); + err = 1; + } else { + print_abs_file_name(protocol, ": Private RSA key", turn_params.pkey_file); + } + } else { + print_abs_file_name(protocol, ": Private key", turn_params.pkey_file); + } - if (!SSL_CTX_check_private_key(ctx)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: invalid private key\n", protocol); - err = 1; - } + if (!SSL_CTX_check_private_key(ctx)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: invalid private key\n", protocol); + err = 1; + } - if(turn_params.ca_cert_file[0]) { + if (turn_params.ca_cert_file[0]) { - if (!SSL_CTX_load_verify_locations(ctx, turn_params.ca_cert_file, NULL )) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot load CA from file: %s\n", turn_params.ca_cert_file); - err = 1; - } + if (!SSL_CTX_load_verify_locations(ctx, turn_params.ca_cert_file, NULL)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot load CA from file: %s\n", turn_params.ca_cert_file); + err = 1; + } - SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(turn_params.ca_cert_file)); + SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(turn_params.ca_cert_file)); - /* Set to require peer (client) certificate verification */ - SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE, NULL); + /* Set to require peer (client) certificate verification */ + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE, NULL); - /* Set the verification depth to 9 */ - SSL_CTX_set_verify_depth(ctx, 9); + /* Set the verification depth to 9 */ + SSL_CTX_set_verify_depth(ctx, 9); - } else { - SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); - } + } else { + SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); + } #if !defined(OPENSSL_NO_EC) && defined(OPENSSL_EC_NAMED_CURVE) - { //Elliptic curve algorithms: - int nid = 0; - int set_auto_curve = 0; + { // Elliptic curve algorithms: + int nid = 0; + int set_auto_curve = 0; - const char* curve_name = turn_params.ec_curve_name; + const char *curve_name = turn_params.ec_curve_name; - if (!(curve_name[0])) { + if (!(curve_name[0])) { #if !SSL_SESSION_ECDH_AUTO_SUPPORTED - curve_name = DEFAULT_EC_CURVE_NAME; + curve_name = DEFAULT_EC_CURVE_NAME; #endif - set_auto_curve = 1; - } + set_auto_curve = 1; + } - if(curve_name[0]) { - { - nid = OBJ_sn2nid(curve_name); - if (nid == 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"unknown curve name: %s\n",curve_name); - curve_name = DEFAULT_EC_CURVE_NAME; - nid = OBJ_sn2nid(curve_name); - set_auto_curve = 1; - } - } + if (curve_name[0]) { + { + nid = OBJ_sn2nid(curve_name); + if (nid == 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "unknown curve name: %s\n", curve_name); + curve_name = DEFAULT_EC_CURVE_NAME; + nid = OBJ_sn2nid(curve_name); + set_auto_curve = 1; + } + } - { - EC_KEY *ecdh = EC_KEY_new_by_curve_name(nid); - if (!ecdh) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: ERROR: allocate EC suite\n",__FUNCTION__); - set_auto_curve = 1; - } else { - SSL_CTX_set_tmp_ecdh(ctx, ecdh); - EC_KEY_free(ecdh); - } - } - } + { + EC_KEY *ecdh = EC_KEY_new_by_curve_name(nid); + if (!ecdh) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: allocate EC suite\n", __FUNCTION__); + set_auto_curve = 1; + } else { + SSL_CTX_set_tmp_ecdh(ctx, ecdh); + EC_KEY_free(ecdh); + } + } + } - if(set_auto_curve) { + if (set_auto_curve) { #if SSL_SESSION_ECDH_AUTO_SUPPORTED #if OPENSSL_VERSION_NUMBER < 0x10100000L - SSL_CTX_set_ecdh_auto(ctx,1); + SSL_CTX_set_ecdh_auto(ctx, 1); #endif #endif - set_auto_curve = 0; - } - } + set_auto_curve = 0; + } + } #endif - {//DH algorithms: + { // DH algorithms: - DH *dh = NULL; - if(turn_params.dh_file[0]) { - FILE *paramfile = fopen(turn_params.dh_file, "r"); - if (!paramfile) { - perror("Cannot open DH file"); - } else { - dh = PEM_read_DHparams(paramfile, NULL, NULL, NULL); - fclose(paramfile); - if(dh) { - turn_params.dh_key_size = DH_CUSTOM; - } - } - } + DH *dh = NULL; + if (turn_params.dh_file[0]) { + FILE *paramfile = fopen(turn_params.dh_file, "r"); + if (!paramfile) { + perror("Cannot open DH file"); + } else { + dh = PEM_read_DHparams(paramfile, NULL, NULL, NULL); + fclose(paramfile); + if (dh) { + turn_params.dh_key_size = DH_CUSTOM; + } + } + } - if(!dh) { - if(turn_params.dh_key_size == DH_566) - dh = get_dh566(); - else if(turn_params.dh_key_size == DH_1066) - dh = get_dh1066(); - else - dh = get_dh2066(); - } + if (!dh) { + if (turn_params.dh_key_size == DH_566) + dh = get_dh566(); + else if (turn_params.dh_key_size == DH_1066) + dh = get_dh1066(); + else + dh = get_dh2066(); + } - if(!dh) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: cannot allocate DH suite\n",__FUNCTION__); - err = 1; - } else { - if (1 != SSL_CTX_set_tmp_dh (ctx, dh)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: cannot set DH\n",__FUNCTION__); - err = 1; - } - DH_free (dh); - } - } + if (!dh) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: cannot allocate DH suite\n", __FUNCTION__); + err = 1; + } else { + if (1 != SSL_CTX_set_tmp_dh(ctx, dh)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: cannot set DH\n", __FUNCTION__); + err = 1; + } + DH_free(dh); + } + } - {//secret key + { // secret key - if(turn_params.secret_key_file[0]) { - FILE *f = fopen(turn_params.secret_key_file, "r"); + if (turn_params.secret_key_file[0]) { + FILE *f = fopen(turn_params.secret_key_file, "r"); - if (!f) { - perror("Cannot open Secret-Key file"); - } else { - fseek (f, 0, SEEK_SET); - rc = fread(turn_params.secret_key, sizeof(char), 16, f); - if( rc == 0 ){ - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: Secret-Key file is empty\n",__FUNCTION__); - } - else{ - if( rc != 16 ){ - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: Secret-Key length is not enough\n",__FUNCTION__); - } - } - fclose (f); - } - } - } + if (!f) { + perror("Cannot open Secret-Key file"); + } else { + fseek(f, 0, SEEK_SET); + rc = fread(turn_params.secret_key, sizeof(char), 16, f); + if (rc == 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: Secret-Key file is empty\n", __FUNCTION__); + } else { + if (rc != 16) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: Secret-Key length is not enough\n", __FUNCTION__); + } + } + fclose(f); + } + } + } - { - int op = 0; + { + int op = 0; #if defined(SSL_OP_NO_SSLv2) - op |= SSL_OP_NO_SSLv2; + op |= SSL_OP_NO_SSLv2; #endif #if defined(SSL_OP_NO_SSLv3) - op |= SSL_OP_NO_SSLv3; + op |= SSL_OP_NO_SSLv3; #endif #if defined(SSL_OP_NO_DTLSv1) && DTLS_SUPPORTED - if(turn_params.no_tlsv1) - op |= SSL_OP_NO_DTLSv1; + if (turn_params.no_tlsv1) + op |= SSL_OP_NO_DTLSv1; #endif #if defined(SSL_OP_NO_DTLSv1_2) && DTLSv1_2_SUPPORTED - if(turn_params.no_tlsv1_2) - op |= SSL_OP_NO_DTLSv1_2; + if (turn_params.no_tlsv1_2) + op |= SSL_OP_NO_DTLSv1_2; #endif #if defined(SSL_OP_CIPHER_SERVER_PREFERENCE) - op |= SSL_OP_CIPHER_SERVER_PREFERENCE; + op |= SSL_OP_CIPHER_SERVER_PREFERENCE; #endif #if defined(SSL_OP_SINGLE_DH_USE) - op |= SSL_OP_SINGLE_DH_USE; + op |= SSL_OP_SINGLE_DH_USE; #endif #if defined(SSL_OP_SINGLE_ECDH_USE) - op |= SSL_OP_SINGLE_ECDH_USE; + op |= SSL_OP_SINGLE_ECDH_USE; #endif - SSL_CTX_set_options(ctx, op); - } + SSL_CTX_set_options(ctx, op); + } - if (*out == NULL) { - // Always initialize, even if issues were encountered - *out = ctx; - } else if (!err) { - SSL_CTX_free(*out); - *out = ctx; - } + if (*out == NULL) { + // Always initialize, even if issues were encountered + *out = ctx; + } else if (!err) { + SSL_CTX_free(*out); + *out = ctx; + } } static void openssl_load_certificates(void); -static void openssl_setup(void) -{ - THREAD_setup(); - SSL_load_error_strings(); - OpenSSL_add_ssl_algorithms(); +static void openssl_setup(void) { + THREAD_setup(); + SSL_load_error_strings(); + OpenSSL_add_ssl_algorithms(); #if !TLS_SUPPORTED - if(!turn_params.no_tls) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "WARNING: TLS is not supported\n"); - turn_params.no_tls = 1; - } + if (!turn_params.no_tls) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "WARNING: TLS is not supported\n"); + turn_params.no_tls = 1; + } #endif - if(!(turn_params.no_tls && turn_params.no_dtls) && !turn_params.cert_file[0]) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"\nWARNING: certificate file is not specified, I cannot start TLS/DTLS services.\nOnly 'plain' UDP/TCP listeners can be started.\n"); - turn_params.no_tls = 1; - turn_params.no_dtls = 1; - } + if (!(turn_params.no_tls && turn_params.no_dtls) && !turn_params.cert_file[0]) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "\nWARNING: certificate file is not specified, I cannot start TLS/DTLS " + "services.\nOnly 'plain' UDP/TCP listeners can be started.\n"); + turn_params.no_tls = 1; + turn_params.no_dtls = 1; + } - if(!(turn_params.no_tls && turn_params.no_dtls) && !turn_params.pkey_file[0]) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"\nWARNING: private key file is not specified, I cannot start TLS/DTLS services.\nOnly 'plain' UDP/TCP listeners can be started.\n"); - turn_params.no_tls = 1; - turn_params.no_dtls = 1; - } + if (!(turn_params.no_tls && turn_params.no_dtls) && !turn_params.pkey_file[0]) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "\nWARNING: private key file is not specified, I cannot start TLS/DTLS " + "services.\nOnly 'plain' UDP/TCP listeners can be started.\n"); + turn_params.no_tls = 1; + turn_params.no_dtls = 1; + } - if(!(turn_params.no_tls && turn_params.no_dtls)) { - adjust_key_file_names(); - } + if (!(turn_params.no_tls && turn_params.no_dtls)) { + adjust_key_file_names(); + } - openssl_load_certificates(); + openssl_load_certificates(); } -static void openssl_load_certificates(void) -{ - TURN_MUTEX_LOCK(&turn_params.tls_mutex); - if(!turn_params.no_tls) { +static void openssl_load_certificates(void) { + TURN_MUTEX_LOCK(&turn_params.tls_mutex); + if (!turn_params.no_tls) { #if OPENSSL_VERSION_NUMBER < 0x10100000L - set_ctx(&turn_params.tls_ctx,"TLS", TLSv1_2_server_method()); /*openssl-1.0.2 version specific API */ - if(!turn_params.no_tlsv1) { - SSL_CTX_set_options(turn_params.tls_ctx, SSL_OP_NO_TLSv1); - } + set_ctx(&turn_params.tls_ctx, "TLS", TLSv1_2_server_method()); /*openssl-1.0.2 version specific API */ + if (!turn_params.no_tlsv1) { + SSL_CTX_set_options(turn_params.tls_ctx, SSL_OP_NO_TLSv1); + } #if TLSv1_1_SUPPORTED - if(!turn_params.no_tlsv1_1) { - SSL_CTX_set_options(turn_params.tls_ctx, SSL_OP_NO_TLSv1_1); - } + if (!turn_params.no_tlsv1_1) { + SSL_CTX_set_options(turn_params.tls_ctx, SSL_OP_NO_TLSv1_1); + } #if TLSv1_2_SUPPORTED - if(!turn_params.no_tlsv1_2) { - SSL_CTX_set_options(turn_params.tls_ctx, SSL_OP_NO_TLSv1_2); - } + if (!turn_params.no_tlsv1_2) { + SSL_CTX_set_options(turn_params.tls_ctx, SSL_OP_NO_TLSv1_2); + } #endif #endif #else // OPENSSL_VERSION_NUMBER < 0x10100000L - set_ctx(&turn_params.tls_ctx,"TLS", TLS_server_method()); - if(!turn_params.no_tlsv1) { - SSL_CTX_set_min_proto_version(turn_params.tls_ctx, TLS1_1_VERSION); - } - if(!turn_params.no_tlsv1_1) { - SSL_CTX_set_min_proto_version(turn_params.tls_ctx, TLS1_2_VERSION); - } + set_ctx(&turn_params.tls_ctx, "TLS", TLS_server_method()); + if (!turn_params.no_tlsv1) { + SSL_CTX_set_min_proto_version(turn_params.tls_ctx, TLS1_1_VERSION); + } + if (!turn_params.no_tlsv1_1) { + SSL_CTX_set_min_proto_version(turn_params.tls_ctx, TLS1_2_VERSION); + } #if TLSv1_3_SUPPORTED - if(!turn_params.no_tlsv1_2) { - SSL_CTX_set_min_proto_version(turn_params.tls_ctx, TLS1_3_VERSION); - } + if (!turn_params.no_tlsv1_2) { + SSL_CTX_set_min_proto_version(turn_params.tls_ctx, TLS1_3_VERSION); + } #endif #endif // OPENSSL_VERSION_NUMBER < 0x10100000L - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS cipher suite: %s\n",turn_params.cipher_list); - } + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS cipher suite: %s\n", turn_params.cipher_list); + } - if(!turn_params.no_dtls) { + if (!turn_params.no_dtls) { #if !DTLS_SUPPORTED - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: DTLS is not supported.\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: DTLS is not supported.\n"); #elif OPENSSL_VERSION_NUMBER < 0x10000000L - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: TURN Server was compiled with rather old OpenSSL version, DTLS may not be working correctly.\n"); + TURN_LOG_FUNC( + TURN_LOG_LEVEL_WARNING, + "WARNING: TURN Server was compiled with rather old OpenSSL version, DTLS may not be working correctly.\n"); #else #if OPENSSL_VERSION_NUMBER < 0x10100000L // before openssl-1.1.0 no version independent API #if DTLSv1_2_SUPPORTED - set_ctx(&turn_params.dtls_ctx,"DTLS",DTLSv1_2_server_method()); // openssl-1.0.2 - if(!turn_params.no_tlsv1_2) { - SSL_CTX_set_options(turn_params.dtls_ctx, SSL_OP_NO_DTLSv1_2); - } + set_ctx(&turn_params.dtls_ctx, "DTLS", DTLSv1_2_server_method()); // openssl-1.0.2 + if (!turn_params.no_tlsv1_2) { + SSL_CTX_set_options(turn_params.dtls_ctx, SSL_OP_NO_DTLSv1_2); + } #else - set_ctx(&turn_params.dtls_ctx,"DTLS",DTLSv1_server_method()); // < openssl-1.0.2 + set_ctx(&turn_params.dtls_ctx, "DTLS", DTLSv1_server_method()); // < openssl-1.0.2 #endif - if(!turn_params.no_tlsv1 || !turn_params.no_tlsv1_1) { - SSL_CTX_set_options(turn_params.dtls_ctx, SSL_OP_NO_DTLSv1); - } -#else // OPENSSL_VERSION_NUMBER < 0x10100000L - set_ctx(&turn_params.dtls_ctx,"DTLS",DTLS_server_method()); - if(!turn_params.no_tlsv1 || !turn_params.no_tlsv1_1) { - SSL_CTX_set_min_proto_version(turn_params.tls_ctx, DTLS1_2_VERSION); - } - if(!turn_params.no_tlsv1_2) { - SSL_CTX_set_max_proto_version(turn_params.tls_ctx, DTLS1_VERSION); - } -#endif //OPENSSL_VERSION_NUMBER < 0x10100000L - setup_dtls_callbacks(turn_params.dtls_ctx); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS cipher suite: %s\n",turn_params.cipher_list); + if (!turn_params.no_tlsv1 || !turn_params.no_tlsv1_1) { + SSL_CTX_set_options(turn_params.dtls_ctx, SSL_OP_NO_DTLSv1); + } +#else // OPENSSL_VERSION_NUMBER < 0x10100000L + set_ctx(&turn_params.dtls_ctx, "DTLS", DTLS_server_method()); + if (!turn_params.no_tlsv1 || !turn_params.no_tlsv1_1) { + SSL_CTX_set_min_proto_version(turn_params.tls_ctx, DTLS1_2_VERSION); + } + if (!turn_params.no_tlsv1_2) { + SSL_CTX_set_max_proto_version(turn_params.tls_ctx, DTLS1_VERSION); + } +#endif // OPENSSL_VERSION_NUMBER < 0x10100000L + setup_dtls_callbacks(turn_params.dtls_ctx); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS cipher suite: %s\n", turn_params.cipher_list); #endif - } - TURN_MUTEX_UNLOCK(&turn_params.tls_mutex); + } + TURN_MUTEX_UNLOCK(&turn_params.tls_mutex); } -static void reload_ssl_certs(evutil_socket_t sock, short events, void *args) -{ - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Reloading TLS certificates and keys\n"); - openssl_load_certificates(); - if (turn_params.tls_ctx_update_ev != NULL) - event_active(turn_params.tls_ctx_update_ev, EV_READ, 0); +static void reload_ssl_certs(evutil_socket_t sock, short events, void *args) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Reloading TLS certificates and keys\n"); + openssl_load_certificates(); + if (turn_params.tls_ctx_update_ev != NULL) + event_active(turn_params.tls_ctx_update_ev, EV_READ, 0); - UNUSED_ARG(sock); - UNUSED_ARG(events); - UNUSED_ARG(args); + UNUSED_ARG(sock); + UNUSED_ARG(events); + UNUSED_ARG(args); } /////////////////////////////// diff --git a/src/apps/relay/mainrelay.h b/src/apps/relay/mainrelay.h index 76245f5..c6bc003 100644 --- a/src/apps/relay/mainrelay.h +++ b/src/apps/relay/mainrelay.h @@ -31,11 +31,11 @@ #if !defined(__MAIN_RELAY__) #define __MAIN_RELAY__ -#include +#include #include +#include #include #include -#include #include @@ -44,39 +44,38 @@ #include -#include #include +#include #include -#if defined(__unix__) || defined(unix) || defined(__APPLE__) \ - || defined(__DARWIN__) || defined(__MACH__) +#if defined(__unix__) || defined(unix) || defined(__APPLE__) || defined(__DARWIN__) || defined(__MACH__) #include #include -#include #include +#include #include -#include #include +#include #endif -#include #include +#include #include "ns_turn_openssl.h" -#include "ns_turn_utils.h" #include "ns_turn_khash.h" +#include "ns_turn_utils.h" -#include "userdb.h" #include "turn_admin_server.h" +#include "userdb.h" -#include "tls_listener.h" #include "dtls_listener.h" +#include "tls_listener.h" -#include "ns_turn_server.h" #include "ns_turn_maps.h" +#include "ns_turn_server.h" #include "apputils.h" @@ -88,7 +87,7 @@ #include #if OPENSSL_VERSION_NUMBER >= 0x10100000L - #include +#include #endif #if !defined(TURN_NO_SYSTEMD) @@ -117,60 +116,52 @@ extern "C" { /////////// TYPES /////////////////////////////////// -enum _DH_KEY_SIZE { - DH_566, - DH_1066, - DH_2066, - DH_CUSTOM -}; +enum _DH_KEY_SIZE { DH_566, DH_1066, DH_2066, DH_CUSTOM }; typedef enum _DH_KEY_SIZE DH_KEY_SIZE; ///////// LISTENER SERVER TYPES ///////////////////// struct message_to_listener_to_client { - ioa_addr origin; - ioa_addr destination; - ioa_network_buffer_handle nbh; + ioa_addr origin; + ioa_addr destination; + ioa_network_buffer_handle nbh; }; -enum _MESSAGE_TO_LISTENER_TYPE { - LMT_UNKNOWN, - LMT_TO_CLIENT -}; +enum _MESSAGE_TO_LISTENER_TYPE { LMT_UNKNOWN, LMT_TO_CLIENT }; typedef enum _MESSAGE_TO_LISTENER_TYPE MESSAGE_TO_LISTENER_TYPE; struct message_to_listener { - MESSAGE_TO_LISTENER_TYPE t; - union { - struct message_to_listener_to_client tc; - } m; + MESSAGE_TO_LISTENER_TYPE t; + union { + struct message_to_listener_to_client tc; + } m; }; struct listener_server { - rtcp_map* rtcpmap; - turnipports* tp; - struct event_base* event_base; - ioa_engine_handle ioa_eng; - struct bufferevent *in_buf; - struct bufferevent *out_buf; - char **addrs; - ioa_addr **encaddrs; - size_t addrs_number; - size_t services_number; - dtls_listener_relay_server_type ***udp_services; - dtls_listener_relay_server_type ***dtls_services; - dtls_listener_relay_server_type ***aux_udp_services; + rtcp_map *rtcpmap; + turnipports *tp; + struct event_base *event_base; + ioa_engine_handle ioa_eng; + struct bufferevent *in_buf; + struct bufferevent *out_buf; + char **addrs; + ioa_addr **encaddrs; + size_t addrs_number; + size_t services_number; + dtls_listener_relay_server_type ***udp_services; + dtls_listener_relay_server_type ***dtls_services; + dtls_listener_relay_server_type ***aux_udp_services; }; enum _NET_ENG_VERSION { - NEV_UNKNOWN=0, - NEV_MIN, - NEV_UDP_SOCKET_PER_SESSION=NEV_MIN, - NEV_UDP_SOCKET_PER_ENDPOINT, - NEV_UDP_SOCKET_PER_THREAD, - NEV_MAX=NEV_UDP_SOCKET_PER_THREAD, - NEV_TOTAL + NEV_UNKNOWN = 0, + NEV_MIN, + NEV_UDP_SOCKET_PER_SESSION = NEV_MIN, + NEV_UDP_SOCKET_PER_ENDPOINT, + NEV_UDP_SOCKET_PER_THREAD, + NEV_MAX = NEV_UDP_SOCKET_PER_THREAD, + NEV_TOTAL }; typedef enum _NET_ENG_VERSION NET_ENG_VERSION; @@ -179,16 +170,16 @@ typedef enum _NET_ENG_VERSION NET_ENG_VERSION; typedef struct _turn_params_ { -//////////////// OpenSSL group ////////////////////// + //////////////// OpenSSL group ////////////////////// SSL_CTX *tls_ctx; SSL_CTX *dtls_ctx; - + DH_KEY_SIZE dh_key_size; - + char cipher_list[1025]; char ec_curve_name[33]; - + char ca_cert_file[1025]; char cert_file[1025]; char pkey_file[1025]; @@ -204,7 +195,7 @@ typedef struct _turn_params_ { struct event *tls_ctx_update_ev; TURN_MUTEX_DECLARE(tls_mutex) -//////////////// Common params //////////////////// + //////////////// Common params //////////////////// int verbose; int turn_daemon; @@ -228,7 +219,7 @@ typedef struct _turn_params_ { int no_udp; int no_tcp; int tcp_use_proxy; - + vint no_tcp_relay; vint no_udp_relay; @@ -243,9 +234,9 @@ typedef struct _turn_params_ { ip_range_list_t ip_blacklist; NET_ENG_VERSION net_engine_version; - const char* net_engine_version_txt[NEV_TOTAL]; + const char *net_engine_version_txt[NEV_TOTAL]; -//////////////// Relay servers ///////////// + //////////////// Relay servers ///////////// uint16_t min_port; uint16_t max_port; @@ -268,26 +259,26 @@ typedef struct _turn_params_ { turnserver_id general_relay_servers_number; turnserver_id udp_relay_servers_number; -////////////// Auth server //////////////// + ////////////// Auth server //////////////// char oauth_server_name[1025]; char domain[1025]; int oauth; -/////////////// AUX SERVERS //////////////// + /////////////// AUX SERVERS //////////////// turn_server_addrs_list_t aux_servers_list; int udp_self_balance; -/////////////// ALTERNATE SERVERS //////////////// + /////////////// ALTERNATE SERVERS //////////////// turn_server_addrs_list_t alternate_servers_list; turn_server_addrs_list_t tls_alternate_servers_list; -/////////////// stop server //////////////// + /////////////// stop server //////////////// int stop_turn_server; -////////////// MISC PARAMS //////////////// + ////////////// MISC PARAMS //////////////// vint stun_only; vint no_stun; @@ -311,12 +302,11 @@ typedef struct _turn_params_ { int prometheus_port; int prometheus_username_labels; - -/////// Users DB /////////// + /////// Users DB /////////// default_users_db_t default_users_db; -/////// CPUs ////////////// + /////// CPUs ////////////// unsigned long cpus; @@ -338,15 +328,15 @@ extern turn_params_t turn_params; //////////////// Listener server ///////////////// static inline int get_alt_listener_port(void) { - if(turn_params.alt_listener_port<1) - return turn_params.listener_port + 1; - return turn_params.alt_listener_port; + if (turn_params.alt_listener_port < 1) + return turn_params.listener_port + 1; + return turn_params.alt_listener_port; } static inline int get_alt_tls_listener_port(void) { - if(turn_params.alt_tls_listener_port<1) - return turn_params.tls_listener_port + 1; - return turn_params.alt_tls_listener_port; + if (turn_params.alt_tls_listener_port < 1) + return turn_params.tls_listener_port + 1; + return turn_params.alt_tls_listener_port; } void add_aux_server(const char *saddr); @@ -358,8 +348,8 @@ void del_tls_alternate_server(const char *saddr); ////////// Addrs //////////////////// -void add_listener_addr(const char* addr); -int add_relay_addr(const char* addr); +void add_listener_addr(const char *addr); +int add_relay_addr(const char *addr); ////////// SSL CTX //////////////////// void set_ssl_ctx(ioa_engine_handle e, turn_params_t *params); @@ -385,21 +375,19 @@ void set_max_bps(band_limit_t value); ///////// AES ENCRYPTION AND DECRYPTION //////// struct ctr_state { - unsigned char ivec[16]; - unsigned int num; - unsigned char ecount[16]; + unsigned char ivec[16]; + unsigned int num; + unsigned char ecount[16]; }; -void generate_aes_128_key(char* filePath, unsigned char* returnedKey); -unsigned char *base64encode (const void *b64_encode_this, int encode_this_many_bytes); -void encrypt_aes_128(unsigned char* in, const unsigned char* mykey); -unsigned char *base64decode (const void *b64_decode_this, int decode_this_many_bytes); -void decrypt_aes_128(char* in, const unsigned char* mykey); +void generate_aes_128_key(char *filePath, unsigned char *returnedKey); +unsigned char *base64encode(const void *b64_encode_this, int encode_this_many_bytes); +void encrypt_aes_128(unsigned char *in, const unsigned char *mykey); +unsigned char *base64decode(const void *b64_decode_this, int decode_this_many_bytes); +void decrypt_aes_128(char *in, const unsigned char *mykey); int decodedTextSize(char *input); -char* decryptPassword(char* in, const unsigned char* mykey); +char *decryptPassword(char *in, const unsigned char *mykey); int init_ctr(struct ctr_state *state, const unsigned char iv[8]); - - /////////////////////////////// #ifdef __cplusplus diff --git a/src/apps/relay/netengine.c b/src/apps/relay/netengine.c index c270549..2f25a7e 100644 --- a/src/apps/relay/netengine.c +++ b/src/apps/relay/netengine.c @@ -47,12 +47,12 @@ static pthread_barrier_t barrier; typedef unsigned char authserver_id; struct auth_server { - authserver_id id; - struct event_base* event_base; - struct bufferevent *in_buf; - struct bufferevent *out_buf; - pthread_t thr; - redis_context_handle rch; + authserver_id id; + struct event_base *event_base; + struct bufferevent *in_buf; + struct bufferevent *out_buf; + pthread_t thr; + redis_context_handle rch; }; #define MIN_AUTHSERVER_NUMBER (3) @@ -61,13 +61,15 @@ static struct auth_server authserver[256]; ////////////////////////////////////////////// -#define get_real_general_relay_servers_number() (turn_params.general_relay_servers_number > 1 ? turn_params.general_relay_servers_number : 1) -#define get_real_udp_relay_servers_number() (turn_params.udp_relay_servers_number > 1 ? turn_params.udp_relay_servers_number : 1) +#define get_real_general_relay_servers_number() \ + (turn_params.general_relay_servers_number > 1 ? turn_params.general_relay_servers_number : 1) +#define get_real_udp_relay_servers_number() \ + (turn_params.udp_relay_servers_number > 1 ? turn_params.udp_relay_servers_number : 1) -static struct relay_server *general_relay_servers[1+((turnserver_id)-1)]; -static struct relay_server *udp_relay_servers[1+((turnserver_id)-1)]; +static struct relay_server *general_relay_servers[1 + ((turnserver_id)-1)]; +static struct relay_server *udp_relay_servers[1 + ((turnserver_id)-1)]; -static struct relay_server* get_relay_server(turnserver_id id); +static struct relay_server *get_relay_server(turnserver_id id); ////////////////////////////////////////////// @@ -80,361 +82,343 @@ static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int #define PTHREAD_BARRIER_SERIAL_THREAD (-1) #endif -static void barrier_wait_func(const char* func, int line) -{ +static void barrier_wait_func(const char *func, int line) { #if !defined(TURN_NO_THREAD_BARRIERS) - int br = 0; - do { - br = pthread_barrier_wait(&barrier); - if ((br < 0)&&(br != PTHREAD_BARRIER_SERIAL_THREAD)) { - int err = errno; - perror("barrier wait"); - printf("%s:%s:%d: %d\n", __FUNCTION__, func,line,err); - } - } while (((br < 0)&&(br != PTHREAD_BARRIER_SERIAL_THREAD)) && (errno == EINTR)); + int br = 0; + do { + br = pthread_barrier_wait(&barrier); + if ((br < 0) && (br != PTHREAD_BARRIER_SERIAL_THREAD)) { + int err = errno; + perror("barrier wait"); + printf("%s:%s:%d: %d\n", __FUNCTION__, func, line, err); + } + } while (((br < 0) && (br != PTHREAD_BARRIER_SERIAL_THREAD)) && (errno == EINTR)); #else - UNUSED_ARG(func); - UNUSED_ARG(line); - sleep(5); + UNUSED_ARG(func); + UNUSED_ARG(line); + sleep(5); #endif } -#define barrier_wait() barrier_wait_func(__FUNCTION__,__LINE__) +#define barrier_wait() barrier_wait_func(__FUNCTION__, __LINE__) /////////////// Bandwidth ////////////////// static TURN_MUTEX_DECLARE(mutex_bps); -static band_limit_t allocate_bps(band_limit_t bps, int positive) -{ - band_limit_t ret = 0; - if(bps>0) { - TURN_MUTEX_LOCK(&mutex_bps); +static band_limit_t allocate_bps(band_limit_t bps, int positive) { + band_limit_t ret = 0; + if (bps > 0) { + TURN_MUTEX_LOCK(&mutex_bps); - if(positive) { + if (positive) { - if(!(turn_params.bps_capacity)) { - ret = bps; - turn_params.bps_capacity_allocated += ret; - } else if(turn_params.bps_capacity_allocated < turn_params.bps_capacity) { - band_limit_t reserve = turn_params.bps_capacity - turn_params.bps_capacity_allocated; - if(reserve <= bps) { - ret = reserve; - turn_params.bps_capacity_allocated = turn_params.bps_capacity; - } else { - ret = bps; - turn_params.bps_capacity_allocated += ret; - } - } + if (!(turn_params.bps_capacity)) { + ret = bps; + turn_params.bps_capacity_allocated += ret; + } else if (turn_params.bps_capacity_allocated < turn_params.bps_capacity) { + band_limit_t reserve = turn_params.bps_capacity - turn_params.bps_capacity_allocated; + if (reserve <= bps) { + ret = reserve; + turn_params.bps_capacity_allocated = turn_params.bps_capacity; + } else { + ret = bps; + turn_params.bps_capacity_allocated += ret; + } + } - } else { + } else { - if(turn_params.bps_capacity_allocated >= bps) { - turn_params.bps_capacity_allocated -= bps; - } else { - turn_params.bps_capacity_allocated = 0; - } - } + if (turn_params.bps_capacity_allocated >= bps) { + turn_params.bps_capacity_allocated -= bps; + } else { + turn_params.bps_capacity_allocated = 0; + } + } - TURN_MUTEX_UNLOCK(&mutex_bps); - } + TURN_MUTEX_UNLOCK(&mutex_bps); + } - return ret; + return ret; } -band_limit_t get_bps_capacity_allocated(void) -{ - band_limit_t ret = 0; - TURN_MUTEX_LOCK(&mutex_bps); - ret = turn_params.bps_capacity_allocated; - TURN_MUTEX_UNLOCK(&mutex_bps); - return ret; +band_limit_t get_bps_capacity_allocated(void) { + band_limit_t ret = 0; + TURN_MUTEX_LOCK(&mutex_bps); + ret = turn_params.bps_capacity_allocated; + TURN_MUTEX_UNLOCK(&mutex_bps); + return ret; } -band_limit_t get_bps_capacity(void) -{ - band_limit_t ret = 0; - TURN_MUTEX_LOCK(&mutex_bps); - ret = turn_params.bps_capacity; - TURN_MUTEX_UNLOCK(&mutex_bps); - return ret; +band_limit_t get_bps_capacity(void) { + band_limit_t ret = 0; + TURN_MUTEX_LOCK(&mutex_bps); + ret = turn_params.bps_capacity; + TURN_MUTEX_UNLOCK(&mutex_bps); + return ret; } -void set_bps_capacity(band_limit_t value) -{ - TURN_MUTEX_LOCK(&mutex_bps); - turn_params.bps_capacity = value; - TURN_MUTEX_UNLOCK(&mutex_bps); +void set_bps_capacity(band_limit_t value) { + TURN_MUTEX_LOCK(&mutex_bps); + turn_params.bps_capacity = value; + TURN_MUTEX_UNLOCK(&mutex_bps); } -band_limit_t get_max_bps(void) -{ - band_limit_t ret = 0; - TURN_MUTEX_LOCK(&mutex_bps); - ret = turn_params.max_bps; - TURN_MUTEX_UNLOCK(&mutex_bps); - return ret; +band_limit_t get_max_bps(void) { + band_limit_t ret = 0; + TURN_MUTEX_LOCK(&mutex_bps); + ret = turn_params.max_bps; + TURN_MUTEX_UNLOCK(&mutex_bps); + return ret; } -void set_max_bps(band_limit_t value) -{ - TURN_MUTEX_LOCK(&mutex_bps); - turn_params.max_bps = value; - TURN_MUTEX_UNLOCK(&mutex_bps); +void set_max_bps(band_limit_t value) { + TURN_MUTEX_LOCK(&mutex_bps); + turn_params.max_bps = value; + TURN_MUTEX_UNLOCK(&mutex_bps); } /////////////// AUX SERVERS //////////////// -static void add_aux_server_list(const char *saddr, turn_server_addrs_list_t *list) -{ - if(saddr && list) { - ioa_addr addr; - if(make_ioa_addr_from_full_string((const uint8_t*)saddr, 0, &addr)!=0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong full address format: %s\n",saddr); - } else { - list->addrs = (ioa_addr*)realloc(list->addrs,sizeof(ioa_addr)*(list->size+1)); - addr_cpy(&(list->addrs[(list->size)++]),&addr); - { - uint8_t s[1025]; - addr_to_string(&addr, s); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Aux server: %s\n",s); - } - } - } +static void add_aux_server_list(const char *saddr, turn_server_addrs_list_t *list) { + if (saddr && list) { + ioa_addr addr; + if (make_ioa_addr_from_full_string((const uint8_t *)saddr, 0, &addr) != 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong full address format: %s\n", saddr); + } else { + list->addrs = (ioa_addr *)realloc(list->addrs, sizeof(ioa_addr) * (list->size + 1)); + addr_cpy(&(list->addrs[(list->size)++]), &addr); + { + uint8_t s[1025]; + addr_to_string(&addr, s); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Aux server: %s\n", s); + } + } + } } -void add_aux_server(const char *saddr) -{ - add_aux_server_list(saddr,&turn_params.aux_servers_list); -} +void add_aux_server(const char *saddr) { add_aux_server_list(saddr, &turn_params.aux_servers_list); } /////////////// ALTERNATE SERVERS //////////////// -static void add_alt_server(const char *saddr, int default_port, turn_server_addrs_list_t *list) -{ - if(saddr && list) { - ioa_addr addr; +static void add_alt_server(const char *saddr, int default_port, turn_server_addrs_list_t *list) { + if (saddr && list) { + ioa_addr addr; - TURN_MUTEX_LOCK(&(list->m)); + TURN_MUTEX_LOCK(&(list->m)); - if(make_ioa_addr_from_full_string((const uint8_t*)saddr, default_port, &addr)!=0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong IP address format: %s\n",saddr); - } else { - list->addrs = (ioa_addr*)realloc(list->addrs,sizeof(ioa_addr)*(list->size+1)); - addr_cpy(&(list->addrs[(list->size)++]),&addr); - { - uint8_t s[1025]; - addr_to_string(&addr, s); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Alternate server added: %s\n",s); - } - } + if (make_ioa_addr_from_full_string((const uint8_t *)saddr, default_port, &addr) != 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong IP address format: %s\n", saddr); + } else { + list->addrs = (ioa_addr *)realloc(list->addrs, sizeof(ioa_addr) * (list->size + 1)); + addr_cpy(&(list->addrs[(list->size)++]), &addr); + { + uint8_t s[1025]; + addr_to_string(&addr, s); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Alternate server added: %s\n", s); + } + } - TURN_MUTEX_UNLOCK(&(list->m)); - } + TURN_MUTEX_UNLOCK(&(list->m)); + } } -static void del_alt_server(const char *saddr, int default_port, turn_server_addrs_list_t *list) -{ - if(saddr && list && list->size && list->addrs) { +static void del_alt_server(const char *saddr, int default_port, turn_server_addrs_list_t *list) { + if (saddr && list && list->size && list->addrs) { - ioa_addr addr; + ioa_addr addr; - TURN_MUTEX_LOCK(&(list->m)); + TURN_MUTEX_LOCK(&(list->m)); - if(make_ioa_addr_from_full_string((const uint8_t*)saddr, default_port, &addr)!=0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong IP address format: %s\n",saddr); - } else { + if (make_ioa_addr_from_full_string((const uint8_t *)saddr, default_port, &addr) != 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong IP address format: %s\n", saddr); + } else { - size_t i; - int found = 0; - for(i=0;isize;++i) { - if(addr_eq(&(list->addrs[i]),&addr)) { - found = 1; - break; - } - } + size_t i; + int found = 0; + for (i = 0; i < list->size; ++i) { + if (addr_eq(&(list->addrs[i]), &addr)) { + found = 1; + break; + } + } - if(found) { + if (found) { - size_t j; - ioa_addr *new_addrs = (ioa_addr*)malloc(sizeof(ioa_addr)*(list->size-1)); - for(j=0;jaddrs[j])); - } - for(j=i;jsize-1;++j) { - addr_cpy(&(new_addrs[j]),&(list->addrs[j+1])); - } + size_t j; + ioa_addr *new_addrs = (ioa_addr *)malloc(sizeof(ioa_addr) * (list->size - 1)); + for (j = 0; j < i; ++j) { + addr_cpy(&(new_addrs[j]), &(list->addrs[j])); + } + for (j = i; j < list->size - 1; ++j) { + addr_cpy(&(new_addrs[j]), &(list->addrs[j + 1])); + } - free(list->addrs); - list->addrs = new_addrs; - list->size -= 1; + free(list->addrs); + list->addrs = new_addrs; + list->size -= 1; - { - uint8_t s[1025]; - addr_to_string(&addr, s); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Alternate server removed: %s\n",s); - } + { + uint8_t s[1025]; + addr_to_string(&addr, s); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Alternate server removed: %s\n", s); + } - del_alt_server(saddr, default_port, list); - } - } + del_alt_server(saddr, default_port, list); + } + } - TURN_MUTEX_UNLOCK(&(list->m)); - } + TURN_MUTEX_UNLOCK(&(list->m)); + } } -void add_alternate_server(const char *saddr) -{ - add_alt_server(saddr,DEFAULT_STUN_PORT,&turn_params.alternate_servers_list); +void add_alternate_server(const char *saddr) { + add_alt_server(saddr, DEFAULT_STUN_PORT, &turn_params.alternate_servers_list); } -void del_alternate_server(const char *saddr) -{ - del_alt_server(saddr,DEFAULT_STUN_PORT,&turn_params.alternate_servers_list); +void del_alternate_server(const char *saddr) { + del_alt_server(saddr, DEFAULT_STUN_PORT, &turn_params.alternate_servers_list); } -void add_tls_alternate_server(const char *saddr) -{ - add_alt_server(saddr,DEFAULT_STUN_TLS_PORT,&turn_params.tls_alternate_servers_list); +void add_tls_alternate_server(const char *saddr) { + add_alt_server(saddr, DEFAULT_STUN_TLS_PORT, &turn_params.tls_alternate_servers_list); } -void del_tls_alternate_server(const char *saddr) -{ - del_alt_server(saddr,DEFAULT_STUN_TLS_PORT,&turn_params.tls_alternate_servers_list); +void del_tls_alternate_server(const char *saddr) { + del_alt_server(saddr, DEFAULT_STUN_TLS_PORT, &turn_params.tls_alternate_servers_list); } ////////////////////////////////////////////////// typedef struct update_ssl_ctx_cb_args { - ioa_engine_handle engine; - turn_params_t *params; - struct event *next; + ioa_engine_handle engine; + turn_params_t *params; + struct event *next; } update_ssl_ctx_cb_args_t; /* * Copy SSL context at "from", which may be NULL if no context in use */ -static void replace_one_ssl_ctx(SSL_CTX **to, SSL_CTX *from) -{ - if (*to) - SSL_CTX_free(*to); +static void replace_one_ssl_ctx(SSL_CTX **to, SSL_CTX *from) { + if (*to) + SSL_CTX_free(*to); - if (from != NULL) - SSL_CTX_up_ref(from); + if (from != NULL) + SSL_CTX_up_ref(from); - *to = from; + *to = from; } /* * Synchronise the ioa_engine's SSL certificates with the global ones */ -static void update_ssl_ctx(evutil_socket_t sock, short events, update_ssl_ctx_cb_args_t *args) -{ - ioa_engine_handle e = args->engine; - turn_params_t *params = args->params; +static void update_ssl_ctx(evutil_socket_t sock, short events, update_ssl_ctx_cb_args_t *args) { + ioa_engine_handle e = args->engine; + turn_params_t *params = args->params; - /* No mutex with "e" as these are only used in the same event loop */ - TURN_MUTEX_LOCK(&turn_params.tls_mutex); - replace_one_ssl_ctx(&e->tls_ctx, params->tls_ctx); + /* No mutex with "e" as these are only used in the same event loop */ + TURN_MUTEX_LOCK(&turn_params.tls_mutex); + replace_one_ssl_ctx(&e->tls_ctx, params->tls_ctx); #if DTLS_SUPPORTED - replace_one_ssl_ctx(&e->dtls_ctx, params->dtls_ctx); + replace_one_ssl_ctx(&e->dtls_ctx, params->dtls_ctx); #endif - struct event *next = args->next; - TURN_MUTEX_UNLOCK(&turn_params.tls_mutex); + struct event *next = args->next; + TURN_MUTEX_UNLOCK(&turn_params.tls_mutex); - if (next != NULL) - event_active(next, EV_READ, 0); + if (next != NULL) + event_active(next, EV_READ, 0); - UNUSED_ARG(sock); - UNUSED_ARG(events); + UNUSED_ARG(sock); + UNUSED_ARG(events); } -void set_ssl_ctx(ioa_engine_handle e, turn_params_t *params) -{ - update_ssl_ctx_cb_args_t *args = (update_ssl_ctx_cb_args_t *)malloc(sizeof(update_ssl_ctx_cb_args_t)); - args->engine = e; - args->params = params; - args->next = NULL; +void set_ssl_ctx(ioa_engine_handle e, turn_params_t *params) { + update_ssl_ctx_cb_args_t *args = (update_ssl_ctx_cb_args_t *)malloc(sizeof(update_ssl_ctx_cb_args_t)); + args->engine = e; + args->params = params; + args->next = NULL; - update_ssl_ctx(-1, 0, args); + update_ssl_ctx(-1, 0, args); - struct event_base *base = e->event_base; - if (base != NULL) { - struct event *ev = event_new(base, -1, EV_PERSIST, (event_callback_fn)update_ssl_ctx, (void *)args); - TURN_MUTEX_LOCK(&turn_params.tls_mutex); - args->next = params->tls_ctx_update_ev; - params->tls_ctx_update_ev = ev; - TURN_MUTEX_UNLOCK(&turn_params.tls_mutex); - } + struct event_base *base = e->event_base; + if (base != NULL) { + struct event *ev = event_new(base, -1, EV_PERSIST, (event_callback_fn)update_ssl_ctx, (void *)args); + TURN_MUTEX_LOCK(&turn_params.tls_mutex); + args->next = params->tls_ctx_update_ev; + params->tls_ctx_update_ev = ev; + TURN_MUTEX_UNLOCK(&turn_params.tls_mutex); + } } ////////////////////////////////////////////////// -void add_listener_addr(const char* addr) { - ioa_addr baddr; - if(make_ioa_addr((const uint8_t*)addr,0,&baddr)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot add a listener address: %s\n",addr); - } else { +void add_listener_addr(const char *addr) { + ioa_addr baddr; + if (make_ioa_addr((const uint8_t *)addr, 0, &baddr) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot add a listener address: %s\n", addr); + } else { - char sbaddr[129]; - addr_to_string_no_port(&baddr,(uint8_t*)sbaddr); + char sbaddr[129]; + addr_to_string_no_port(&baddr, (uint8_t *)sbaddr); - size_t i = 0; - for(i=0;i=0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, " relay %s initialization...\n",turn_params.relay_addrs[i]); - turnipports_add_ip(STUN_ATTRIBUTE_TRANSPORT_UDP_VALUE, &baddr); - turnipports_add_ip(STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE, &baddr); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, " relay %s initialization done\n",turn_params.relay_addrs[i]); - } - } - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Relay ports initialization done\n"); + int i; + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Wait for relay ports initialization...\n"); + for (i = 0; i < (int)turn_params.relays_number; i++) { + ioa_addr baddr; + if (make_ioa_addr((const uint8_t *)turn_params.relay_addrs[i], 0, &baddr) >= 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, " relay %s initialization...\n", turn_params.relay_addrs[i]); + turnipports_add_ip(STUN_ATTRIBUTE_TRANSPORT_UDP_VALUE, &baddr); + turnipports_add_ip(STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE, &baddr); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, " relay %s initialization done\n", turn_params.relay_addrs[i]); + } + } + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Relay ports initialization done\n"); } ////////////////////////////////////////////////// @@ -443,93 +427,86 @@ static void allocate_relay_addrs_ports(void) { static int handle_relay_message(relay_server_handle rs, struct message_to_relay *sm); -static struct relay_server* get_relay_server(turnserver_id id) { - struct relay_server *rs = NULL; - if(id>=TURNSERVER_ID_BOUNDARY_BETWEEN_TCP_AND_UDP) { - size_t dest = id-TURNSERVER_ID_BOUNDARY_BETWEEN_TCP_AND_UDP; - if(dest >= get_real_udp_relay_servers_number()) { - TURN_LOG_FUNC( - TURN_LOG_LEVEL_ERROR, - "%s: Too large UDP relay number: %d, total=%d\n", - __FUNCTION__,(int)dest,(int)get_real_udp_relay_servers_number()); - } - rs = udp_relay_servers[dest]; - if(!rs) { - TURN_LOG_FUNC( - TURN_LOG_LEVEL_ERROR, - "%s: Wrong UDP relay number: %d, total=%d\n", - __FUNCTION__,(int)dest,(int)get_real_udp_relay_servers_number()); - } - } else { - size_t dest = id; - if(dest >= get_real_general_relay_servers_number()) { - TURN_LOG_FUNC( - TURN_LOG_LEVEL_ERROR, - "%s: Too large general relay number: %d, total=%d\n", - __FUNCTION__,(int)dest,(int)get_real_general_relay_servers_number()); - } - rs = general_relay_servers[dest]; - if(!rs) { - TURN_LOG_FUNC( - TURN_LOG_LEVEL_ERROR, - "%s: Wrong general relay number: %d, total=%d\n", - __FUNCTION__,(int)dest,(int)get_real_general_relay_servers_number()); - } - } - return rs; +static struct relay_server *get_relay_server(turnserver_id id) { + struct relay_server *rs = NULL; + if (id >= TURNSERVER_ID_BOUNDARY_BETWEEN_TCP_AND_UDP) { + size_t dest = id - TURNSERVER_ID_BOUNDARY_BETWEEN_TCP_AND_UDP; + if (dest >= get_real_udp_relay_servers_number()) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Too large UDP relay number: %d, total=%d\n", __FUNCTION__, (int)dest, + (int)get_real_udp_relay_servers_number()); + } + rs = udp_relay_servers[dest]; + if (!rs) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Wrong UDP relay number: %d, total=%d\n", __FUNCTION__, (int)dest, + (int)get_real_udp_relay_servers_number()); + } + } else { + size_t dest = id; + if (dest >= get_real_general_relay_servers_number()) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Too large general relay number: %d, total=%d\n", __FUNCTION__, (int)dest, + (int)get_real_general_relay_servers_number()); + } + rs = general_relay_servers[dest]; + if (!rs) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Wrong general relay number: %d, total=%d\n", __FUNCTION__, (int)dest, + (int)get_real_general_relay_servers_number()); + } + } + return rs; } static TURN_MUTEX_DECLARE(auth_message_counter_mutex); static authserver_id auth_message_counter = 1; -void send_auth_message_to_auth_server(struct auth_message *am) -{ - TURN_MUTEX_LOCK(&auth_message_counter_mutex); - if(auth_message_counter>=authserver_number) auth_message_counter = 1; - else if(auth_message_counter<1) auth_message_counter = 1; - authserver_id sn = auth_message_counter++; - TURN_MUTEX_UNLOCK(&auth_message_counter_mutex); +void send_auth_message_to_auth_server(struct auth_message *am) { + TURN_MUTEX_LOCK(&auth_message_counter_mutex); + if (auth_message_counter >= authserver_number) + auth_message_counter = 1; + else if (auth_message_counter < 1) + auth_message_counter = 1; + authserver_id sn = auth_message_counter++; + TURN_MUTEX_UNLOCK(&auth_message_counter_mutex); - struct evbuffer *output = bufferevent_get_output(authserver[sn].out_buf); - if(evbuffer_add(output,am,sizeof(struct auth_message))<0) { - fprintf(stderr,"%s: Weird buffer error\n",__FUNCTION__); - } + struct evbuffer *output = bufferevent_get_output(authserver[sn].out_buf); + if (evbuffer_add(output, am, sizeof(struct auth_message)) < 0) { + fprintf(stderr, "%s: Weird buffer error\n", __FUNCTION__); + } } -static void auth_server_receive_message(struct bufferevent *bev, void *ptr) -{ +static void auth_server_receive_message(struct bufferevent *bev, void *ptr) { UNUSED_ARG(ptr); - + struct auth_message am; int n = 0; struct evbuffer *input = bufferevent_get_input(bev); - + while ((n = evbuffer_remove(input, &am, sizeof(struct auth_message))) > 0) { if (n != sizeof(struct auth_message)) { - fprintf(stderr,"%s: Weird buffer error: size=%d\n",__FUNCTION__,n); + fprintf(stderr, "%s: Weird buffer error: size=%d\n", __FUNCTION__, n); continue; } - + { hmackey_t key; - if(get_user_key(am.in_oauth,&(am.out_oauth),&(am.max_session_time),am.username,am.realm,key,am.in_buffer.nbh)<0) { - am.success = 0; + if (get_user_key(am.in_oauth, &(am.out_oauth), &(am.max_session_time), am.username, am.realm, key, + am.in_buffer.nbh) < 0) { + am.success = 0; } else { - memcpy(am.key,key,sizeof(hmackey_t)); - am.success = 1; + memcpy(am.key, key, sizeof(hmackey_t)); + am.success = 1; } } struct evbuffer *output = NULL; - struct relay_server* relay_server = get_relay_server(am.id); - if(relay_server) { - output = bufferevent_get_output(relay_server->auth_out_buf); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: can't find relay for turn_server_id: %d\n", __FUNCTION__,(int)am.id); - } + struct relay_server *relay_server = get_relay_server(am.id); + if (relay_server) { + output = bufferevent_get_output(relay_server->auth_out_buf); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: can't find relay for turn_server_id: %d\n", __FUNCTION__, (int)am.id); + } - if(output) - evbuffer_add(output,&am,sizeof(struct auth_message)); + if (output) + evbuffer_add(output, &am, sizeof(struct auth_message)); else { ioa_network_buffer_delete(NULL, am.in_buffer.nbh); am.in_buffer.nbh = NULL; @@ -537,454 +514,435 @@ static void auth_server_receive_message(struct bufferevent *bev, void *ptr) } } -static int send_socket_to_general_relay(ioa_engine_handle e, struct message_to_relay *sm) -{ - struct relay_server *rdest = sm->relay_server; +static int send_socket_to_general_relay(ioa_engine_handle e, struct message_to_relay *sm) { + struct relay_server *rdest = sm->relay_server; - if(!rdest) { - size_t dest = (hash_int32(addr_get_port(&(sm->m.sm.nd.src_addr)))) % get_real_general_relay_servers_number(); - rdest = general_relay_servers[dest]; - } + if (!rdest) { + size_t dest = (hash_int32(addr_get_port(&(sm->m.sm.nd.src_addr)))) % get_real_general_relay_servers_number(); + rdest = general_relay_servers[dest]; + } - struct message_to_relay *smptr = sm; + struct message_to_relay *smptr = sm; - smptr->t = RMT_SOCKET; + smptr->t = RMT_SOCKET; - struct evbuffer *output = NULL; - int success = 0; + struct evbuffer *output = NULL; + int success = 0; - if(!rdest) { - goto label_end; - } + if (!rdest) { + goto label_end; + } - output = bufferevent_get_output(rdest->out_buf); + output = bufferevent_get_output(rdest->out_buf); - if(output) { + if (output) { - if(evbuffer_add(output,smptr,sizeof(struct message_to_relay))<0) { - TURN_LOG_FUNC( - TURN_LOG_LEVEL_ERROR, - "%s: Cannot add message to relay output buffer\n", - __FUNCTION__); - } else { - success = 1; - smptr->m.sm.nd.nbh=NULL; - } - } + if (evbuffer_add(output, smptr, sizeof(struct message_to_relay)) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot add message to relay output buffer\n", __FUNCTION__); + } else { + success = 1; + smptr->m.sm.nd.nbh = NULL; + } + } - label_end: +label_end: - if(!success) { - ioa_network_buffer_delete(e, smptr->m.sm.nd.nbh); - smptr->m.sm.nd.nbh=NULL; - IOA_CLOSE_SOCKET(smptr->m.sm.s); - return -1; - } + if (!success) { + ioa_network_buffer_delete(e, smptr->m.sm.nd.nbh); + smptr->m.sm.nd.nbh = NULL; + IOA_CLOSE_SOCKET(smptr->m.sm.s); + return -1; + } - return 0; + return 0; } -static int send_socket_to_relay(turnserver_id id, uint64_t cid, stun_tid *tid, ioa_socket_handle s, - int message_integrity, MESSAGE_TO_RELAY_TYPE rmt, ioa_net_data *nd, - int can_resume) -{ - int ret = -1; +static int send_socket_to_relay(turnserver_id id, uint64_t cid, stun_tid *tid, ioa_socket_handle s, + int message_integrity, MESSAGE_TO_RELAY_TYPE rmt, ioa_net_data *nd, int can_resume) { + int ret = -1; - struct message_to_relay sm; - memset(&sm, 0, sizeof(struct message_to_relay)); - sm.t = rmt; + struct message_to_relay sm; + memset(&sm, 0, sizeof(struct message_to_relay)); + sm.t = rmt; - ioa_socket_handle s_to_delete = s; + ioa_socket_handle s_to_delete = s; - struct relay_server *rs = get_relay_server(id); - if(!rs) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: can't find relay for turn_server_id: %d\n", __FUNCTION__,(int)id); - goto err; - } + struct relay_server *rs = get_relay_server(id); + if (!rs) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: can't find relay for turn_server_id: %d\n", __FUNCTION__, (int)id); + goto err; + } - switch (rmt) { - case(RMT_CB_SOCKET): { + switch (rmt) { + case (RMT_CB_SOCKET): { - if(nd && nd->nbh) { - sm.m.cb_sm.id = id; - sm.m.cb_sm.connection_id = (tcp_connection_id)cid; - stun_tid_cpy(&(sm.m.cb_sm.tid),tid); - sm.m.cb_sm.s = s; - sm.m.cb_sm.message_integrity = message_integrity; + if (nd && nd->nbh) { + sm.m.cb_sm.id = id; + sm.m.cb_sm.connection_id = (tcp_connection_id)cid; + stun_tid_cpy(&(sm.m.cb_sm.tid), tid); + sm.m.cb_sm.s = s; + sm.m.cb_sm.message_integrity = message_integrity; - addr_cpy(&(sm.m.cb_sm.nd.src_addr),&(nd->src_addr)); - sm.m.cb_sm.nd.recv_tos = nd->recv_tos; - sm.m.cb_sm.nd.recv_ttl = nd->recv_ttl; - sm.m.cb_sm.nd.nbh = nd->nbh; - sm.m.cb_sm.can_resume = can_resume; + addr_cpy(&(sm.m.cb_sm.nd.src_addr), &(nd->src_addr)); + sm.m.cb_sm.nd.recv_tos = nd->recv_tos; + sm.m.cb_sm.nd.recv_ttl = nd->recv_ttl; + sm.m.cb_sm.nd.nbh = nd->nbh; + sm.m.cb_sm.can_resume = can_resume; - nd->nbh = NULL; - s_to_delete = NULL; - ret = 0; - } + nd->nbh = NULL; + s_to_delete = NULL; + ret = 0; + } - break; - } - case (RMT_MOBILE_SOCKET): { + break; + } + case (RMT_MOBILE_SOCKET): { - if(nd && nd->nbh) { - sm.m.sm.s = s; - addr_cpy(&(sm.m.sm.nd.src_addr),&(nd->src_addr)); - sm.m.sm.nd.recv_tos = nd->recv_tos; - sm.m.sm.nd.recv_ttl = nd->recv_ttl; - sm.m.sm.nd.nbh = nd->nbh; - sm.m.sm.can_resume = can_resume; + if (nd && nd->nbh) { + sm.m.sm.s = s; + addr_cpy(&(sm.m.sm.nd.src_addr), &(nd->src_addr)); + sm.m.sm.nd.recv_tos = nd->recv_tos; + sm.m.sm.nd.recv_ttl = nd->recv_ttl; + sm.m.sm.nd.nbh = nd->nbh; + sm.m.sm.can_resume = can_resume; - nd->nbh = NULL; - s_to_delete = NULL; - ret = 0; + nd->nbh = NULL; + s_to_delete = NULL; + ret = 0; - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Empty buffer with mobile socket\n",__FUNCTION__); - } + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Empty buffer with mobile socket\n", __FUNCTION__); + } - break; - } - default: { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: UNKNOWN RMT message: %d\n",__FUNCTION__,(int)rmt); - } - } + break; + } + default: { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: UNKNOWN RMT message: %d\n", __FUNCTION__, (int)rmt); + } + } - if(ret == 0) { + if (ret == 0) { - struct evbuffer *output = bufferevent_get_output(rs->out_buf); - if(output) { - evbuffer_add(output,&sm,sizeof(struct message_to_relay)); - } else { - TURN_LOG_FUNC( - TURN_LOG_LEVEL_ERROR, - "%s: Empty output buffer\n", - __FUNCTION__); - ret = -1; - s_to_delete = s; - } - } + struct evbuffer *output = bufferevent_get_output(rs->out_buf); + if (output) { + evbuffer_add(output, &sm, sizeof(struct message_to_relay)); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Empty output buffer\n", __FUNCTION__); + ret = -1; + s_to_delete = s; + } + } - err: +err: - IOA_CLOSE_SOCKET(s_to_delete); - if(nd && nd->nbh) { - ioa_network_buffer_delete(NULL, nd->nbh); - nd->nbh = NULL; - } + IOA_CLOSE_SOCKET(s_to_delete); + if (nd && nd->nbh) { + ioa_network_buffer_delete(NULL, nd->nbh); + nd->nbh = NULL; + } - if(ret<0) { - if(rmt == RMT_MOBILE_SOCKET) { - ioa_network_buffer_delete(NULL, sm.m.sm.nd.nbh); - sm.m.sm.nd.nbh = NULL; - } else if(rmt == RMT_CB_SOCKET) { - ioa_network_buffer_delete(NULL, sm.m.cb_sm.nd.nbh); - sm.m.cb_sm.nd.nbh = NULL; - } - } + if (ret < 0) { + if (rmt == RMT_MOBILE_SOCKET) { + ioa_network_buffer_delete(NULL, sm.m.sm.nd.nbh); + sm.m.sm.nd.nbh = NULL; + } else if (rmt == RMT_CB_SOCKET) { + ioa_network_buffer_delete(NULL, sm.m.cb_sm.nd.nbh); + sm.m.cb_sm.nd.nbh = NULL; + } + } - return ret; + return ret; } -int send_session_cancellation_to_relay(turnsession_id sid) -{ - int ret = 0; +int send_session_cancellation_to_relay(turnsession_id sid) { + int ret = 0; - struct message_to_relay sm; - memset(&sm, 0, sizeof(struct message_to_relay)); - sm.t = RMT_CANCEL_SESSION; + struct message_to_relay sm; + memset(&sm, 0, sizeof(struct message_to_relay)); + sm.t = RMT_CANCEL_SESSION; - turnserver_id id = (turnserver_id)(sid / TURN_SESSION_ID_FACTOR); + turnserver_id id = (turnserver_id)(sid / TURN_SESSION_ID_FACTOR); - struct relay_server *rs = get_relay_server(id); - if(!rs) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: can't find relay for turn_server_id: %d\n", __FUNCTION__,(int)id); - ret = -1; - goto err; - } + struct relay_server *rs = get_relay_server(id); + if (!rs) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: can't find relay for turn_server_id: %d\n", __FUNCTION__, (int)id); + ret = -1; + goto err; + } - sm.relay_server = rs; - sm.m.csm.id = sid; + sm.relay_server = rs; + sm.m.csm.id = sid; - { - struct evbuffer *output = bufferevent_get_output(rs->out_buf); - if(output) { - evbuffer_add(output,&sm,sizeof(struct message_to_relay)); - } else { - TURN_LOG_FUNC( - TURN_LOG_LEVEL_ERROR, - "%s: Empty output buffer\n", - __FUNCTION__); - ret = -1; - } - } + { + struct evbuffer *output = bufferevent_get_output(rs->out_buf); + if (output) { + evbuffer_add(output, &sm, sizeof(struct message_to_relay)); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Empty output buffer\n", __FUNCTION__); + ret = -1; + } + } - err: - return ret; +err: + return ret; } -static int handle_relay_message(relay_server_handle rs, struct message_to_relay *sm) -{ - if(rs && sm) { +static int handle_relay_message(relay_server_handle rs, struct message_to_relay *sm) { + if (rs && sm) { - switch (sm->t) { + switch (sm->t) { - case RMT_CANCEL_SESSION: { - turn_cancel_session(&(rs->server),sm->m.csm.id); - } - break; - case RMT_SOCKET: { + case RMT_CANCEL_SESSION: { + turn_cancel_session(&(rs->server), sm->m.csm.id); + } break; + case RMT_SOCKET: { - if (sm->m.sm.s->defer_nbh) { - if (!sm->m.sm.nd.nbh) { - sm->m.sm.nd.nbh = sm->m.sm.s->defer_nbh; - sm->m.sm.s->defer_nbh = NULL; - } else { - ioa_network_buffer_delete(rs->ioa_eng, sm->m.sm.s->defer_nbh); - sm->m.sm.s->defer_nbh = NULL; - } - } + if (sm->m.sm.s->defer_nbh) { + if (!sm->m.sm.nd.nbh) { + sm->m.sm.nd.nbh = sm->m.sm.s->defer_nbh; + sm->m.sm.s->defer_nbh = NULL; + } else { + ioa_network_buffer_delete(rs->ioa_eng, sm->m.sm.s->defer_nbh); + sm->m.sm.s->defer_nbh = NULL; + } + } - ioa_socket_handle s = sm->m.sm.s; + ioa_socket_handle s = sm->m.sm.s; - if (!s) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: socket EMPTY\n",__FUNCTION__); - } else if (s->read_event || s->bev) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: socket wrongly preset: 0x%lx : 0x%lx\n", - __FUNCTION__, (long) s->read_event, (long) s->bev); - IOA_CLOSE_SOCKET(s); - sm->m.sm.s = NULL; - } else { - s->e = rs->ioa_eng; - if(open_client_connection_session(&(rs->server), &(sm->m.sm))<0) { - IOA_CLOSE_SOCKET(s); - sm->m.sm.s = NULL; - } - } + if (!s) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: socket EMPTY\n", __FUNCTION__); + } else if (s->read_event || s->bev) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: socket wrongly preset: 0x%lx : 0x%lx\n", __FUNCTION__, + (long)s->read_event, (long)s->bev); + IOA_CLOSE_SOCKET(s); + sm->m.sm.s = NULL; + } else { + s->e = rs->ioa_eng; + if (open_client_connection_session(&(rs->server), &(sm->m.sm)) < 0) { + IOA_CLOSE_SOCKET(s); + sm->m.sm.s = NULL; + } + } - ioa_network_buffer_delete(rs->ioa_eng, sm->m.sm.nd.nbh); - sm->m.sm.nd.nbh = NULL; - } - break; - case RMT_CB_SOCKET: + ioa_network_buffer_delete(rs->ioa_eng, sm->m.sm.nd.nbh); + sm->m.sm.nd.nbh = NULL; + } break; + case RMT_CB_SOCKET: - turnserver_accept_tcp_client_data_connection(&(rs->server), sm->m.cb_sm.connection_id, - &(sm->m.cb_sm.tid), sm->m.cb_sm.s, sm->m.cb_sm.message_integrity, &(sm->m.cb_sm.nd), - /*sm->m.cb_sm.can_resume*/ - /* Note: we cannot resume this call, it must be authenticated in-place. - * There are two reasons for that: - * 1) Technical. That's very difficult with the current code structure. - * 2) Security (more important). We do not want 'stealing' connections between the users. - * */ - 0); + turnserver_accept_tcp_client_data_connection( + &(rs->server), sm->m.cb_sm.connection_id, &(sm->m.cb_sm.tid), sm->m.cb_sm.s, sm->m.cb_sm.message_integrity, + &(sm->m.cb_sm.nd), + /*sm->m.cb_sm.can_resume*/ + /* Note: we cannot resume this call, it must be authenticated in-place. + * There are two reasons for that: + * 1) Technical. That's very difficult with the current code structure. + * 2) Security (more important). We do not want 'stealing' connections between the users. + * */ + 0); - ioa_network_buffer_delete(rs->ioa_eng, sm->m.cb_sm.nd.nbh); - sm->m.cb_sm.nd.nbh = NULL; + ioa_network_buffer_delete(rs->ioa_eng, sm->m.cb_sm.nd.nbh); + sm->m.cb_sm.nd.nbh = NULL; - break; - case RMT_MOBILE_SOCKET: { + break; + case RMT_MOBILE_SOCKET: { - ioa_socket_handle s = sm->m.sm.s; + ioa_socket_handle s = sm->m.sm.s; - if (!s) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: mobile socket EMPTY\n",__FUNCTION__); - } else if (s->read_event || s->bev) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: mobile socket wrongly preset: 0x%lx : 0x%lx\n", - __FUNCTION__, (long) s->read_event, (long) s->bev); - IOA_CLOSE_SOCKET(s); - sm->m.sm.s = NULL; - } else { - s->e = rs->ioa_eng; - if(open_client_connection_session(&(rs->server), &(sm->m.sm))<0) { - IOA_CLOSE_SOCKET(s); - sm->m.sm.s = NULL; - } - } + if (!s) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: mobile socket EMPTY\n", __FUNCTION__); + } else if (s->read_event || s->bev) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: mobile socket wrongly preset: 0x%lx : 0x%lx\n", __FUNCTION__, + (long)s->read_event, (long)s->bev); + IOA_CLOSE_SOCKET(s); + sm->m.sm.s = NULL; + } else { + s->e = rs->ioa_eng; + if (open_client_connection_session(&(rs->server), &(sm->m.sm)) < 0) { + IOA_CLOSE_SOCKET(s); + sm->m.sm.s = NULL; + } + } - ioa_network_buffer_delete(rs->ioa_eng, sm->m.sm.nd.nbh); - sm->m.sm.nd.nbh = NULL; - break; - } - default: { - perror("Weird buffer type\n"); - } - } - } + ioa_network_buffer_delete(rs->ioa_eng, sm->m.sm.nd.nbh); + sm->m.sm.nd.nbh = NULL; + break; + } + default: { + perror("Weird buffer type\n"); + } + } + } - return 0; + return 0; } -static void handle_relay_auth_message(struct relay_server *rs, struct auth_message *am) -{ - am->resume_func(am->success, am->out_oauth, am->max_session_time, am->key, am->pwd, - &(rs->server), am->ctxkey, &(am->in_buffer), am->realm); - if (am->in_buffer.nbh) { - ioa_network_buffer_delete(rs->ioa_eng, am->in_buffer.nbh); - am->in_buffer.nbh = NULL; - } +static void handle_relay_auth_message(struct relay_server *rs, struct auth_message *am) { + am->resume_func(am->success, am->out_oauth, am->max_session_time, am->key, am->pwd, &(rs->server), am->ctxkey, + &(am->in_buffer), am->realm); + if (am->in_buffer.nbh) { + ioa_network_buffer_delete(rs->ioa_eng, am->in_buffer.nbh); + am->in_buffer.nbh = NULL; + } } -static void relay_receive_message(struct bufferevent *bev, void *ptr) -{ - struct message_to_relay sm; - int n = 0; - struct evbuffer *input = bufferevent_get_input(bev); - struct relay_server *rs = (struct relay_server *)ptr; +static void relay_receive_message(struct bufferevent *bev, void *ptr) { + struct message_to_relay sm; + int n = 0; + struct evbuffer *input = bufferevent_get_input(bev); + struct relay_server *rs = (struct relay_server *)ptr; - while ((n = evbuffer_remove(input, &sm, sizeof(struct message_to_relay))) > 0) { + while ((n = evbuffer_remove(input, &sm, sizeof(struct message_to_relay))) > 0) { - if (n != sizeof(struct message_to_relay)) { - perror("Weird buffer error\n"); - continue; - } + if (n != sizeof(struct message_to_relay)) { + perror("Weird buffer error\n"); + continue; + } - handle_relay_message(rs, &sm); - } + handle_relay_message(rs, &sm); + } } -static void relay_receive_auth_message(struct bufferevent *bev, void *ptr) -{ - struct auth_message am; - int n = 0; - struct evbuffer *input = bufferevent_get_input(bev); - struct relay_server *rs = (struct relay_server *)ptr; +static void relay_receive_auth_message(struct bufferevent *bev, void *ptr) { + struct auth_message am; + int n = 0; + struct evbuffer *input = bufferevent_get_input(bev); + struct relay_server *rs = (struct relay_server *)ptr; - while ((n = evbuffer_remove(input, &am, sizeof(struct auth_message))) > 0) { + while ((n = evbuffer_remove(input, &am, sizeof(struct auth_message))) > 0) { - if (n != sizeof(struct auth_message)) { - perror("Weird auth_buffer error\n"); - continue; - } + if (n != sizeof(struct auth_message)) { + perror("Weird auth_buffer error\n"); + continue; + } - handle_relay_auth_message(rs, &am); - } + handle_relay_auth_message(rs, &am); + } } -static int send_message_from_listener_to_client(ioa_engine_handle e, ioa_network_buffer_handle nbh, ioa_addr *origin, ioa_addr *destination) -{ +static int send_message_from_listener_to_client(ioa_engine_handle e, ioa_network_buffer_handle nbh, ioa_addr *origin, + ioa_addr *destination) { - struct message_to_listener mm; - mm.t = LMT_TO_CLIENT; - addr_cpy(&(mm.m.tc.origin),origin); - addr_cpy(&(mm.m.tc.destination),destination); - mm.m.tc.nbh = ioa_network_buffer_allocate(e); - ioa_network_buffer_header_init(mm.m.tc.nbh); - memcpy(ioa_network_buffer_data(mm.m.tc.nbh),ioa_network_buffer_data(nbh),ioa_network_buffer_get_size(nbh)); - ioa_network_buffer_set_size(mm.m.tc.nbh,ioa_network_buffer_get_size(nbh)); + struct message_to_listener mm; + mm.t = LMT_TO_CLIENT; + addr_cpy(&(mm.m.tc.origin), origin); + addr_cpy(&(mm.m.tc.destination), destination); + mm.m.tc.nbh = ioa_network_buffer_allocate(e); + ioa_network_buffer_header_init(mm.m.tc.nbh); + memcpy(ioa_network_buffer_data(mm.m.tc.nbh), ioa_network_buffer_data(nbh), ioa_network_buffer_get_size(nbh)); + ioa_network_buffer_set_size(mm.m.tc.nbh, ioa_network_buffer_get_size(nbh)); - struct evbuffer *output = bufferevent_get_output(turn_params.listener.out_buf); + struct evbuffer *output = bufferevent_get_output(turn_params.listener.out_buf); - evbuffer_add(output,&mm,sizeof(struct message_to_listener)); + evbuffer_add(output, &mm, sizeof(struct message_to_listener)); - return 0; + return 0; } -static void listener_receive_message(struct bufferevent *bev, void *ptr) -{ - UNUSED_ARG(ptr); +static void listener_receive_message(struct bufferevent *bev, void *ptr) { + UNUSED_ARG(ptr); - struct message_to_listener mm; - int n = 0; - struct evbuffer *input = bufferevent_get_input(bev); + struct message_to_listener mm; + int n = 0; + struct evbuffer *input = bufferevent_get_input(bev); - while ((n = evbuffer_remove(input, &mm, sizeof(struct message_to_listener))) > 0) { - if (n != sizeof(struct message_to_listener)) { - perror("Weird buffer error\n"); - continue; - } + while ((n = evbuffer_remove(input, &mm, sizeof(struct message_to_listener))) > 0) { + if (n != sizeof(struct message_to_listener)) { + perror("Weird buffer error\n"); + continue; + } - if (mm.t != LMT_TO_CLIENT) { - perror("Weird buffer type\n"); - continue; - } + if (mm.t != LMT_TO_CLIENT) { + perror("Weird buffer type\n"); + continue; + } - size_t relay_thread_index = 0; + size_t relay_thread_index = 0; - if(turn_params.net_engine_version == NEV_UDP_SOCKET_PER_THREAD) { - size_t ri; - for(ri=0;rithr, pthread_self())) { - relay_thread_index=ri; - break; - } - } - } + if (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_THREAD) { + size_t ri; + for (ri = 0; ri < get_real_general_relay_servers_number(); ri++) { + if (!(general_relay_servers[ri])) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Wrong general relay number: %d, total %d\n", __FUNCTION__, (int)ri, + (int)get_real_general_relay_servers_number()); + } else if (pthread_equal(general_relay_servers[ri]->thr, pthread_self())) { + relay_thread_index = ri; + break; + } + } + } - size_t i; - int found = 0; - for(i=0;i1) { + if ((turn_params.net_engine_version == NEV_UDP_SOCKET_PER_ENDPOINT) && turn_params.general_relay_servers_number > 1) { - /* UDP: */ - if(!turn_params.no_udp) { + /* UDP: */ + if (!turn_params.no_udp) { - barrier_count += turn_params.listener.addrs_number; + barrier_count += turn_params.listener.addrs_number; - if(turn_params.rfc5780) { - barrier_count += turn_params.listener.addrs_number; - } - } + if (turn_params.rfc5780) { + barrier_count += turn_params.listener.addrs_number; + } + } - if(!turn_params.no_dtls && (turn_params.no_udp || (turn_params.listener_port != turn_params.tls_listener_port))) { + if (!turn_params.no_dtls && (turn_params.no_udp || (turn_params.listener_port != turn_params.tls_listener_port))) { - barrier_count += turn_params.listener.addrs_number; + barrier_count += turn_params.listener.addrs_number; - if(turn_params.rfc5780) { - barrier_count += turn_params.listener.addrs_number; - } - } + if (turn_params.rfc5780) { + barrier_count += turn_params.listener.addrs_number; + } + } - if(!turn_params.no_udp || !turn_params.no_dtls) { - barrier_count += (unsigned int)turn_params.aux_servers_list.size; - } - } + if (!turn_params.no_udp || !turn_params.no_dtls) { + barrier_count += (unsigned int)turn_params.aux_servers_list.size; + } + } #endif #if !defined(TURN_NO_THREAD_BARRIERS) - { - if(pthread_barrier_init(&barrier,NULL,barrier_count)<0) - perror("barrier init"); - } + { + if (pthread_barrier_init(&barrier, NULL, barrier_count) < 0) + perror("barrier init"); + } #endif } -static void setup_socket_per_endpoint_udp_listener_servers(void) -{ - size_t i = 0; +static void setup_socket_per_endpoint_udp_listener_servers(void) { + size_t i = 0; - /* Adjust udp relay number */ + /* Adjust udp relay number */ - if(turn_params.general_relay_servers_number>1) { + if (turn_params.general_relay_servers_number > 1) { - if (!turn_params.no_udp) { + if (!turn_params.no_udp) { - turn_params.udp_relay_servers_number += turn_params.listener.addrs_number; + turn_params.udp_relay_servers_number += turn_params.listener.addrs_number; - if (turn_params.rfc5780) { - turn_params.udp_relay_servers_number += turn_params.listener.addrs_number; - } - } + if (turn_params.rfc5780) { + turn_params.udp_relay_servers_number += turn_params.listener.addrs_number; + } + } - if (!turn_params.no_dtls && (turn_params.no_udp || (turn_params.listener_port != turn_params.tls_listener_port))) { + if (!turn_params.no_dtls && (turn_params.no_udp || (turn_params.listener_port != turn_params.tls_listener_port))) { - turn_params.udp_relay_servers_number += turn_params.listener.addrs_number; + turn_params.udp_relay_servers_number += turn_params.listener.addrs_number; - if (turn_params.rfc5780) { - turn_params.udp_relay_servers_number += turn_params.listener.addrs_number; - } - } + if (turn_params.rfc5780) { + turn_params.udp_relay_servers_number += turn_params.listener.addrs_number; + } + } - if (!turn_params.no_udp || !turn_params.no_dtls) { - turn_params.udp_relay_servers_number += (unsigned int) turn_params.aux_servers_list.size; - } - } + if (!turn_params.no_udp || !turn_params.no_dtls) { + turn_params.udp_relay_servers_number += (unsigned int)turn_params.aux_servers_list.size; + } + } - { - if (!turn_params.no_udp || !turn_params.no_dtls) { + { + if (!turn_params.no_udp || !turn_params.no_dtls) { - for (i = 0; i < get_real_udp_relay_servers_number(); i++) { + for (i = 0; i < get_real_udp_relay_servers_number(); i++) { - ioa_engine_handle e = turn_params.listener.ioa_eng; - int is_5780 = turn_params.rfc5780; + ioa_engine_handle e = turn_params.listener.ioa_eng; + int is_5780 = turn_params.rfc5780; - if(turn_params.general_relay_servers_number<=1) { - while(!(general_relay_servers[0]->ioa_eng)) - sched_yield(); - udp_relay_servers[i] = general_relay_servers[0]; - continue; - } else if(turn_params.general_relay_servers_number>1) { - e = create_new_listener_engine(); - is_5780 = is_5780 && (i >= (size_t) (turn_params.aux_servers_list.size)); - } + if (turn_params.general_relay_servers_number <= 1) { + while (!(general_relay_servers[0]->ioa_eng)) + sched_yield(); + udp_relay_servers[i] = general_relay_servers[0]; + continue; + } else if (turn_params.general_relay_servers_number > 1) { + e = create_new_listener_engine(); + is_5780 = is_5780 && (i >= (size_t)(turn_params.aux_servers_list.size)); + } - super_memory_t *sm = new_super_memory_region(); - struct relay_server* udp_rs = (struct relay_server*) allocate_super_memory_region(sm, sizeof(struct relay_server)); - udp_rs->id = (turnserver_id) i + TURNSERVER_ID_BOUNDARY_BETWEEN_TCP_AND_UDP; - udp_rs->sm = sm; - setup_relay_server(udp_rs, e, is_5780); - udp_relay_servers[i] = udp_rs; - } - } - } + super_memory_t *sm = new_super_memory_region(); + struct relay_server *udp_rs = + (struct relay_server *)allocate_super_memory_region(sm, sizeof(struct relay_server)); + udp_rs->id = (turnserver_id)i + TURNSERVER_ID_BOUNDARY_BETWEEN_TCP_AND_UDP; + udp_rs->sm = sm; + setup_relay_server(udp_rs, e, is_5780); + udp_relay_servers[i] = udp_rs; + } + } + } - int udp_relay_server_index = 0; + int udp_relay_server_index = 0; - /* Create listeners */ + /* Create listeners */ - /* Aux UDP servers */ - for(i=0; iioa_eng, sizeof(dtls_listener_relay_server_type*)); - turn_params.listener.aux_udp_services[index][0] = create_dtls_listener_server(turn_params.listener_ifname, saddr, port, turn_params.verbose, udp_relay_servers[udp_relay_server_index]->ioa_eng, &(udp_relay_servers[udp_relay_server_index]->server), 1, NULL); + turn_params.listener.aux_udp_services[index] = (dtls_listener_relay_server_type **)allocate_super_memory_engine( + udp_relay_servers[udp_relay_server_index]->ioa_eng, sizeof(dtls_listener_relay_server_type *)); + turn_params.listener.aux_udp_services[index][0] = + create_dtls_listener_server(turn_params.listener_ifname, saddr, port, turn_params.verbose, + udp_relay_servers[udp_relay_server_index]->ioa_eng, + &(udp_relay_servers[udp_relay_server_index]->server), 1, NULL); - if(turn_params.general_relay_servers_number>1) { - ++udp_relay_server_index; - pthread_t thr; - if(pthread_create(&thr, NULL, run_udp_listener_thread, turn_params.listener.aux_udp_services[index][0])) { - perror("Cannot create aux listener thread\n"); - exit(-1); - } - pthread_detach(thr); - } - } - } + if (turn_params.general_relay_servers_number > 1) { + ++udp_relay_server_index; + pthread_t thr; + if (pthread_create(&thr, NULL, run_udp_listener_thread, turn_params.listener.aux_udp_services[index][0])) { + perror("Cannot create aux listener thread\n"); + exit(-1); + } + pthread_detach(thr); + } + } + } - /* Main servers */ - for(i=0; iioa_eng, sizeof(dtls_listener_relay_server_type*)); - turn_params.listener.udp_services[index][0] = create_dtls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], turn_params.listener_port, turn_params.verbose, udp_relay_servers[udp_relay_server_index]->ioa_eng, &(udp_relay_servers[udp_relay_server_index]->server), 1, NULL); + turn_params.listener.udp_services[index] = (dtls_listener_relay_server_type **)allocate_super_memory_engine( + udp_relay_servers[udp_relay_server_index]->ioa_eng, sizeof(dtls_listener_relay_server_type *)); + turn_params.listener.udp_services[index][0] = create_dtls_listener_server( + turn_params.listener_ifname, turn_params.listener.addrs[i], turn_params.listener_port, turn_params.verbose, + udp_relay_servers[udp_relay_server_index]->ioa_eng, &(udp_relay_servers[udp_relay_server_index]->server), 1, + NULL); - if(turn_params.general_relay_servers_number>1) { - ++udp_relay_server_index; - pthread_t thr; - if(pthread_create(&thr, NULL, run_udp_listener_thread, turn_params.listener.udp_services[index][0])) { - perror("Cannot create listener thread\n"); - exit(-1); - } - pthread_detach(thr); - } + if (turn_params.general_relay_servers_number > 1) { + ++udp_relay_server_index; + pthread_t thr; + if (pthread_create(&thr, NULL, run_udp_listener_thread, turn_params.listener.udp_services[index][0])) { + perror("Cannot create listener thread\n"); + exit(-1); + } + pthread_detach(thr); + } - if(turn_params.rfc5780) { + if (turn_params.rfc5780) { - turn_params.listener.udp_services[index+1] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(udp_relay_servers[udp_relay_server_index]->ioa_eng, sizeof(dtls_listener_relay_server_type*)); - turn_params.listener.udp_services[index+1][0] = create_dtls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], get_alt_listener_port(), turn_params.verbose, udp_relay_servers[udp_relay_server_index]->ioa_eng, &(udp_relay_servers[udp_relay_server_index]->server), 1, NULL); + turn_params.listener.udp_services[index + 1] = (dtls_listener_relay_server_type **)allocate_super_memory_engine( + udp_relay_servers[udp_relay_server_index]->ioa_eng, sizeof(dtls_listener_relay_server_type *)); + turn_params.listener.udp_services[index + 1][0] = create_dtls_listener_server( + turn_params.listener_ifname, turn_params.listener.addrs[i], get_alt_listener_port(), turn_params.verbose, + udp_relay_servers[udp_relay_server_index]->ioa_eng, &(udp_relay_servers[udp_relay_server_index]->server), 1, + NULL); - if(turn_params.general_relay_servers_number>1) { - ++udp_relay_server_index; - pthread_t thr; - if(pthread_create(&thr, NULL, run_udp_listener_thread, turn_params.listener.udp_services[index+1][0])) { - perror("Cannot create listener thread\n"); - exit(-1); - } - pthread_detach(thr); - } - } - } else { - turn_params.listener.udp_services[index] = NULL; - if(turn_params.rfc5780) - turn_params.listener.udp_services[index+1] = NULL; - } - if(!turn_params.no_dtls && (turn_params.no_udp || (turn_params.listener_port != turn_params.tls_listener_port))) { + if (turn_params.general_relay_servers_number > 1) { + ++udp_relay_server_index; + pthread_t thr; + if (pthread_create(&thr, NULL, run_udp_listener_thread, turn_params.listener.udp_services[index + 1][0])) { + perror("Cannot create listener thread\n"); + exit(-1); + } + pthread_detach(thr); + } + } + } else { + turn_params.listener.udp_services[index] = NULL; + if (turn_params.rfc5780) + turn_params.listener.udp_services[index + 1] = NULL; + } + if (!turn_params.no_dtls && (turn_params.no_udp || (turn_params.listener_port != turn_params.tls_listener_port))) { - turn_params.listener.dtls_services[index] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(udp_relay_servers[udp_relay_server_index]->ioa_eng, sizeof(dtls_listener_relay_server_type*)); - turn_params.listener.dtls_services[index][0] = create_dtls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], turn_params.tls_listener_port, turn_params.verbose, udp_relay_servers[udp_relay_server_index]->ioa_eng, &(udp_relay_servers[udp_relay_server_index]->server), 1, NULL); + turn_params.listener.dtls_services[index] = (dtls_listener_relay_server_type **)allocate_super_memory_engine( + udp_relay_servers[udp_relay_server_index]->ioa_eng, sizeof(dtls_listener_relay_server_type *)); + turn_params.listener.dtls_services[index][0] = create_dtls_listener_server( + turn_params.listener_ifname, turn_params.listener.addrs[i], turn_params.tls_listener_port, + turn_params.verbose, udp_relay_servers[udp_relay_server_index]->ioa_eng, + &(udp_relay_servers[udp_relay_server_index]->server), 1, NULL); - if(turn_params.general_relay_servers_number>1) { - ++udp_relay_server_index; - pthread_t thr; - if(pthread_create(&thr, NULL, run_udp_listener_thread, turn_params.listener.dtls_services[index][0])) { - perror("Cannot create listener thread\n"); - exit(-1); - } - pthread_detach(thr); - } + if (turn_params.general_relay_servers_number > 1) { + ++udp_relay_server_index; + pthread_t thr; + if (pthread_create(&thr, NULL, run_udp_listener_thread, turn_params.listener.dtls_services[index][0])) { + perror("Cannot create listener thread\n"); + exit(-1); + } + pthread_detach(thr); + } - if(turn_params.rfc5780) { + if (turn_params.rfc5780) { - turn_params.listener.dtls_services[index+1] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(udp_relay_servers[udp_relay_server_index]->ioa_eng, sizeof(dtls_listener_relay_server_type*)); - turn_params.listener.dtls_services[index+1][0] = create_dtls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], get_alt_tls_listener_port(), turn_params.verbose, udp_relay_servers[udp_relay_server_index]->ioa_eng, &(udp_relay_servers[udp_relay_server_index]->server), 1, NULL); + turn_params.listener.dtls_services[index + 1] = + (dtls_listener_relay_server_type **)allocate_super_memory_engine( + udp_relay_servers[udp_relay_server_index]->ioa_eng, sizeof(dtls_listener_relay_server_type *)); + turn_params.listener.dtls_services[index + 1][0] = create_dtls_listener_server( + turn_params.listener_ifname, turn_params.listener.addrs[i], get_alt_tls_listener_port(), + turn_params.verbose, udp_relay_servers[udp_relay_server_index]->ioa_eng, + &(udp_relay_servers[udp_relay_server_index]->server), 1, NULL); - if(turn_params.general_relay_servers_number>1) { - ++udp_relay_server_index; - pthread_t thr; - if(pthread_create(&thr, NULL, run_udp_listener_thread, turn_params.listener.dtls_services[index+1][0])) { - perror("Cannot create listener thread\n"); - exit(-1); - } - pthread_detach(thr); - } - } - } else { - turn_params.listener.dtls_services[index] = NULL; - if(turn_params.rfc5780) - turn_params.listener.dtls_services[index+1] = NULL; - } - } + if (turn_params.general_relay_servers_number > 1) { + ++udp_relay_server_index; + pthread_t thr; + if (pthread_create(&thr, NULL, run_udp_listener_thread, turn_params.listener.dtls_services[index + 1][0])) { + perror("Cannot create listener thread\n"); + exit(-1); + } + pthread_detach(thr); + } + } + } else { + turn_params.listener.dtls_services[index] = NULL; + if (turn_params.rfc5780) + turn_params.listener.dtls_services[index + 1] = NULL; + } + } } -static void setup_socket_per_thread_udp_listener_servers(void) -{ - size_t i = 0; - size_t relayindex = 0; +static void setup_socket_per_thread_udp_listener_servers(void) { + size_t i = 0; + size_t relayindex = 0; - /* Create listeners */ + /* Create listeners */ - for(relayindex=0;relayindexioa_eng) || !(general_relay_servers[relayindex]->server.e)) - sched_yield(); - } + for (relayindex = 0; relayindex < get_real_general_relay_servers_number(); relayindex++) { + while (!(general_relay_servers[relayindex]->ioa_eng) || !(general_relay_servers[relayindex]->server.e)) + sched_yield(); + } - /* Aux UDP servers */ - for(i=0; iioa_eng, &(general_relay_servers[relayindex]->server), !relayindex, NULL); - } - } - } + for (relayindex = 0; relayindex < get_real_general_relay_servers_number(); relayindex++) { + turn_params.listener.aux_udp_services[index][relayindex] = create_dtls_listener_server( + turn_params.listener_ifname, saddr, port, turn_params.verbose, general_relay_servers[relayindex]->ioa_eng, + &(general_relay_servers[relayindex]->server), !relayindex, NULL); + } + } + } - /* Main servers */ - for(i=0; iioa_eng, &(general_relay_servers[relayindex]->server), !relayindex, NULL); - } + for (relayindex = 0; relayindex < get_real_general_relay_servers_number(); relayindex++) { + turn_params.listener.udp_services[index][relayindex] = create_dtls_listener_server( + turn_params.listener_ifname, turn_params.listener.addrs[i], turn_params.listener_port, turn_params.verbose, + general_relay_servers[relayindex]->ioa_eng, &(general_relay_servers[relayindex]->server), !relayindex, + NULL); + } - if(turn_params.rfc5780) { + if (turn_params.rfc5780) { - turn_params.listener.udp_services[index+1] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(dtls_listener_relay_server_type*) * get_real_general_relay_servers_number()); + turn_params.listener.udp_services[index + 1] = (dtls_listener_relay_server_type **)allocate_super_memory_engine( + turn_params.listener.ioa_eng, + sizeof(dtls_listener_relay_server_type *) * get_real_general_relay_servers_number()); - for(relayindex=0;relayindexioa_eng, &(general_relay_servers[relayindex]->server), !relayindex, NULL); - } - } - } else { - turn_params.listener.udp_services[index] = NULL; - if(turn_params.rfc5780) - turn_params.listener.udp_services[index+1] = NULL; - } - if(!turn_params.no_dtls && (turn_params.no_udp || (turn_params.listener_port != turn_params.tls_listener_port))) { + for (relayindex = 0; relayindex < get_real_general_relay_servers_number(); relayindex++) { + turn_params.listener.udp_services[index + 1][relayindex] = create_dtls_listener_server( + turn_params.listener_ifname, turn_params.listener.addrs[i], get_alt_listener_port(), turn_params.verbose, + general_relay_servers[relayindex]->ioa_eng, &(general_relay_servers[relayindex]->server), !relayindex, + NULL); + } + } + } else { + turn_params.listener.udp_services[index] = NULL; + if (turn_params.rfc5780) + turn_params.listener.udp_services[index + 1] = NULL; + } + if (!turn_params.no_dtls && (turn_params.no_udp || (turn_params.listener_port != turn_params.tls_listener_port))) { - turn_params.listener.dtls_services[index] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(dtls_listener_relay_server_type*) * get_real_general_relay_servers_number()); + turn_params.listener.dtls_services[index] = (dtls_listener_relay_server_type **)allocate_super_memory_engine( + turn_params.listener.ioa_eng, + sizeof(dtls_listener_relay_server_type *) * get_real_general_relay_servers_number()); - for(relayindex=0;relayindexioa_eng, &(general_relay_servers[relayindex]->server), !relayindex, NULL); - } + for (relayindex = 0; relayindex < get_real_general_relay_servers_number(); relayindex++) { + turn_params.listener.dtls_services[index][relayindex] = create_dtls_listener_server( + turn_params.listener_ifname, turn_params.listener.addrs[i], turn_params.tls_listener_port, + turn_params.verbose, general_relay_servers[relayindex]->ioa_eng, + &(general_relay_servers[relayindex]->server), !relayindex, NULL); + } - if(turn_params.rfc5780) { + if (turn_params.rfc5780) { - turn_params.listener.dtls_services[index+1] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(dtls_listener_relay_server_type*) * get_real_general_relay_servers_number()); + turn_params.listener.dtls_services[index + 1] = + (dtls_listener_relay_server_type **)allocate_super_memory_engine( + turn_params.listener.ioa_eng, + sizeof(dtls_listener_relay_server_type *) * get_real_general_relay_servers_number()); - for(relayindex=0;relayindexioa_eng, &(general_relay_servers[relayindex]->server), !relayindex, NULL); - } - } - } else { - turn_params.listener.dtls_services[index] = NULL; - if(turn_params.rfc5780) - turn_params.listener.dtls_services[index+1] = NULL; - } - } + for (relayindex = 0; relayindex < get_real_general_relay_servers_number(); relayindex++) { + turn_params.listener.dtls_services[index + 1][relayindex] = create_dtls_listener_server( + turn_params.listener_ifname, turn_params.listener.addrs[i], get_alt_tls_listener_port(), + turn_params.verbose, general_relay_servers[relayindex]->ioa_eng, + &(general_relay_servers[relayindex]->server), !relayindex, NULL); + } + } + } else { + turn_params.listener.dtls_services[index] = NULL; + if (turn_params.rfc5780) + turn_params.listener.dtls_services[index + 1] = NULL; + } + } } -static void setup_socket_per_session_udp_listener_servers(void) -{ - size_t i = 0; +static void setup_socket_per_session_udp_listener_servers(void) { + size_t i = 0; - /* Aux UDP servers */ - for(i=0; iss.sa_family == turn_params.listener.encaddrs[i]->ss.sa_family) { - index=i; - break; - } - } - } - if(index!=0xffff) { - for(i=0;iss.sa_family == addr->ss.sa_family) { - addr_cpy(alt_addr,caddr); - addr_set_port(alt_addr, alt_port); - return 0; - } - } - } - } - } + for (i = 0; i < turn_params.listener.addrs_number; i++) { + if (turn_params.listener.encaddrs && turn_params.listener.encaddrs[i]) { + if (addr->ss.sa_family == turn_params.listener.encaddrs[i]->ss.sa_family) { + index = i; + break; + } + } + } + if (index != 0xffff) { + for (i = 0; i < turn_params.listener.addrs_number; i++) { + size_t ind = (index + i + 1) % turn_params.listener.addrs_number; + if (turn_params.listener.encaddrs && turn_params.listener.encaddrs[ind]) { + ioa_addr *caddr = turn_params.listener.encaddrs[ind]; + if (caddr->ss.sa_family == addr->ss.sa_family) { + addr_cpy(alt_addr, caddr); + addr_set_port(alt_addr, alt_port); + return 0; + } + } + } + } + } - return -1; + return -1; } -static void run_events(struct event_base *eb, ioa_engine_handle e) -{ - if(!eb && e) - eb = e->event_base; +static void run_events(struct event_base *eb, ioa_engine_handle e) { + if (!eb && e) + eb = e->event_base; - if (!eb) - return; + if (!eb) + return; - struct timeval timeout; + struct timeval timeout; - timeout.tv_sec = 5; - timeout.tv_usec = 0; + timeout.tv_sec = 5; + timeout.tv_usec = 0; - event_base_loopexit(eb, &timeout); + event_base_loopexit(eb, &timeout); - event_base_dispatch(eb); + event_base_dispatch(eb); } -void run_listener_server(struct listener_server *ls) -{ - unsigned int cycle = 0; - while (!turn_params.stop_turn_server) { +void run_listener_server(struct listener_server *ls) { + unsigned int cycle = 0; + while (!turn_params.stop_turn_server) { - #if !defined(TURN_NO_SYSTEMD) - sd_notify (0, "READY=1"); - #endif +#if !defined(TURN_NO_SYSTEMD) + sd_notify(0, "READY=1"); +#endif - if (eve(turn_params.verbose)) { - if ((cycle++ & 15) == 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: cycle=%u\n", __FUNCTION__, cycle); - } - } + if (eve(turn_params.verbose)) { + if ((cycle++ & 15) == 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: cycle=%u\n", __FUNCTION__, cycle); + } + } - run_events(ls->event_base, ls->ioa_eng); + run_events(ls->event_base, ls->ioa_eng); - rollover_logfile(); - } + rollover_logfile(); + } - #if !defined(TURN_NO_SYSTEMD) - sd_notify (0, "STOPPING=1"); - #endif +#if !defined(TURN_NO_SYSTEMD) + sd_notify(0, "STOPPING=1"); +#endif } -static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int to_set_rfc5780) -{ - struct bufferevent *pair[2]; +static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int to_set_rfc5780) { + struct bufferevent *pair[2]; - if(e) { - rs->event_base = e->event_base; - rs->ioa_eng = e; - } else { - rs->event_base = turn_event_base_new(); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"IO method (general relay thread): %s\n",event_base_get_method(rs->event_base)); - rs->ioa_eng = create_ioa_engine(rs->sm, rs->event_base, turn_params.listener.tp, turn_params.relay_ifname, - turn_params.relays_number, turn_params.relay_addrs, turn_params.default_relays, turn_params.verbose + if (e) { + rs->event_base = e->event_base; + rs->ioa_eng = e; + } else { + rs->event_base = turn_event_base_new(); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "IO method (general relay thread): %s\n", event_base_get_method(rs->event_base)); + rs->ioa_eng = create_ioa_engine(rs->sm, rs->event_base, turn_params.listener.tp, turn_params.relay_ifname, + turn_params.relays_number, turn_params.relay_addrs, turn_params.default_relays, + turn_params.verbose #if !defined(TURN_NO_HIREDIS) - ,&turn_params.redis_statsdb + , + &turn_params.redis_statsdb #endif - ); - set_ssl_ctx(rs->ioa_eng, &turn_params); - ioa_engine_set_rtcp_map(rs->ioa_eng, turn_params.listener.rtcpmap); - } + ); + set_ssl_ctx(rs->ioa_eng, &turn_params); + ioa_engine_set_rtcp_map(rs->ioa_eng, turn_params.listener.rtcpmap); + } - bufferevent_pair_new(rs->event_base, TURN_BUFFEREVENTS_OPTIONS, pair); - rs->in_buf = pair[0]; - rs->out_buf = pair[1]; - bufferevent_setcb(rs->in_buf, relay_receive_message, NULL, NULL, rs); - bufferevent_enable(rs->in_buf, EV_READ); + bufferevent_pair_new(rs->event_base, TURN_BUFFEREVENTS_OPTIONS, pair); + rs->in_buf = pair[0]; + rs->out_buf = pair[1]; + bufferevent_setcb(rs->in_buf, relay_receive_message, NULL, NULL, rs); + bufferevent_enable(rs->in_buf, EV_READ); - bufferevent_pair_new(rs->event_base, TURN_BUFFEREVENTS_OPTIONS, pair); - rs->auth_in_buf = pair[0]; - rs->auth_out_buf = pair[1]; - bufferevent_setcb(rs->auth_in_buf, relay_receive_auth_message, NULL, NULL, rs); - bufferevent_enable(rs->auth_in_buf, EV_READ); + bufferevent_pair_new(rs->event_base, TURN_BUFFEREVENTS_OPTIONS, pair); + rs->auth_in_buf = pair[0]; + rs->auth_out_buf = pair[1]; + bufferevent_setcb(rs->auth_in_buf, relay_receive_auth_message, NULL, NULL, rs); + bufferevent_enable(rs->auth_in_buf, EV_READ); - init_turn_server(&(rs->server), - rs->id, turn_params.verbose, - rs->ioa_eng, turn_params.ct, 0, - turn_params.fingerprint, DONT_FRAGMENT_SUPPORTED, - start_user_check, - check_new_allocation_quota, - release_allocation_quota, - turn_params.external_ip, - &turn_params.check_origin, - &turn_params.no_tcp_relay, - &turn_params.no_udp_relay, - &turn_params.stale_nonce, - &turn_params.max_allocate_lifetime, - &turn_params.channel_lifetime, - &turn_params.permission_lifetime, - &turn_params.stun_only, - &turn_params.no_stun, - &turn_params.no_software_attribute, - &turn_params.web_admin_listen_on_workers, - &turn_params.alternate_servers_list, - &turn_params.tls_alternate_servers_list, - &turn_params.aux_servers_list, - turn_params.udp_self_balance, - &turn_params.no_multicast_peers, &turn_params.allow_loopback_peers, - &turn_params.ip_whitelist, &turn_params.ip_blacklist, - send_socket_to_relay, - &turn_params.secure_stun, &turn_params.mobility, - turn_params.server_relay, - send_turn_session_info, - send_https_socket, - allocate_bps, - turn_params.oauth, - turn_params.oauth_server_name, - turn_params.acme_redirect, - turn_params.allocation_default_address_family, - &turn_params.log_binding, - &turn_params.no_stun_backward_compatibility, - &turn_params.response_origin_only_with_rfc5780 - ); - - if(to_set_rfc5780) { - set_rfc5780(&(rs->server), get_alt_addr, send_message_from_listener_to_client); - } + init_turn_server(&(rs->server), rs->id, turn_params.verbose, rs->ioa_eng, turn_params.ct, 0, turn_params.fingerprint, + DONT_FRAGMENT_SUPPORTED, start_user_check, check_new_allocation_quota, release_allocation_quota, + turn_params.external_ip, &turn_params.check_origin, &turn_params.no_tcp_relay, + &turn_params.no_udp_relay, &turn_params.stale_nonce, &turn_params.max_allocate_lifetime, + &turn_params.channel_lifetime, &turn_params.permission_lifetime, &turn_params.stun_only, + &turn_params.no_stun, &turn_params.no_software_attribute, &turn_params.web_admin_listen_on_workers, + &turn_params.alternate_servers_list, &turn_params.tls_alternate_servers_list, + &turn_params.aux_servers_list, turn_params.udp_self_balance, &turn_params.no_multicast_peers, + &turn_params.allow_loopback_peers, &turn_params.ip_whitelist, &turn_params.ip_blacklist, + send_socket_to_relay, &turn_params.secure_stun, &turn_params.mobility, turn_params.server_relay, + send_turn_session_info, send_https_socket, allocate_bps, turn_params.oauth, + turn_params.oauth_server_name, turn_params.acme_redirect, + turn_params.allocation_default_address_family, &turn_params.log_binding, + &turn_params.no_stun_backward_compatibility, &turn_params.response_origin_only_with_rfc5780); - if(turn_params.net_engine_version == NEV_UDP_SOCKET_PER_THREAD) { - setup_tcp_listener_servers(rs->ioa_eng, rs); - } + if (to_set_rfc5780) { + set_rfc5780(&(rs->server), get_alt_addr, send_message_from_listener_to_client); + } + + if (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_THREAD) { + setup_tcp_listener_servers(rs->ioa_eng, rs); + } } -static void *run_general_relay_thread(void *arg) -{ +static void *run_general_relay_thread(void *arg) { static int always_true = 1; struct relay_server *rs = (struct relay_server *)arg; - - int udp_reuses_the_same_relay_server = (turn_params.general_relay_servers_number<=1) || (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_THREAD) || (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_SESSION); + + int udp_reuses_the_same_relay_server = (turn_params.general_relay_servers_number <= 1) || + (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_THREAD) || + (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_SESSION); int we_need_rfc5780 = udp_reuses_the_same_relay_server && turn_params.rfc5780; @@ -1663,219 +1667,214 @@ static void *run_general_relay_thread(void *arg) barrier_wait(); - while(always_true) { + while (always_true) { run_events(rs->event_base, rs->ioa_eng); } - + return arg; } -static void setup_general_relay_servers(void) -{ - size_t i = 0; +static void setup_general_relay_servers(void) { + size_t i = 0; - for(i=0;iid = (turnserver_id)i; - general_relay_servers[i]->sm = NULL; - setup_relay_server(general_relay_servers[i], turn_params.listener.ioa_eng, ((turn_params.net_engine_version == NEV_UDP_SOCKET_PER_THREAD) || (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_SESSION)) && turn_params.rfc5780); - general_relay_servers[i]->thr = pthread_self(); - } else { - super_memory_t *sm = new_super_memory_region(); - general_relay_servers[i] = (struct relay_server*)allocate_super_memory_region(sm,sizeof(struct relay_server)); - general_relay_servers[i]->id = (turnserver_id)i; - general_relay_servers[i]->sm = sm; - if(pthread_create(&(general_relay_servers[i]->thr), NULL, run_general_relay_thread, general_relay_servers[i])) { - perror("Cannot create relay thread\n"); - exit(-1); - } - pthread_detach(general_relay_servers[i]->thr); - } - } + if (turn_params.general_relay_servers_number == 0) { + general_relay_servers[i] = (struct relay_server *)allocate_super_memory_engine(turn_params.listener.ioa_eng, + sizeof(struct relay_server)); + general_relay_servers[i]->id = (turnserver_id)i; + general_relay_servers[i]->sm = NULL; + setup_relay_server(general_relay_servers[i], turn_params.listener.ioa_eng, + ((turn_params.net_engine_version == NEV_UDP_SOCKET_PER_THREAD) || + (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_SESSION)) && + turn_params.rfc5780); + general_relay_servers[i]->thr = pthread_self(); + } else { + super_memory_t *sm = new_super_memory_region(); + general_relay_servers[i] = (struct relay_server *)allocate_super_memory_region(sm, sizeof(struct relay_server)); + general_relay_servers[i]->id = (turnserver_id)i; + general_relay_servers[i]->sm = sm; + if (pthread_create(&(general_relay_servers[i]->thr), NULL, run_general_relay_thread, general_relay_servers[i])) { + perror("Cannot create relay thread\n"); + exit(-1); + } + pthread_detach(general_relay_servers[i]->thr); + } + } } static int run_auth_server_flag = 1; -static void* run_auth_server_thread(void *arg) -{ - ignore_sigpipe(); +static void *run_auth_server_thread(void *arg) { + ignore_sigpipe(); - struct auth_server *as = (struct auth_server*)arg; + struct auth_server *as = (struct auth_server *)arg; - authserver_id id = as->id; + authserver_id id = as->id; - if(id == 0) { + if (id == 0) { - reread_realms(); - update_white_and_black_lists(); + reread_realms(); + update_white_and_black_lists(); - barrier_wait(); + barrier_wait(); - while(run_auth_server_flag) { + while (run_auth_server_flag) { #if defined(DB_TEST) - run_db_test(); + run_db_test(); #endif - sleep(5); - reread_realms(); - update_white_and_black_lists(); - } + sleep(5); + reread_realms(); + update_white_and_black_lists(); + } - } else { + } else { - memset(as, 0, sizeof(struct auth_server)); + memset(as, 0, sizeof(struct auth_server)); - as->id = id; + as->id = id; - as->event_base = turn_event_base_new(); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"IO method (auth thread): %s\n",event_base_get_method(as->event_base)); + as->event_base = turn_event_base_new(); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "IO method (auth thread): %s\n", event_base_get_method(as->event_base)); - struct bufferevent *pair[2]; + struct bufferevent *pair[2]; - bufferevent_pair_new(as->event_base, TURN_BUFFEREVENTS_OPTIONS, pair); - as->in_buf = pair[0]; - as->out_buf = pair[1]; - bufferevent_setcb(as->in_buf, auth_server_receive_message, NULL, NULL, as); - bufferevent_enable(as->in_buf, EV_READ); + bufferevent_pair_new(as->event_base, TURN_BUFFEREVENTS_OPTIONS, pair); + as->in_buf = pair[0]; + as->out_buf = pair[1]; + bufferevent_setcb(as->in_buf, auth_server_receive_message, NULL, NULL, as); + bufferevent_enable(as->in_buf, EV_READ); #if !defined(TURN_NO_HIREDIS) - as->rch = get_redis_async_connection(as->event_base, &turn_params.redis_statsdb, 1); + as->rch = get_redis_async_connection(as->event_base, &turn_params.redis_statsdb, 1); #endif - barrier_wait(); + barrier_wait(); - while(run_auth_server_flag) { - if (!turn_params.no_auth_pings) { - auth_ping(as->rch); - } + while (run_auth_server_flag) { + if (!turn_params.no_auth_pings) { + auth_ping(as->rch); + } - run_events(as->event_base,NULL); - } - } + run_events(as->event_base, NULL); + } + } - return arg; + return arg; } -static void setup_auth_server(struct auth_server *as) -{ - pthread_attr_t attr; - if(pthread_attr_init(&attr) || - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) || - pthread_create(&(as->thr), &attr, run_auth_server_thread, as)) { - perror("Cannot create auth thread\n"); - exit(-1); - } +static void setup_auth_server(struct auth_server *as) { + pthread_attr_t attr; + if (pthread_attr_init(&attr) || pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) || + pthread_create(&(as->thr), &attr, run_auth_server_thread, as)) { + perror("Cannot create auth thread\n"); + exit(-1); + } } -static void* run_admin_server_thread(void *arg) -{ - ignore_sigpipe(); +static void *run_admin_server_thread(void *arg) { + ignore_sigpipe(); - setup_admin_thread(); + setup_admin_thread(); - barrier_wait(); + barrier_wait(); - while(adminserver.event_base) { - run_events(adminserver.event_base,NULL); - } + while (adminserver.event_base) { + run_events(adminserver.event_base, NULL); + } - return arg; + return arg; } -static void setup_admin_server(void) -{ - memset(&adminserver, 0, sizeof(struct admin_server)); - adminserver.listen_fd = -1; - adminserver.verbose = turn_params.verbose; +static void setup_admin_server(void) { + memset(&adminserver, 0, sizeof(struct admin_server)); + adminserver.listen_fd = -1; + adminserver.verbose = turn_params.verbose; - if(pthread_create(&(adminserver.thr), NULL, run_admin_server_thread, &adminserver)) { - perror("Cannot create cli thread\n"); - exit(-1); - } + if (pthread_create(&(adminserver.thr), NULL, run_admin_server_thread, &adminserver)) { + perror("Cannot create cli thread\n"); + exit(-1); + } - pthread_detach(adminserver.thr); + pthread_detach(adminserver.thr); } -void setup_server(void) -{ +void setup_server(void) { #if defined(WINDOWS) - evthread_use_windows_threads(); + evthread_use_windows_threads(); #else - evthread_use_pthreads(); + evthread_use_pthreads(); #endif - TURN_MUTEX_INIT(&mutex_bps); - TURN_MUTEX_INIT(&auth_message_counter_mutex); + TURN_MUTEX_INIT(&mutex_bps); + TURN_MUTEX_INIT(&auth_message_counter_mutex); - authserver_number = 1 + (authserver_id)(turn_params.cpus / 2); + authserver_number = 1 + (authserver_id)(turn_params.cpus / 2); - if(authserver_number < MIN_AUTHSERVER_NUMBER) authserver_number = MIN_AUTHSERVER_NUMBER; + if (authserver_number < MIN_AUTHSERVER_NUMBER) + authserver_number = MIN_AUTHSERVER_NUMBER; #if !defined(TURN_NO_THREAD_BARRIERS) - /* relay threads plus auth threads plus main listener thread */ - /* plus admin thread */ - /* udp address listener thread(s) will start later */ - barrier_count = turn_params.general_relay_servers_number+authserver_number+1+1; + /* relay threads plus auth threads plus main listener thread */ + /* plus admin thread */ + /* udp address listener thread(s) will start later */ + barrier_count = turn_params.general_relay_servers_number + authserver_number + 1 + 1; #endif - setup_listener(); - allocate_relay_addrs_ports(); - setup_barriers(); - setup_general_relay_servers(); + setup_listener(); + allocate_relay_addrs_ports(); + setup_barriers(); + setup_general_relay_servers(); - if(turn_params.net_engine_version == NEV_UDP_SOCKET_PER_THREAD) - setup_socket_per_thread_udp_listener_servers(); - else if(turn_params.net_engine_version == NEV_UDP_SOCKET_PER_ENDPOINT) - setup_socket_per_endpoint_udp_listener_servers(); - else if(turn_params.net_engine_version == NEV_UDP_SOCKET_PER_SESSION) - setup_socket_per_session_udp_listener_servers(); + if (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_THREAD) + setup_socket_per_thread_udp_listener_servers(); + else if (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_ENDPOINT) + setup_socket_per_endpoint_udp_listener_servers(); + else if (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_SESSION) + setup_socket_per_session_udp_listener_servers(); - if(turn_params.net_engine_version != NEV_UDP_SOCKET_PER_THREAD) { - setup_tcp_listener_servers(turn_params.listener.ioa_eng, NULL); - } + if (turn_params.net_engine_version != NEV_UDP_SOCKET_PER_THREAD) { + setup_tcp_listener_servers(turn_params.listener.ioa_eng, NULL); + } - { - int tot = 0; - if(udp_relay_servers[0]) { - tot = get_real_udp_relay_servers_number(); - } - if(tot) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Total UDP servers: %d\n",(int)tot); - } - } + { + int tot = 0; + if (udp_relay_servers[0]) { + tot = get_real_udp_relay_servers_number(); + } + if (tot) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Total UDP servers: %d\n", (int)tot); + } + } - { - int tot = get_real_general_relay_servers_number(); - if(tot) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Total General servers: %d\n",(int)tot); - int i; - for(i = 0;idone) && !(s->broken) && !(s->tobeclosed)) { + if (!(s->done) && !(s->broken) && !(s->tobeclosed)) { - switch (s->st){ + switch (s->st) { - case SCTP_SOCKET: - case TLS_SCTP_SOCKET: + case SCTP_SOCKET: + case TLS_SCTP_SOCKET: - case TCP_SOCKET: - case TLS_SOCKET: + case TCP_SOCKET: + case TLS_SOCKET: - if (s->bev) { + if (s->bev) { - struct evbuffer *evb = bufferevent_get_output(s->bev); + struct evbuffer *evb = bufferevent_get_output(s->bev); - if (evb) { - size_t bufsz = evbuffer_get_length(evb); - size_t newsz = bufsz + sz; + if (evb) { + size_t bufsz = evbuffer_get_length(evb); + size_t newsz = bufsz + sz; - switch (s->sat){ - case TCP_CLIENT_DATA_SOCKET: - case TCP_RELAY_DATA_SOCKET: + switch (s->sat) { + case TCP_CLIENT_DATA_SOCKET: + case TCP_RELAY_DATA_SOCKET: - switch (option){ - case 0: - case 1: - if (newsz >= BUFFEREVENT_MAX_TCP_TO_TCP_WRITE) { - return 0; - } - break; - case 3: - case 4: - if (newsz >= BUFFEREVENT_MAX_TCP_TO_TCP_WRITE) { - return 0; - } - break; - default: - return 1; - } - ; - break; - default: - if (option == 2) { - if (newsz >= BUFFEREVENT_MAX_UDP_TO_TCP_WRITE) { - return 0; - } - } - }; - } - } - break; - default: - ; - }; - } + switch (option) { + case 0: + case 1: + if (newsz >= BUFFEREVENT_MAX_TCP_TO_TCP_WRITE) { + return 0; + } + break; + case 3: + case 4: + if (newsz >= BUFFEREVENT_MAX_TCP_TO_TCP_WRITE) { + return 0; + } + break; + default: + return 1; + }; + break; + default: + if (option == 2) { + if (newsz >= BUFFEREVENT_MAX_UDP_TO_TCP_WRITE) { + return 0; + } + } + }; + } + } + break; + default:; + }; + } - return 1; + return 1; } static void log_socket_event(ioa_socket_handle s, const char *msg, int error) { - if(s && (error || (s->e && s->e->verbose))) { - if(!msg) - msg = "General socket event"; - turnsession_id id = 0; - { - ts_ur_super_session *ss = s->session; - if (ss) { - id = ss->id; - } else{ - return; - } - } + if (s && (error || (s->e && s->e->verbose))) { + if (!msg) + msg = "General socket event"; + turnsession_id id = 0; + { + ts_ur_super_session *ss = s->session; + if (ss) { + id = ss->id; + } else { + return; + } + } - TURN_LOG_LEVEL ll = TURN_LOG_LEVEL_INFO; - if(error) - ll = TURN_LOG_LEVEL_ERROR; + TURN_LOG_LEVEL ll = TURN_LOG_LEVEL_INFO; + if (error) + ll = TURN_LOG_LEVEL_ERROR; - UNUSED_ARG(ll); + UNUSED_ARG(ll); - { - char sraddr[129]="\0"; - char sladdr[129]="\0"; - addr_to_string(&(s->remote_addr),(uint8_t*)sraddr); - addr_to_string(&(s->local_addr),(uint8_t*)sladdr); + { + char sraddr[129] = "\0"; + char sladdr[129] = "\0"; + addr_to_string(&(s->remote_addr), (uint8_t *)sraddr); + addr_to_string(&(s->local_addr), (uint8_t *)sladdr); - if(EVUTIL_SOCKET_ERROR()) { - TURN_LOG_FUNC(ll,"session %018llu: %s: %s (local %s, remote %s)\n",(unsigned long long)id, - msg, evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()), - sladdr,sraddr); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"session %018llu: %s (local %s, remote %s)\n", - (unsigned long long)id,msg,sladdr,sraddr); - } - } - } + if (EVUTIL_SOCKET_ERROR()) { + TURN_LOG_FUNC(ll, "session %018llu: %s: %s (local %s, remote %s)\n", (unsigned long long)id, msg, + evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()), sladdr, sraddr); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "session %018llu: %s (local %s, remote %s)\n", (unsigned long long)id, msg, + sladdr, sraddr); + } + } + } } -int set_df_on_ioa_socket(ioa_socket_handle s, int value) -{ - if(!s) - return 0; +int set_df_on_ioa_socket(ioa_socket_handle s, int value) { + if (!s) + return 0; - if(s->parent_s) - return 0; + if (s->parent_s) + return 0; - if (s->do_not_use_df) - value = 0; + if (s->do_not_use_df) + value = 0; - if (s->current_df_relay_flag != value) { - s->current_df_relay_flag = value; - return set_socket_df(s->fd, s->family, value); - } + if (s->current_df_relay_flag != value) { + s->current_df_relay_flag = value; + return set_socket_df(s->fd, s->family, value); + } - return 0; + return 0; } -void set_do_not_use_df(ioa_socket_handle s) -{ - if(s->parent_s) - return; +void set_do_not_use_df(ioa_socket_handle s) { + if (s->parent_s) + return; - s->do_not_use_df = 1; - s->current_df_relay_flag = 1; - set_socket_df(s->fd, s->family, 0); + s->do_not_use_df = 1; + s->current_df_relay_flag = 1; + set_socket_df(s->fd, s->family, 0); } /************** Buffer List ********************/ -static int buffer_list_empty(stun_buffer_list *bufs) -{ - if(bufs && bufs->head && bufs->tsz) - return 0; - return 1; +static int buffer_list_empty(stun_buffer_list *bufs) { + if (bufs && bufs->head && bufs->tsz) + return 0; + return 1; } -static stun_buffer_list_elem *get_elem_from_buffer_list(stun_buffer_list *bufs) -{ - stun_buffer_list_elem *ret = NULL; +static stun_buffer_list_elem *get_elem_from_buffer_list(stun_buffer_list *bufs) { + stun_buffer_list_elem *ret = NULL; - if(bufs && bufs->head && bufs->tsz) { + if (bufs && bufs->head && bufs->tsz) { - ret=bufs->head; - bufs->head=ret->next; - --bufs->tsz; - if(bufs->tsz == 0) { - bufs->tail = NULL; - } + ret = bufs->head; + bufs->head = ret->next; + --bufs->tsz; + if (bufs->tsz == 0) { + bufs->tail = NULL; + } - ret->next=NULL; - ret->buf.len = 0; - ret->buf.offset = 0; - ret->buf.coffset = 0; - } + ret->next = NULL; + ret->buf.len = 0; + ret->buf.offset = 0; + ret->buf.coffset = 0; + } - return ret; + return ret; } -static void pop_elem_from_buffer_list(stun_buffer_list *bufs) -{ - if(bufs && bufs->head && bufs->tsz) { +static void pop_elem_from_buffer_list(stun_buffer_list *bufs) { + if (bufs && bufs->head && bufs->tsz) { - stun_buffer_list_elem *ret = bufs->head; - bufs->head=ret->next; - --bufs->tsz; - if(bufs->tsz == 0) { - bufs->tail = NULL; - } - free(ret); - } + stun_buffer_list_elem *ret = bufs->head; + bufs->head = ret->next; + --bufs->tsz; + if (bufs->tsz == 0) { + bufs->tail = NULL; + } + free(ret); + } } -static stun_buffer_list_elem *new_blist_elem(ioa_engine_handle e) -{ - stun_buffer_list_elem *ret = get_elem_from_buffer_list(&(e->bufs)); +static stun_buffer_list_elem *new_blist_elem(ioa_engine_handle e) { + stun_buffer_list_elem *ret = get_elem_from_buffer_list(&(e->bufs)); - if(!ret) { - ret = (stun_buffer_list_elem *)malloc(sizeof(stun_buffer_list_elem)); - } + if (!ret) { + ret = (stun_buffer_list_elem *)malloc(sizeof(stun_buffer_list_elem)); + } - if(ret) { - ret->buf.len = 0; - ret->buf.offset = 0; - ret->buf.coffset = 0; - ret->next = NULL; - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot allocate memory for STUN buffer!\n", __FUNCTION__); - } + if (ret) { + ret->buf.len = 0; + ret->buf.offset = 0; + ret->buf.coffset = 0; + ret->next = NULL; + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot allocate memory for STUN buffer!\n", __FUNCTION__); + } - return ret; + return ret; } -static inline void add_elem_to_buffer_list(stun_buffer_list *bufs, stun_buffer_list_elem *buf_elem) -{ - // We want a queue, so add to tail - if(bufs->tail) { - bufs->tail->next = buf_elem; - } else { - bufs->head = buf_elem; - } - buf_elem->next = NULL; - bufs->tail = buf_elem; - bufs->tsz += 1; +static inline void add_elem_to_buffer_list(stun_buffer_list *bufs, stun_buffer_list_elem *buf_elem) { + // We want a queue, so add to tail + if (bufs->tail) { + bufs->tail->next = buf_elem; + } else { + bufs->head = buf_elem; + } + buf_elem->next = NULL; + bufs->tail = buf_elem; + bufs->tsz += 1; } -static void add_buffer_to_buffer_list(stun_buffer_list *bufs, char *buf, size_t len) -{ - if(bufs && buf && (bufs->tszbuf.buf,buf,len); - buf_elem->buf.len = len; - buf_elem->buf.offset = 0; - buf_elem->buf.coffset = 0; - add_elem_to_buffer_list(bufs,buf_elem); - } +static void add_buffer_to_buffer_list(stun_buffer_list *bufs, char *buf, size_t len) { + if (bufs && buf && (bufs->tsz < MAX_SOCKET_BUFFER_BACKLOG)) { + stun_buffer_list_elem *buf_elem = (stun_buffer_list_elem *)malloc(sizeof(stun_buffer_list_elem)); + memcpy(buf_elem->buf.buf, buf, len); + buf_elem->buf.len = len; + buf_elem->buf.offset = 0; + buf_elem->buf.coffset = 0; + add_elem_to_buffer_list(bufs, buf_elem); + } } -static void free_blist_elem(ioa_engine_handle e, stun_buffer_list_elem *buf_elem) -{ - if(buf_elem) { - if(e && (e->bufs.tszbufs), buf_elem); - } else { - free(buf_elem); - } - } +static void free_blist_elem(ioa_engine_handle e, stun_buffer_list_elem *buf_elem) { + if (buf_elem) { + if (e && (e->bufs.tsz < MAX_BUFFER_QUEUE_SIZE_PER_ENGINE)) { + add_elem_to_buffer_list(&(e->bufs), buf_elem); + } else { + free(buf_elem); + } + } } /************** ENGINE *************************/ -static void timer_handler(ioa_engine_handle e, void* arg) { +static void timer_handler(ioa_engine_handle e, void *arg) { UNUSED_ARG(arg); @@ -361,337 +348,331 @@ static void timer_handler(ioa_engine_handle e, void* arg) { e->jiffie = _log_time_value; } -ioa_engine_handle create_ioa_engine(super_memory_t *sm, - struct event_base *eb, turnipports *tp, const char* relay_ifname, - size_t relays_number, char **relay_addrs, int default_relays, - int verbose +ioa_engine_handle create_ioa_engine(super_memory_t *sm, struct event_base *eb, turnipports *tp, + const char *relay_ifname, size_t relays_number, char **relay_addrs, + int default_relays, int verbose #if !defined(TURN_NO_HIREDIS) - ,redis_stats_db_t* redis_stats_db + , + redis_stats_db_t *redis_stats_db #endif - ) -{ - static int capabilities_checked = 0; +) { + static int capabilities_checked = 0; - if(!capabilities_checked) { - capabilities_checked = 1; + if (!capabilities_checked) { + capabilities_checked = 1; #if !defined(CMSG_SPACE) - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "On this platform, I am using alternative behavior of TTL/TOS according to RFC 5766.\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, + "On this platform, I am using alternative behavior of TTL/TOS according to RFC 5766.\n"); #endif #if !defined(IP_RECVTTL) || !defined(IP_TTL) - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "IPv4: On this platform, I am using alternative behavior of TTL according to RFC 5766.\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, + "IPv4: On this platform, I am using alternative behavior of TTL according to RFC 5766.\n"); #endif #if !defined(IPV6_RECVHOPLIMIT) || !defined(IPV6_HOPLIMIT) - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "IPv6: On this platform, I am using alternative behavior of TTL (HOPLIMIT) according to RFC 6156.\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, + "IPv6: On this platform, I am using alternative behavior of TTL (HOPLIMIT) according to RFC 6156.\n"); #endif #if !defined(IP_RECVTOS) || !defined(IP_TOS) - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "IPv4: On this platform, I am using alternative behavior of TOS according to RFC 5766.\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, + "IPv4: On this platform, I am using alternative behavior of TOS according to RFC 5766.\n"); #endif #if !defined(IPV6_RECVTCLASS) || !defined(IPV6_TCLASS) - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "IPv6: On this platform, I am using alternative behavior of TRAFFIC CLASS according to RFC 6156.\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, + "IPv6: On this platform, I am using alternative behavior of TRAFFIC CLASS according to RFC 6156.\n"); #endif - } + } - if (!relays_number || !relay_addrs || !tp) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot create TURN engine\n", __FUNCTION__); - return NULL; - } else { - ioa_engine_handle e = (ioa_engine_handle)allocate_super_memory_region(sm, sizeof(ioa_engine)); + if (!relays_number || !relay_addrs || !tp) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot create TURN engine\n", __FUNCTION__); + return NULL; + } else { + ioa_engine_handle e = (ioa_engine_handle)allocate_super_memory_region(sm, sizeof(ioa_engine)); - e->sm = sm; - e->default_relays = default_relays; - e->verbose = verbose; - e->tp = tp; - if (eb) { - e->event_base = eb; - e->deallocate_eb = 0; - } else { - e->event_base = turn_event_base_new(); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"IO method (engine own thread): %s\n",event_base_get_method(e->event_base)); - e->deallocate_eb = 1; - } + e->sm = sm; + e->default_relays = default_relays; + e->verbose = verbose; + e->tp = tp; + if (eb) { + e->event_base = eb; + e->deallocate_eb = 0; + } else { + e->event_base = turn_event_base_new(); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "IO method (engine own thread): %s\n", event_base_get_method(e->event_base)); + e->deallocate_eb = 1; + } #if !defined(TURN_NO_HIREDIS) - e->rch = get_redis_async_connection(e->event_base, redis_stats_db, 0); + e->rch = get_redis_async_connection(e->event_base, redis_stats_db, 0); #endif - { - int t; - for(t=0;tevent_base, &duration); - if(!ptv) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"FATAL: cannot create preferable timeval for %d secs (%d number)\n",predef_timer_intervals[t],t); - exit(-1); - } else { - memcpy(&(e->predef_timers[t]),ptv,sizeof(struct timeval)); - e->predef_timer_intervals[t] = predef_timer_intervals[t]; - } - } - } + { + int t; + for (t = 0; t < PREDEF_TIMERS_NUM; ++t) { + struct timeval duration; + duration.tv_sec = predef_timer_intervals[t]; + duration.tv_usec = 0; + const struct timeval *ptv = event_base_init_common_timeout(e->event_base, &duration); + if (!ptv) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "FATAL: cannot create preferable timeval for %d secs (%d number)\n", + predef_timer_intervals[t], t); + exit(-1); + } else { + memcpy(&(e->predef_timers[t]), ptv, sizeof(struct timeval)); + e->predef_timer_intervals[t] = predef_timer_intervals[t]; + } + } + } - - if (relay_ifname) - STRCPY(e->relay_ifname, relay_ifname); - { - size_t i = 0; - e->relay_addrs = (ioa_addr*)allocate_super_memory_region(sm, relays_number * sizeof(ioa_addr)+8); - for (i = 0; i < relays_number; i++) { - if(make_ioa_addr((uint8_t*) relay_addrs[i], 0, &(e->relay_addrs[i]))<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot add a relay address: %s\n",relay_addrs[i]); - } - } - e->relays_number = relays_number; - } - e->relay_addr_counter = (unsigned short) turn_random(); - timer_handler(e,e); - e->timer_ev = set_ioa_timer(e, 1, 0, timer_handler, e, 1, "timer_handler"); - return e; - } + if (relay_ifname) + STRCPY(e->relay_ifname, relay_ifname); + { + size_t i = 0; + e->relay_addrs = (ioa_addr *)allocate_super_memory_region(sm, relays_number * sizeof(ioa_addr) + 8); + for (i = 0; i < relays_number; i++) { + if (make_ioa_addr((uint8_t *)relay_addrs[i], 0, &(e->relay_addrs[i])) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot add a relay address: %s\n", relay_addrs[i]); + } + } + e->relays_number = relays_number; + } + e->relay_addr_counter = (unsigned short)turn_random(); + timer_handler(e, e); + e->timer_ev = set_ioa_timer(e, 1, 0, timer_handler, e, 1, "timer_handler"); + return e; + } } -void ioa_engine_set_rtcp_map(ioa_engine_handle e, rtcp_map *rtcpmap) -{ - if(e) - e->map_rtcp = rtcpmap; +void ioa_engine_set_rtcp_map(ioa_engine_handle e, rtcp_map *rtcpmap) { + if (e) + e->map_rtcp = rtcpmap; } -static const ioa_addr* ioa_engine_get_relay_addr(ioa_engine_handle e, ioa_socket_handle client_s, - int address_family, int *err_code) -{ - if(e) { +static const ioa_addr *ioa_engine_get_relay_addr(ioa_engine_handle e, ioa_socket_handle client_s, int address_family, + int *err_code) { + if (e) { - int family = AF_INET; - if(address_family == STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6) - family = AF_INET6; + int family = AF_INET; + if (address_family == STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6) + family = AF_INET6; + if (e->default_relays) { - if(e->default_relays) { + // No relay addrs defined - just return the client address if appropriate: - //No relay addrs defined - just return the client address if appropriate: + ioa_addr *client_addr = get_local_addr_from_ioa_socket(client_s); + if (client_addr) { + switch (address_family) { + case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4: + if (client_addr->ss.sa_family == AF_INET) + return client_addr; + break; + case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6: + if (client_addr->ss.sa_family == AF_INET6) + return client_addr; + break; + default: + return client_addr; + }; + } + } - ioa_addr *client_addr = get_local_addr_from_ioa_socket(client_s); - if(client_addr) { - switch(address_family) { - case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4: - if (client_addr->ss.sa_family == AF_INET) - return client_addr; - break; - case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6: - if (client_addr->ss.sa_family == AF_INET6) - return client_addr; - break; - default: - return client_addr; - }; - } - } + if (e->relays_number > 0) { - if (e->relays_number>0) { + size_t i = 0; - size_t i = 0; + // Default recommended behavior: - //Default recommended behavior: + for (i = 0; i < e->relays_number; i++) { - for(i=0; irelays_number; i++) { + if (e->relay_addr_counter >= e->relays_number) + e->relay_addr_counter = 0; + ioa_addr *relay_addr = &(e->relay_addrs[e->relay_addr_counter++]); - if(e->relay_addr_counter >= e->relays_number) - e->relay_addr_counter = 0; - ioa_addr *relay_addr = &(e->relay_addrs[e->relay_addr_counter++]); + if (addr_any_no_port(relay_addr)) + get_a_local_relay(family, relay_addr); - if(addr_any_no_port(relay_addr)) - get_a_local_relay(family, relay_addr); + switch (address_family) { + case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT: + case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4: + if (relay_addr->ss.sa_family == AF_INET) + return relay_addr; + break; + case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6: + if (relay_addr->ss.sa_family == AF_INET6) + return relay_addr; + break; + default:; + }; + } - switch (address_family){ - case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT: - case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4: - if (relay_addr->ss.sa_family == AF_INET) - return relay_addr; - break; - case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6: - if (relay_addr->ss.sa_family == AF_INET6) - return relay_addr; - break; - default: - ; - }; - } + if (address_family == STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT) { - if(address_family == STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT) { + // Fallback to "find whatever is available": - //Fallback to "find whatever is available": + if (e->relay_addr_counter >= e->relays_number) + e->relay_addr_counter = 0; + const ioa_addr *relay_addr = &(e->relay_addrs[e->relay_addr_counter++]); + return relay_addr; + } - if(e->relay_addr_counter >= e->relays_number) - e->relay_addr_counter = 0; - const ioa_addr *relay_addr = &(e->relay_addrs[e->relay_addr_counter++]); - return relay_addr; - } - - *err_code = 440; - } - } - return NULL; + *err_code = 440; + } + } + return NULL; } /******************** Timers ****************************/ -static void timer_event_handler(evutil_socket_t fd, short what, void* arg) -{ - timer_event* te = (timer_event*)arg; +static void timer_event_handler(evutil_socket_t fd, short what, void *arg) { + timer_event *te = (timer_event *)arg; - if(!te) - return; + if (!te) + return; - UNUSED_ARG(fd); + UNUSED_ARG(fd); - if (!(what & EV_TIMEOUT)) - return; + if (!(what & EV_TIMEOUT)) + return; - if(te->e && eve(te->e->verbose)) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: timeout 0x%lx: %s\n", __FUNCTION__,(long)te, te->txt); + if (te->e && eve(te->e->verbose)) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: timeout 0x%lx: %s\n", __FUNCTION__, (long)te, te->txt); - ioa_timer_event_handler cb = te->cb; - ioa_engine_handle e = te->e; - void *ctx = te->ctx; + ioa_timer_event_handler cb = te->cb; + ioa_engine_handle e = te->e; + void *ctx = te->ctx; - cb(e, ctx); + cb(e, ctx); } -ioa_timer_handle set_ioa_timer(ioa_engine_handle e, int secs, int ms, ioa_timer_event_handler cb, void* ctx, int persist, const char *txt) -{ - ioa_timer_handle ret = NULL; +ioa_timer_handle set_ioa_timer(ioa_engine_handle e, int secs, int ms, ioa_timer_event_handler cb, void *ctx, + int persist, const char *txt) { + ioa_timer_handle ret = NULL; - if (e && cb && secs > 0) { + if (e && cb && secs > 0) { - timer_event * te = (timer_event*) malloc(sizeof(timer_event)); - int flags = EV_TIMEOUT; - if (persist) - flags |= EV_PERSIST; - struct event *ev = event_new(e->event_base, -1, flags, timer_event_handler, te); - struct timeval tv; + timer_event *te = (timer_event *)malloc(sizeof(timer_event)); + int flags = EV_TIMEOUT; + if (persist) + flags |= EV_PERSIST; + struct event *ev = event_new(e->event_base, -1, flags, timer_event_handler, te); + struct timeval tv; - tv.tv_sec = secs; + tv.tv_sec = secs; - te->ctx = ctx; - te->e = e; - te->ev = ev; - te->cb = cb; - te->txt = strdup(txt); + te->ctx = ctx; + te->e = e; + te->ev = ev; + te->cb = cb; + te->txt = strdup(txt); - if(!ms) { - tv.tv_usec = 0; - int found = 0; - int t; - for(t=0;tpredef_timer_intervals[t] == secs) { - evtimer_add(ev,&(e->predef_timers[t])); - found = 1; - break; - } - } - if(!found) { - evtimer_add(ev,&tv); - } - } else { - tv.tv_usec = ms * 1000; - evtimer_add(ev,&tv); - } + if (!ms) { + tv.tv_usec = 0; + int found = 0; + int t; + for (t = 0; t < PREDEF_TIMERS_NUM; ++t) { + if (e->predef_timer_intervals[t] == secs) { + evtimer_add(ev, &(e->predef_timers[t])); + found = 1; + break; + } + } + if (!found) { + evtimer_add(ev, &tv); + } + } else { + tv.tv_usec = ms * 1000; + evtimer_add(ev, &tv); + } - ret = te; - } + ret = te; + } - return ret; + return ret; } -void stop_ioa_timer(ioa_timer_handle th) -{ - if (th) { - timer_event *te = (timer_event *)th; - EVENT_DEL(te->ev); - } +void stop_ioa_timer(ioa_timer_handle th) { + if (th) { + timer_event *te = (timer_event *)th; + EVENT_DEL(te->ev); + } } -void delete_ioa_timer(ioa_timer_handle th) -{ - if (th) { - stop_ioa_timer(th); - timer_event *te = (timer_event *)th; - if(te->txt) { - free(te->txt); - te->txt = NULL; - } - free(th); - } +void delete_ioa_timer(ioa_timer_handle th) { + if (th) { + stop_ioa_timer(th); + timer_event *te = (timer_event *)th; + if (te->txt) { + free(te->txt); + te->txt = NULL; + } + free(th); + } } /************** SOCKETS HELPERS ***********************/ -int ioa_socket_check_bandwidth(ioa_socket_handle s, ioa_network_buffer_handle nbh, int read) -{ - if(s && (s->e) && nbh && - ((s->sat == CLIENT_SOCKET) || (s->sat == RELAY_SOCKET) || (s->sat == RELAY_RTCP_SOCKET)) && - (s->session)) { +int ioa_socket_check_bandwidth(ioa_socket_handle s, ioa_network_buffer_handle nbh, int read) { + if (s && (s->e) && nbh && ((s->sat == CLIENT_SOCKET) || (s->sat == RELAY_SOCKET) || (s->sat == RELAY_RTCP_SOCKET)) && + (s->session)) { - size_t sz = ioa_network_buffer_get_size(nbh); + size_t sz = ioa_network_buffer_get_size(nbh); - band_limit_t max_bps = s->session->bps; + band_limit_t max_bps = s->session->bps; - if(max_bps<1) - return 1; + if (max_bps < 1) + return 1; - struct traffic_bytes *traffic = &(s->data_traffic); + struct traffic_bytes *traffic = &(s->data_traffic); - if(s->sat == CLIENT_SOCKET) { - uint8_t *buf = ioa_network_buffer_data(nbh); - if(stun_is_command_message_str(buf,sz)) { - uint16_t method = stun_get_method_str(buf,sz); - if((method != STUN_METHOD_SEND) && (method != STUN_METHOD_DATA)) { - traffic = &(s->control_traffic); - } - } - } + if (s->sat == CLIENT_SOCKET) { + uint8_t *buf = ioa_network_buffer_data(nbh); + if (stun_is_command_message_str(buf, sz)) { + uint16_t method = stun_get_method_str(buf, sz); + if ((method != STUN_METHOD_SEND) && (method != STUN_METHOD_DATA)) { + traffic = &(s->control_traffic); + } + } + } - band_limit_t bsz = (band_limit_t)sz; + band_limit_t bsz = (band_limit_t)sz; - if(s->jiffie != s->e->jiffie) { + if (s->jiffie != s->e->jiffie) { - s->jiffie = s->e->jiffie; - traffic->jiffie_bytes_read = 0; - traffic->jiffie_bytes_write = 0; + s->jiffie = s->e->jiffie; + traffic->jiffie_bytes_read = 0; + traffic->jiffie_bytes_write = 0; - if(bsz > max_bps) { - return 0; - } else { - if(read) - traffic->jiffie_bytes_read = bsz; - else - traffic->jiffie_bytes_write = bsz; - return 1; - } - } else { - band_limit_t nsz; - if(read) - nsz = traffic->jiffie_bytes_read + bsz; - else - nsz = traffic->jiffie_bytes_write + bsz; - if(nsz > max_bps) { - return 0; - } else { - if(read) - traffic->jiffie_bytes_read = nsz; - else - traffic->jiffie_bytes_write = nsz; - return 1; - } - } - } + if (bsz > max_bps) { + return 0; + } else { + if (read) + traffic->jiffie_bytes_read = bsz; + else + traffic->jiffie_bytes_write = bsz; + return 1; + } + } else { + band_limit_t nsz; + if (read) + nsz = traffic->jiffie_bytes_read + bsz; + else + nsz = traffic->jiffie_bytes_write + bsz; + if (nsz > max_bps) { + return 0; + } else { + if (read) + traffic->jiffie_bytes_read = nsz; + else + traffic->jiffie_bytes_write = nsz; + return 1; + } + } + } - return 1; + return 1; } -int get_ioa_socket_from_reservation(ioa_engine_handle e, uint64_t in_reservation_token, ioa_socket_handle *s) -{ +int get_ioa_socket_from_reservation(ioa_engine_handle e, uint64_t in_reservation_token, ioa_socket_handle *s) { if (e && in_reservation_token && s) { *s = rtcp_map_get(e->map_rtcp, in_reservation_token); if (*s) { @@ -703,3280 +684,3181 @@ int get_ioa_socket_from_reservation(ioa_engine_handle e, uint64_t in_reservation /* Socket options helpers ==>> */ -static int set_socket_ttl(ioa_socket_handle s, int ttl) -{ - if(s->default_ttl < 0) //Unsupported - return -1; +static int set_socket_ttl(ioa_socket_handle s, int ttl) { + if (s->default_ttl < 0) // Unsupported + return -1; - if(ttl < 0) - ttl = s->default_ttl; + if (ttl < 0) + ttl = s->default_ttl; - CORRECT_RAW_TTL(ttl); + CORRECT_RAW_TTL(ttl); - if(ttl > s->default_ttl) - ttl=s->default_ttl; + if (ttl > s->default_ttl) + ttl = s->default_ttl; - if(s->current_ttl != ttl) { - int ret = set_raw_socket_ttl(s->fd, s->family, ttl); - s->current_ttl = ttl; - return ret; - } + if (s->current_ttl != ttl) { + int ret = set_raw_socket_ttl(s->fd, s->family, ttl); + s->current_ttl = ttl; + return ret; + } - return 0; + return 0; } -static int set_socket_tos(ioa_socket_handle s, int tos) -{ - if(s->default_tos < 0) //Unsupported - return -1; +static int set_socket_tos(ioa_socket_handle s, int tos) { + if (s->default_tos < 0) // Unsupported + return -1; - if(tos < 0) - tos = s->default_tos; + if (tos < 0) + tos = s->default_tos; - CORRECT_RAW_TOS(tos); + CORRECT_RAW_TOS(tos); - if(s->current_tos != tos) { - int ret = set_raw_socket_tos(s->fd, s->family, tos); - s->current_tos = tos; - return ret; - } + if (s->current_tos != tos) { + int ret = set_raw_socket_tos(s->fd, s->family, tos); + s->current_tos = tos; + return ret; + } - return 0; + return 0; } -int set_raw_socket_ttl_options(evutil_socket_t fd, int family) -{ - if (family == AF_INET6) { +int set_raw_socket_ttl_options(evutil_socket_t fd, int family) { + if (family == AF_INET6) { #if !defined(IPV6_RECVHOPLIMIT) - UNUSED_ARG(fd); + UNUSED_ARG(fd); #else - int recv_ttl_on = 1; - if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &recv_ttl_on, - sizeof(recv_ttl_on)) < 0) { - perror("cannot set recvhoplimit\n"); - } + int recv_ttl_on = 1; + if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &recv_ttl_on, sizeof(recv_ttl_on)) < 0) { + perror("cannot set recvhoplimit\n"); + } #endif - } else { + } else { #if !defined(IP_RECVTTL) - UNUSED_ARG(fd); + UNUSED_ARG(fd); #else - int recv_ttl_on = 1; - if (setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &recv_ttl_on, - sizeof(recv_ttl_on)) < 0) { - perror("cannot set recvttl\n"); - } + int recv_ttl_on = 1; + if (setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &recv_ttl_on, sizeof(recv_ttl_on)) < 0) { + perror("cannot set recvttl\n"); + } #endif - } + } - return 0; + return 0; } -int set_raw_socket_tos_options(evutil_socket_t fd, int family) -{ - if (family == AF_INET6) { +int set_raw_socket_tos_options(evutil_socket_t fd, int family) { + if (family == AF_INET6) { #if !defined(IPV6_RECVTCLASS) - UNUSED_ARG(fd); + UNUSED_ARG(fd); #else - int recv_tos_on = 1; - if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVTCLASS, &recv_tos_on, - sizeof(recv_tos_on)) < 0) { - perror("cannot set recvtclass\n"); - } + int recv_tos_on = 1; + if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVTCLASS, &recv_tos_on, sizeof(recv_tos_on)) < 0) { + perror("cannot set recvtclass\n"); + } #endif - } else { + } else { #if !defined(IP_RECVTOS) - UNUSED_ARG(fd); + UNUSED_ARG(fd); #else - int recv_tos_on = 1; - if (setsockopt(fd, IPPROTO_IP, IP_RECVTOS, &recv_tos_on, - sizeof(recv_tos_on)) < 0) { - perror("cannot set recvtos\n"); - } + int recv_tos_on = 1; + if (setsockopt(fd, IPPROTO_IP, IP_RECVTOS, &recv_tos_on, sizeof(recv_tos_on)) < 0) { + perror("cannot set recvtos\n"); + } #endif - } + } - return 0; + return 0; } -int set_socket_options_fd(evutil_socket_t fd, SOCKET_TYPE st, int family) -{ - if(fd<0) - return 0; +int set_socket_options_fd(evutil_socket_t fd, SOCKET_TYPE st, int family) { + if (fd < 0) + return 0; - set_sock_buf_size(fd,UR_CLIENT_SOCK_BUF_SIZE); + set_sock_buf_size(fd, UR_CLIENT_SOCK_BUF_SIZE); - if(is_tcp_socket(st)) { /* <<== FREEBSD fix */ - struct linger so_linger; - so_linger.l_onoff = 1; - so_linger.l_linger = 0; - if(setsockopt(fd, - SOL_SOCKET, - SO_LINGER, - &so_linger, - sizeof(so_linger))<1) { - //perror("setsolinger") - ; - } - } + if (is_tcp_socket(st)) { /* <<== FREEBSD fix */ + struct linger so_linger; + so_linger.l_onoff = 1; + so_linger.l_linger = 0; + if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger)) < 1) { + // perror("setsolinger") + ; + } + } - socket_set_nonblocking(fd); + socket_set_nonblocking(fd); - if (!is_stream_socket(st)) { - set_raw_socket_ttl_options(fd, family); - set_raw_socket_tos_options(fd, family); + if (!is_stream_socket(st)) { + set_raw_socket_ttl_options(fd, family); + set_raw_socket_tos_options(fd, family); #ifdef IP_RECVERR - if (family != AF_INET6) { - int on = 0; + if (family != AF_INET6) { + int on = 0; #ifdef TURN_IP_RECVERR - on = 1; + on = 1; #endif - if(setsockopt(fd, IPPROTO_IP, IP_RECVERR, (void *)&on, sizeof(on))<0) - perror("IP_RECVERR"); - } + if (setsockopt(fd, IPPROTO_IP, IP_RECVERR, (void *)&on, sizeof(on)) < 0) + perror("IP_RECVERR"); + } #endif #ifdef IPV6_RECVERR - if (family == AF_INET6) { - int on = 0; + if (family == AF_INET6) { + int on = 0; #ifdef TURN_IP_RECVERR - on = 1; + on = 1; #endif - if(setsockopt(fd, IPPROTO_IPV6, IPV6_RECVERR, (void *)&on, sizeof(on))<0) - perror("IPV6_RECVERR"); - } + if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVERR, (void *)&on, sizeof(on)) < 0) + perror("IPV6_RECVERR"); + } #endif - } else { + } else { - int flag = 1; + int flag = 1; - if(is_tcp_socket(st)) { - setsockopt(fd, /* socket affected */ - IPPROTO_TCP, /* set option at TCP level */ - TCP_NODELAY, /* name of option */ - (char*)&flag, /* value */ - sizeof(int)); /* length of option value */ - } else { + if (is_tcp_socket(st)) { + setsockopt(fd, /* socket affected */ + IPPROTO_TCP, /* set option at TCP level */ + TCP_NODELAY, /* name of option */ + (char *)&flag, /* value */ + sizeof(int)); /* length of option value */ + } else { #if defined(SCTP_NODELAY) - setsockopt(fd, /* socket affected */ - IPPROTO_SCTP, /* set option at SCTP level */ - SCTP_NODELAY, /* name of option */ - (char*)&flag, /* value */ - sizeof(int)); /* length of option value */ + setsockopt(fd, /* socket affected */ + IPPROTO_SCTP, /* set option at SCTP level */ + SCTP_NODELAY, /* name of option */ + (char *)&flag, /* value */ + sizeof(int)); /* length of option value */ #endif - } + } - socket_tcp_set_keepalive(fd,st); - } + socket_tcp_set_keepalive(fd, st); + } - return 0; + return 0; } -int set_socket_options(ioa_socket_handle s) -{ - if(!s || (s->parent_s)) - return 0; +int set_socket_options(ioa_socket_handle s) { + if (!s || (s->parent_s)) + return 0; - set_socket_options_fd(s->fd,s->st,s->family); + set_socket_options_fd(s->fd, s->st, s->family); - s->default_ttl = get_raw_socket_ttl(s->fd, s->family); - s->current_ttl = s->default_ttl; + s->default_ttl = get_raw_socket_ttl(s->fd, s->family); + s->current_ttl = s->default_ttl; - s->default_tos = get_raw_socket_tos(s->fd, s->family); - s->current_tos = s->default_tos; + s->default_tos = get_raw_socket_tos(s->fd, s->family); + s->current_tos = s->default_tos; - return 0; + return 0; } /* <<== Socket options helpers */ -ioa_socket_handle create_unbound_relay_ioa_socket(ioa_engine_handle e, int family, SOCKET_TYPE st, SOCKET_APP_TYPE sat) -{ - evutil_socket_t fd = -1; - ioa_socket_handle ret = NULL; +ioa_socket_handle create_unbound_relay_ioa_socket(ioa_engine_handle e, int family, SOCKET_TYPE st, + SOCKET_APP_TYPE sat) { + evutil_socket_t fd = -1; + ioa_socket_handle ret = NULL; - switch (st){ - case UDP_SOCKET: - fd = socket(family, RELAY_DGRAM_SOCKET_TYPE, RELAY_DGRAM_SOCKET_PROTOCOL); - if (fd < 0) { - perror("UDP socket"); - return NULL; - } - set_sock_buf_size(fd, UR_CLIENT_SOCK_BUF_SIZE); - break; - case TCP_SOCKET: - fd = socket(family, RELAY_STREAM_SOCKET_TYPE, RELAY_STREAM_SOCKET_PROTOCOL); - if (fd < 0) { - perror("TCP socket"); - return NULL; - } - set_sock_buf_size(fd, UR_CLIENT_SOCK_BUF_SIZE); - break; - default: - /* we do not support other sockets in the relay position */ - return NULL; - } + switch (st) { + case UDP_SOCKET: + fd = socket(family, RELAY_DGRAM_SOCKET_TYPE, RELAY_DGRAM_SOCKET_PROTOCOL); + if (fd < 0) { + perror("UDP socket"); + return NULL; + } + set_sock_buf_size(fd, UR_CLIENT_SOCK_BUF_SIZE); + break; + case TCP_SOCKET: + fd = socket(family, RELAY_STREAM_SOCKET_TYPE, RELAY_STREAM_SOCKET_PROTOCOL); + if (fd < 0) { + perror("TCP socket"); + return NULL; + } + set_sock_buf_size(fd, UR_CLIENT_SOCK_BUF_SIZE); + break; + default: + /* we do not support other sockets in the relay position */ + return NULL; + } - ret = (ioa_socket*)calloc(sizeof(ioa_socket), 1); + ret = (ioa_socket *)calloc(sizeof(ioa_socket), 1); - ret->magic = SOCKET_MAGIC; + ret->magic = SOCKET_MAGIC; - ret->fd = fd; - ret->family = family; - ret->st = st; - ret->sat = sat; - ret->e = e; + ret->fd = fd; + ret->family = family; + ret->st = st; + ret->sat = sat; + ret->e = e; - set_socket_options(ret); + set_socket_options(ret); - return ret; + return ret; } -static int bind_ioa_socket(ioa_socket_handle s, const ioa_addr* local_addr, int reusable) -{ - if(!s || (s->parent_s)) - return 0; +static int bind_ioa_socket(ioa_socket_handle s, const ioa_addr *local_addr, int reusable) { + if (!s || (s->parent_s)) + return 0; - if (s && s->fd >= 0 && s->e && local_addr) { + if (s && s->fd >= 0 && s->e && local_addr) { - int res = addr_bind(s->fd, local_addr, reusable,1,s->st); - if (res >= 0) { - s->bound = 1; - addr_cpy(&(s->local_addr), local_addr); - if(addr_get_port(local_addr)<1) { - ioa_addr tmpaddr; - addr_get_from_sock(s->fd, &tmpaddr); - if(addr_any(&(s->local_addr))) { - addr_cpy(&(s->local_addr),&tmpaddr); - } else { - addr_set_port(&(s->local_addr),addr_get_port(&tmpaddr)); - } - } - s->local_addr_known = 1; - return 0; - } - } - return -1; + int res = addr_bind(s->fd, local_addr, reusable, 1, s->st); + if (res >= 0) { + s->bound = 1; + addr_cpy(&(s->local_addr), local_addr); + if (addr_get_port(local_addr) < 1) { + ioa_addr tmpaddr; + addr_get_from_sock(s->fd, &tmpaddr); + if (addr_any(&(s->local_addr))) { + addr_cpy(&(s->local_addr), &tmpaddr); + } else { + addr_set_port(&(s->local_addr), addr_get_port(&tmpaddr)); + } + } + s->local_addr_known = 1; + return 0; + } + } + return -1; } -int create_relay_ioa_sockets(ioa_engine_handle e, - ioa_socket_handle client_s, - int address_family, uint8_t transport, - int even_port, ioa_socket_handle *rtp_s, - ioa_socket_handle *rtcp_s, uint64_t *out_reservation_token, - int *err_code, const uint8_t **reason, - accept_cb acb, void *acbarg) -{ +int create_relay_ioa_sockets(ioa_engine_handle e, ioa_socket_handle client_s, int address_family, uint8_t transport, + int even_port, ioa_socket_handle *rtp_s, ioa_socket_handle *rtcp_s, + uint64_t *out_reservation_token, int *err_code, const uint8_t **reason, accept_cb acb, + void *acbarg) { - *rtp_s = NULL; - if (rtcp_s) - *rtcp_s = NULL; + *rtp_s = NULL; + if (rtcp_s) + *rtcp_s = NULL; - turnipports* tp = e->tp; + turnipports *tp = e->tp; - size_t iip = 0; + size_t iip = 0; - for (iip = 0; iip < e->relays_number; ++iip) { + for (iip = 0; iip < e->relays_number; ++iip) { - ioa_addr relay_addr; - const ioa_addr *ra = ioa_engine_get_relay_addr(e, client_s, address_family, err_code); - if(ra) - addr_cpy(&relay_addr, ra); + ioa_addr relay_addr; + const ioa_addr *ra = ioa_engine_get_relay_addr(e, client_s, address_family, err_code); + if (ra) + addr_cpy(&relay_addr, ra); - if(*err_code) { - if(*err_code == 440) - *reason = (const uint8_t *) "Unsupported address family"; - return -1; - } + if (*err_code) { + if (*err_code == 440) + *reason = (const uint8_t *)"Unsupported address family"; + return -1; + } - int rtcp_port = -1; + int rtcp_port = -1; - IOA_CLOSE_SOCKET(*rtp_s); - if(rtcp_s) - IOA_CLOSE_SOCKET(*rtcp_s); + IOA_CLOSE_SOCKET(*rtp_s); + if (rtcp_s) + IOA_CLOSE_SOCKET(*rtcp_s); - ioa_addr rtcp_local_addr; - addr_cpy(&rtcp_local_addr, &relay_addr); + ioa_addr rtcp_local_addr; + addr_cpy(&rtcp_local_addr, &relay_addr); - int i = 0; - int port = 0; - ioa_addr local_addr; - addr_cpy(&local_addr, &relay_addr); - for (i = 0; i < 0xFFFF; i++) { - port = 0; - rtcp_port = -1; - if (even_port < 0) { - port = turnipports_allocate(tp, transport, &relay_addr); - } else { + int i = 0; + int port = 0; + ioa_addr local_addr; + addr_cpy(&local_addr, &relay_addr); + for (i = 0; i < 0xFFFF; i++) { + port = 0; + rtcp_port = -1; + if (even_port < 0) { + port = turnipports_allocate(tp, transport, &relay_addr); + } else { - port = turnipports_allocate_even(tp, &relay_addr, even_port, out_reservation_token); - if (port >= 0 && even_port > 0) { + port = turnipports_allocate_even(tp, &relay_addr, even_port, out_reservation_token); + if (port >= 0 && even_port > 0) { - IOA_CLOSE_SOCKET(*rtcp_s); - *rtcp_s = create_unbound_relay_ioa_socket(e, relay_addr.ss.sa_family, UDP_SOCKET, RELAY_RTCP_SOCKET); - if (*rtcp_s == NULL) { - perror("socket"); - IOA_CLOSE_SOCKET(*rtp_s); - addr_set_port(&local_addr, port); - turnipports_release(tp, transport, &local_addr); - rtcp_port = port + 1; - addr_set_port(&rtcp_local_addr, rtcp_port); - turnipports_release(tp, transport, &rtcp_local_addr); - return -1; - } - sock_bind_to_device((*rtcp_s)->fd, (unsigned char*)e->relay_ifname); + IOA_CLOSE_SOCKET(*rtcp_s); + *rtcp_s = create_unbound_relay_ioa_socket(e, relay_addr.ss.sa_family, UDP_SOCKET, RELAY_RTCP_SOCKET); + if (*rtcp_s == NULL) { + perror("socket"); + IOA_CLOSE_SOCKET(*rtp_s); + addr_set_port(&local_addr, port); + turnipports_release(tp, transport, &local_addr); + rtcp_port = port + 1; + addr_set_port(&rtcp_local_addr, rtcp_port); + turnipports_release(tp, transport, &rtcp_local_addr); + return -1; + } + sock_bind_to_device((*rtcp_s)->fd, (unsigned char *)e->relay_ifname); - rtcp_port = port + 1; - addr_set_port(&rtcp_local_addr, rtcp_port); - if (bind_ioa_socket(*rtcp_s, &rtcp_local_addr, - (transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE)) < 0) { - addr_set_port(&local_addr, port); - turnipports_release(tp, transport, &local_addr); - turnipports_release(tp, transport, &rtcp_local_addr); - rtcp_port = -1; - IOA_CLOSE_SOCKET(*rtcp_s); - continue; - } - } - } - if (port < 0) { - IOA_CLOSE_SOCKET(*rtp_s); - if (rtcp_s) - IOA_CLOSE_SOCKET(*rtcp_s); - rtcp_port = -1; - break; - } else { + rtcp_port = port + 1; + addr_set_port(&rtcp_local_addr, rtcp_port); + if (bind_ioa_socket(*rtcp_s, &rtcp_local_addr, (transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE)) < 0) { + addr_set_port(&local_addr, port); + turnipports_release(tp, transport, &local_addr); + turnipports_release(tp, transport, &rtcp_local_addr); + rtcp_port = -1; + IOA_CLOSE_SOCKET(*rtcp_s); + continue; + } + } + } + if (port < 0) { + IOA_CLOSE_SOCKET(*rtp_s); + if (rtcp_s) + IOA_CLOSE_SOCKET(*rtcp_s); + rtcp_port = -1; + break; + } else { - IOA_CLOSE_SOCKET(*rtp_s); + IOA_CLOSE_SOCKET(*rtp_s); - *rtp_s = create_unbound_relay_ioa_socket(e, relay_addr.ss.sa_family, - (transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE) ? TCP_SOCKET : UDP_SOCKET, - RELAY_SOCKET); - if (*rtp_s == NULL) { - int rtcp_bound = 0; - if (rtcp_s && *rtcp_s) { - rtcp_bound = (*rtcp_s)->bound; - IOA_CLOSE_SOCKET(*rtcp_s); - } - addr_set_port(&local_addr, port); - turnipports_release(tp, transport, &local_addr); - if (rtcp_port >= 0 && !rtcp_bound) { - addr_set_port(&rtcp_local_addr, rtcp_port); - turnipports_release(tp, transport, &rtcp_local_addr); - } - perror("socket"); - return -1; - } + *rtp_s = create_unbound_relay_ioa_socket( + e, relay_addr.ss.sa_family, (transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE) ? TCP_SOCKET : UDP_SOCKET, + RELAY_SOCKET); + if (*rtp_s == NULL) { + int rtcp_bound = 0; + if (rtcp_s && *rtcp_s) { + rtcp_bound = (*rtcp_s)->bound; + IOA_CLOSE_SOCKET(*rtcp_s); + } + addr_set_port(&local_addr, port); + turnipports_release(tp, transport, &local_addr); + if (rtcp_port >= 0 && !rtcp_bound) { + addr_set_port(&rtcp_local_addr, rtcp_port); + turnipports_release(tp, transport, &rtcp_local_addr); + } + perror("socket"); + return -1; + } - sock_bind_to_device((*rtp_s)->fd, (unsigned char*)e->relay_ifname); + sock_bind_to_device((*rtp_s)->fd, (unsigned char *)e->relay_ifname); - addr_set_port(&local_addr, port); - if (bind_ioa_socket(*rtp_s, &local_addr, - (transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE)) >= 0) { - break; - } else { - IOA_CLOSE_SOCKET(*rtp_s); - int rtcp_bound = 0; - if (rtcp_s && *rtcp_s) { - rtcp_bound = (*rtcp_s)->bound; - IOA_CLOSE_SOCKET(*rtcp_s); - } - addr_set_port(&local_addr, port); - turnipports_release(tp, transport, &local_addr); - if (rtcp_port >= 0 && !rtcp_bound) { - addr_set_port(&rtcp_local_addr, rtcp_port); - turnipports_release(tp, transport, &rtcp_local_addr); - } - rtcp_port = -1; - } - } - } + addr_set_port(&local_addr, port); + if (bind_ioa_socket(*rtp_s, &local_addr, (transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE)) >= 0) { + break; + } else { + IOA_CLOSE_SOCKET(*rtp_s); + int rtcp_bound = 0; + if (rtcp_s && *rtcp_s) { + rtcp_bound = (*rtcp_s)->bound; + IOA_CLOSE_SOCKET(*rtcp_s); + } + addr_set_port(&local_addr, port); + turnipports_release(tp, transport, &local_addr); + if (rtcp_port >= 0 && !rtcp_bound) { + addr_set_port(&rtcp_local_addr, rtcp_port); + turnipports_release(tp, transport, &rtcp_local_addr); + } + rtcp_port = -1; + } + } + } - if(i>=0xFFFF) { - IOA_CLOSE_SOCKET(*rtp_s); - if (rtcp_s) - IOA_CLOSE_SOCKET(*rtcp_s); - } + if (i >= 0xFFFF) { + IOA_CLOSE_SOCKET(*rtp_s); + if (rtcp_s) + IOA_CLOSE_SOCKET(*rtcp_s); + } - if (*rtp_s) { - addr_set_port(&local_addr, port); - addr_debug_print(e->verbose, &local_addr, "Local relay addr"); - if (rtcp_s && *rtcp_s) { - addr_set_port(&local_addr, port+1); - addr_debug_print(e->verbose, &local_addr, "Local reserved relay addr"); - } - break; - } - } + if (*rtp_s) { + addr_set_port(&local_addr, port); + addr_debug_print(e->verbose, &local_addr, "Local relay addr"); + if (rtcp_s && *rtcp_s) { + addr_set_port(&local_addr, port + 1); + addr_debug_print(e->verbose, &local_addr, "Local reserved relay addr"); + } + break; + } + } - if (!(*rtp_s)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: no available ports 3\n", __FUNCTION__); - IOA_CLOSE_SOCKET(*rtp_s); - if (rtcp_s) - IOA_CLOSE_SOCKET(*rtcp_s); - return -1; - } + if (!(*rtp_s)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: no available ports 3\n", __FUNCTION__); + IOA_CLOSE_SOCKET(*rtp_s); + if (rtcp_s) + IOA_CLOSE_SOCKET(*rtcp_s); + return -1; + } - set_accept_cb(*rtp_s, acb, acbarg); + set_accept_cb(*rtp_s, acb, acbarg); - if (rtcp_s && *rtcp_s && out_reservation_token && *out_reservation_token) { - if (rtcp_map_put(e->map_rtcp, *out_reservation_token, *rtcp_s) < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: cannot update RTCP map\n", __FUNCTION__); - IOA_CLOSE_SOCKET(*rtp_s); - if (rtcp_s) - IOA_CLOSE_SOCKET(*rtcp_s); - return -1; - } - } + if (rtcp_s && *rtcp_s && out_reservation_token && *out_reservation_token) { + if (rtcp_map_put(e->map_rtcp, *out_reservation_token, *rtcp_s) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: cannot update RTCP map\n", __FUNCTION__); + IOA_CLOSE_SOCKET(*rtp_s); + if (rtcp_s) + IOA_CLOSE_SOCKET(*rtcp_s); + return -1; + } + } - return 0; + return 0; } /* RFC 6062 ==>> */ -static void tcp_listener_input_handler(struct evconnlistener *l, evutil_socket_t fd, - struct sockaddr *sa, int socklen, void *arg) -{ - UNUSED_ARG(l); +static void tcp_listener_input_handler(struct evconnlistener *l, evutil_socket_t fd, struct sockaddr *sa, int socklen, + void *arg) { + UNUSED_ARG(l); - ioa_socket_handle list_s = (ioa_socket_handle) arg; + ioa_socket_handle list_s = (ioa_socket_handle)arg; - ioa_addr client_addr; - memcpy(&client_addr,sa,socklen); + ioa_addr client_addr; + memcpy(&client_addr, sa, socklen); - addr_debug_print(((list_s->e) && list_s->e->verbose), &client_addr,"tcp accepted from"); + addr_debug_print(((list_s->e) && list_s->e->verbose), &client_addr, "tcp accepted from"); - ioa_socket_handle s = - create_ioa_socket_from_fd( - list_s->e, - fd, - NULL, - TCP_SOCKET, - TCP_RELAY_DATA_SOCKET, - &client_addr, - &(list_s->local_addr)); + ioa_socket_handle s = create_ioa_socket_from_fd(list_s->e, fd, NULL, TCP_SOCKET, TCP_RELAY_DATA_SOCKET, &client_addr, + &(list_s->local_addr)); - if (s) { - if(list_s->acb) { - list_s->acb(s,list_s->acbarg); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Do not know what to do with accepted TCP socket\n"); - close_ioa_socket(s); - } - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Cannot create ioa_socket from FD\n"); - socket_closesocket(fd); - } + if (s) { + if (list_s->acb) { + list_s->acb(s, list_s->acbarg); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Do not know what to do with accepted TCP socket\n"); + close_ioa_socket(s); + } + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot create ioa_socket from FD\n"); + socket_closesocket(fd); + } } -static int set_accept_cb(ioa_socket_handle s, accept_cb acb, void *arg) -{ - if(!s || s->parent_s) - return -1; +static int set_accept_cb(ioa_socket_handle s, accept_cb acb, void *arg) { + if (!s || s->parent_s) + return -1; - if(s->st == TCP_SOCKET) { - s->list_ev = evconnlistener_new(s->e->event_base, - tcp_listener_input_handler, s, - LEV_OPT_REUSEABLE, - 1024, s->fd); - if(!(s->list_ev)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: cannot start TCP listener\n", __FUNCTION__); - return -1; - } - s->acb = acb; - s->acbarg = arg; - } - return 0; + if (s->st == TCP_SOCKET) { + s->list_ev = evconnlistener_new(s->e->event_base, tcp_listener_input_handler, s, LEV_OPT_REUSEABLE, 1024, s->fd); + if (!(s->list_ev)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: cannot start TCP listener\n", __FUNCTION__); + return -1; + } + s->acb = acb; + s->acbarg = arg; + } + return 0; } -static void connect_eventcb(struct bufferevent *bev, short events, void *ptr) -{ - UNUSED_ARG(bev); +static void connect_eventcb(struct bufferevent *bev, short events, void *ptr) { + UNUSED_ARG(bev); - ioa_socket_handle ret = (ioa_socket_handle) ptr; - if (ret) { - connect_cb cb = ret->conn_cb; - void *arg = ret->conn_arg; - if (events & BEV_EVENT_CONNECTED) { - ret->conn_cb = NULL; - ret->conn_arg = NULL; - BUFFEREVENT_FREE(ret->conn_bev); - ret->connected = 1; - if(cb) { - cb(1,arg); - } - } else if (events & BEV_EVENT_ERROR) { - /* An error occured while connecting. */ - ret->conn_cb = NULL; - ret->conn_arg = NULL; - BUFFEREVENT_FREE(ret->conn_bev); - if(cb) { - cb(0,arg); - } - } - } + ioa_socket_handle ret = (ioa_socket_handle)ptr; + if (ret) { + connect_cb cb = ret->conn_cb; + void *arg = ret->conn_arg; + if (events & BEV_EVENT_CONNECTED) { + ret->conn_cb = NULL; + ret->conn_arg = NULL; + BUFFEREVENT_FREE(ret->conn_bev); + ret->connected = 1; + if (cb) { + cb(1, arg); + } + } else if (events & BEV_EVENT_ERROR) { + /* An error occured while connecting. */ + ret->conn_cb = NULL; + ret->conn_arg = NULL; + BUFFEREVENT_FREE(ret->conn_bev); + if (cb) { + cb(0, arg); + } + } + } } -ioa_socket_handle ioa_create_connecting_tcp_relay_socket(ioa_socket_handle s, ioa_addr *peer_addr, connect_cb cb, void *arg) -{ - ioa_socket_handle ret = create_unbound_relay_ioa_socket(s->e, s->family, s->st, TCP_RELAY_DATA_SOCKET); +ioa_socket_handle ioa_create_connecting_tcp_relay_socket(ioa_socket_handle s, ioa_addr *peer_addr, connect_cb cb, + void *arg) { + ioa_socket_handle ret = create_unbound_relay_ioa_socket(s->e, s->family, s->st, TCP_RELAY_DATA_SOCKET); - if(!ret) { - return NULL; - } + if (!ret) { + return NULL; + } - ioa_addr new_local_addr; - addr_cpy(&new_local_addr, &(s->local_addr)); + ioa_addr new_local_addr; + addr_cpy(&new_local_addr, &(s->local_addr)); #if !defined(SO_REUSEPORT) - /* - * trick for OSes which do not support SO_REUSEPORT. - * Section 5.2 of RFC 6062 will not work correctly - * for those OSes (for example, Linux pre-3.9 kernel). - */ + /* + * trick for OSes which do not support SO_REUSEPORT. + * Section 5.2 of RFC 6062 will not work correctly + * for those OSes (for example, Linux pre-3.9 kernel). + */ #if !defined(__CYGWIN__) && !defined(__CYGWIN32__) && !defined(__CYGWIN64__) - close_socket_net_data(s); + close_socket_net_data(s); #else - addr_set_port(&new_local_addr,0); + addr_set_port(&new_local_addr, 0); #endif #endif - if(bind_ioa_socket(ret, &new_local_addr,1)<0) { - IOA_CLOSE_SOCKET(ret); - ret = NULL; - goto ccs_end; - } + if (bind_ioa_socket(ret, &new_local_addr, 1) < 0) { + IOA_CLOSE_SOCKET(ret); + ret = NULL; + goto ccs_end; + } - addr_cpy(&(ret->remote_addr), peer_addr); + addr_cpy(&(ret->remote_addr), peer_addr); - set_ioa_socket_session(ret, s->session); + set_ioa_socket_session(ret, s->session); - BUFFEREVENT_FREE(ret->conn_bev); + BUFFEREVENT_FREE(ret->conn_bev); - ret->conn_bev = bufferevent_socket_new(ret->e->event_base, - ret->fd, - TURN_BUFFEREVENTS_OPTIONS); - bufferevent_setcb(ret->conn_bev, NULL, NULL, connect_eventcb, ret); + ret->conn_bev = bufferevent_socket_new(ret->e->event_base, ret->fd, TURN_BUFFEREVENTS_OPTIONS); + bufferevent_setcb(ret->conn_bev, NULL, NULL, connect_eventcb, ret); - ret->conn_arg = arg; - ret->conn_cb = cb; + ret->conn_arg = arg; + ret->conn_cb = cb; - if (bufferevent_socket_connect(ret->conn_bev, (struct sockaddr *) peer_addr, get_ioa_addr_len(peer_addr)) < 0) { - /* Error starting connection */ - set_ioa_socket_session(ret, NULL); - IOA_CLOSE_SOCKET(ret); - ret = NULL; - goto ccs_end; - } + if (bufferevent_socket_connect(ret->conn_bev, (struct sockaddr *)peer_addr, get_ioa_addr_len(peer_addr)) < 0) { + /* Error starting connection */ + set_ioa_socket_session(ret, NULL); + IOA_CLOSE_SOCKET(ret); + ret = NULL; + goto ccs_end; + } - ccs_end: +ccs_end: #if !defined(SO_REUSEPORT) #if !defined(__CYGWIN__) && !defined(__CYGWIN32__) && !defined(__CYGWIN64__) - /* - * trick for OSes which do not support SO_REUSEPORT. - * Section 5.2 of RFC 6062 will not work correctly - * for those OSes (for example, Linux pre-3.9 kernel). - */ - s->fd = socket(s->family, RELAY_STREAM_SOCKET_TYPE, RELAY_STREAM_SOCKET_PROTOCOL); - if (s->fd < 0) { - perror("TCP socket"); - if(ret) { - set_ioa_socket_session(ret, NULL); - IOA_CLOSE_SOCKET(ret); - ret = NULL; - } - } else { - set_socket_options(s); - sock_bind_to_device(s->fd, (unsigned char*)s->e->relay_ifname); - if(bind_ioa_socket(s, &new_local_addr, 1)<0) { - if(ret) { - set_ioa_socket_session(ret, NULL); - IOA_CLOSE_SOCKET(ret); - ret = NULL; - } - } else { - set_accept_cb(s, s->acb, s->acbarg); - } - } + /* + * trick for OSes which do not support SO_REUSEPORT. + * Section 5.2 of RFC 6062 will not work correctly + * for those OSes (for example, Linux pre-3.9 kernel). + */ + s->fd = socket(s->family, RELAY_STREAM_SOCKET_TYPE, RELAY_STREAM_SOCKET_PROTOCOL); + if (s->fd < 0) { + perror("TCP socket"); + if (ret) { + set_ioa_socket_session(ret, NULL); + IOA_CLOSE_SOCKET(ret); + ret = NULL; + } + } else { + set_socket_options(s); + sock_bind_to_device(s->fd, (unsigned char *)s->e->relay_ifname); + if (bind_ioa_socket(s, &new_local_addr, 1) < 0) { + if (ret) { + set_ioa_socket_session(ret, NULL); + IOA_CLOSE_SOCKET(ret); + ret = NULL; + } + } else { + set_accept_cb(s, s->acb, s->acbarg); + } + } #endif #endif - return ret; + return ret; } /* <<== RFC 6062 */ -void add_socket_to_parent(ioa_socket_handle parent_s, ioa_socket_handle s) -{ - if(parent_s && s) { - delete_socket_from_parent(s); - s->parent_s = parent_s; - s->fd = parent_s->fd; - } +void add_socket_to_parent(ioa_socket_handle parent_s, ioa_socket_handle s) { + if (parent_s && s) { + delete_socket_from_parent(s); + s->parent_s = parent_s; + s->fd = parent_s->fd; + } } -void delete_socket_from_parent(ioa_socket_handle s) -{ - if(s && s->parent_s) { - s->parent_s = NULL; - s->fd = -1; - } +void delete_socket_from_parent(ioa_socket_handle s) { + if (s && s->parent_s) { + s->parent_s = NULL; + s->fd = -1; + } } -void add_socket_to_map(ioa_socket_handle s, ur_addr_map *amap) -{ - if(amap && s && (s->sockets_container != amap)) { - delete_socket_from_map(s); - ur_addr_map_del(amap, &(s->remote_addr),NULL); - ur_addr_map_put(amap, - &(s->remote_addr), - (ur_addr_map_value_type)s); - s->sockets_container = amap; - } +void add_socket_to_map(ioa_socket_handle s, ur_addr_map *amap) { + if (amap && s && (s->sockets_container != amap)) { + delete_socket_from_map(s); + ur_addr_map_del(amap, &(s->remote_addr), NULL); + ur_addr_map_put(amap, &(s->remote_addr), (ur_addr_map_value_type)s); + s->sockets_container = amap; + } } -void delete_socket_from_map(ioa_socket_handle s) -{ - if(s && s->sockets_container) { +void delete_socket_from_map(ioa_socket_handle s) { + if (s && s->sockets_container) { - ur_addr_map_del(s->sockets_container, - &(s->remote_addr), - NULL); - s->sockets_container = NULL; - } + ur_addr_map_del(s->sockets_container, &(s->remote_addr), NULL); + s->sockets_container = NULL; + } } -ioa_socket_handle create_ioa_socket_from_fd(ioa_engine_handle e, - ioa_socket_raw fd, ioa_socket_handle parent_s, - SOCKET_TYPE st, SOCKET_APP_TYPE sat, - const ioa_addr *remote_addr, const ioa_addr *local_addr) -{ - ioa_socket_handle ret = NULL; +ioa_socket_handle create_ioa_socket_from_fd(ioa_engine_handle e, ioa_socket_raw fd, ioa_socket_handle parent_s, + SOCKET_TYPE st, SOCKET_APP_TYPE sat, const ioa_addr *remote_addr, + const ioa_addr *local_addr) { + ioa_socket_handle ret = NULL; - if ((fd < 0) && !parent_s) { - return NULL; - } + if ((fd < 0) && !parent_s) { + return NULL; + } - ret = (ioa_socket*)calloc(sizeof(ioa_socket), 1); + ret = (ioa_socket *)calloc(sizeof(ioa_socket), 1); - ret->magic = SOCKET_MAGIC; + ret->magic = SOCKET_MAGIC; - ret->fd = fd; - ret->st = st; - ret->sat = sat; - ret->e = e; + ret->fd = fd; + ret->st = st; + ret->sat = sat; + ret->e = e; - if (local_addr) { - ret->family = local_addr->ss.sa_family; - ret->bound = 1; - addr_cpy(&(ret->local_addr), local_addr); - } + if (local_addr) { + ret->family = local_addr->ss.sa_family; + ret->bound = 1; + addr_cpy(&(ret->local_addr), local_addr); + } - if (remote_addr) { - ret->connected = 1; - if(!(ret->family)) - ret->family = remote_addr->ss.sa_family; - addr_cpy(&(ret->remote_addr), remote_addr); - } + if (remote_addr) { + ret->connected = 1; + if (!(ret->family)) + ret->family = remote_addr->ss.sa_family; + addr_cpy(&(ret->remote_addr), remote_addr); + } - if(parent_s) { - add_socket_to_parent(parent_s, ret); - } else { - set_socket_options(ret); - } + if (parent_s) { + add_socket_to_parent(parent_s, ret); + } else { + set_socket_options(ret); + } - return ret; + return ret; } static void ssl_info_callback(SSL *ssl, int where, int ret) { - UNUSED_ARG(ret); - UNUSED_ARG(ssl); - UNUSED_ARG(where); + UNUSED_ARG(ret); + UNUSED_ARG(ssl); + UNUSED_ARG(where); #if OPENSSL_VERSION_NUMBER < 0x10100000L #if defined(SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) - if (0 != (where & SSL_CB_HANDSHAKE_START)) { - ioa_socket_handle s = (ioa_socket_handle)SSL_get_app_data(ssl); - if(s) { - ++(s->ssl_renegs); - } - } else if (0 != (where & SSL_CB_HANDSHAKE_DONE)) { - if(ssl->s3) { - ioa_socket_handle s = (ioa_socket_handle)SSL_get_app_data(ssl); - if(s) { - if(s->ssl_renegs>SSL_MAX_RENEG_NUMBER) { - ssl->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS; - } - } - } + if (0 != (where & SSL_CB_HANDSHAKE_START)) { + ioa_socket_handle s = (ioa_socket_handle)SSL_get_app_data(ssl); + if (s) { + ++(s->ssl_renegs); } + } else if (0 != (where & SSL_CB_HANDSHAKE_DONE)) { + if (ssl->s3) { + ioa_socket_handle s = (ioa_socket_handle)SSL_get_app_data(ssl); + if (s) { + if (s->ssl_renegs > SSL_MAX_RENEG_NUMBER) { + ssl->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS; + } + } + } + } #endif #endif } -typedef void (*ssl_info_callback_t)(const SSL *ssl,int type,int val); +typedef void (*ssl_info_callback_t)(const SSL *ssl, int type, int val); -static void set_socket_ssl(ioa_socket_handle s, SSL *ssl) -{ - if(s && (s->ssl != ssl)) { - if(s->ssl) { - SSL_set_app_data(s->ssl,NULL); - SSL_set_info_callback(s->ssl, (ssl_info_callback_t)NULL); - } - s->ssl = ssl; - if(ssl) { - SSL_set_app_data(ssl,s); - SSL_set_info_callback(ssl, (ssl_info_callback_t)ssl_info_callback); - SSL_set_options(ssl, +static void set_socket_ssl(ioa_socket_handle s, SSL *ssl) { + if (s && (s->ssl != ssl)) { + if (s->ssl) { + SSL_set_app_data(s->ssl, NULL); + SSL_set_info_callback(s->ssl, (ssl_info_callback_t)NULL); + } + s->ssl = ssl; + if (ssl) { + SSL_set_app_data(ssl, s); + SSL_set_info_callback(ssl, (ssl_info_callback_t)ssl_info_callback); + SSL_set_options(ssl, #if OPENSSL_VERSION_NUMBER < 0x10100000L #if defined(SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) - SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS + SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS #endif #else #if defined(SSL_OP_NO_RENEGOTIATION) - SSL_OP_NO_RENEGOTIATION + SSL_OP_NO_RENEGOTIATION #endif #endif - ); - } - } + ); + } + } } /* Only must be called for DTLS_SOCKET */ -ioa_socket_handle create_ioa_socket_from_ssl(ioa_engine_handle e, ioa_socket_handle parent_s, SSL* ssl, SOCKET_TYPE st, SOCKET_APP_TYPE sat, const ioa_addr *remote_addr, const ioa_addr *local_addr) -{ - if(!parent_s) - return NULL; +ioa_socket_handle create_ioa_socket_from_ssl(ioa_engine_handle e, ioa_socket_handle parent_s, SSL *ssl, SOCKET_TYPE st, + SOCKET_APP_TYPE sat, const ioa_addr *remote_addr, + const ioa_addr *local_addr) { + if (!parent_s) + return NULL; - ioa_socket_handle ret = create_ioa_socket_from_fd(e, parent_s->fd, parent_s, st, sat, remote_addr, local_addr); + ioa_socket_handle ret = create_ioa_socket_from_fd(e, parent_s->fd, parent_s, st, sat, remote_addr, local_addr); - if(ret) { - set_socket_ssl(ret,ssl); - } + if (ret) { + set_socket_ssl(ret, ssl); + } - return ret; + return ret; } -static void close_socket_net_data(ioa_socket_handle s) -{ - if(s) { +static void close_socket_net_data(ioa_socket_handle s) { + if (s) { - EVENT_DEL(s->read_event); - if(s->list_ev) { - evconnlistener_free(s->list_ev); - s->list_ev = NULL; - } - BUFFEREVENT_FREE(s->conn_bev); - BUFFEREVENT_FREE(s->bev); + EVENT_DEL(s->read_event); + if (s->list_ev) { + evconnlistener_free(s->list_ev); + s->list_ev = NULL; + } + BUFFEREVENT_FREE(s->conn_bev); + BUFFEREVENT_FREE(s->bev); - if (s->ssl) { - if (!s->broken) { - if(!(SSL_get_shutdown(s->ssl) & SSL_SENT_SHUTDOWN)) { - /* - * SSL_RECEIVED_SHUTDOWN tells SSL_shutdown to act as if we had already - * received a close notify from the other end. SSL_shutdown will then - * send the final close notify in reply. The other end will receive the - * close notify and send theirs. By this time, we will have already - * closed the socket and the other end's real close notify will never be - * received. In effect, both sides will think that they have completed a - * clean shutdown and keep their sessions valid. This strategy will fail - * if the socket is not ready for writing, in which case this hack will - * lead to an unclean shutdown and lost session on the other end. - */ - SSL_set_shutdown(s->ssl, SSL_RECEIVED_SHUTDOWN); - SSL_shutdown(s->ssl); - log_socket_event(s, "SSL shutdown received, socket to be closed",0); - } - } - SSL_free(s->ssl); - } + if (s->ssl) { + if (!s->broken) { + if (!(SSL_get_shutdown(s->ssl) & SSL_SENT_SHUTDOWN)) { + /* + * SSL_RECEIVED_SHUTDOWN tells SSL_shutdown to act as if we had already + * received a close notify from the other end. SSL_shutdown will then + * send the final close notify in reply. The other end will receive the + * close notify and send theirs. By this time, we will have already + * closed the socket and the other end's real close notify will never be + * received. In effect, both sides will think that they have completed a + * clean shutdown and keep their sessions valid. This strategy will fail + * if the socket is not ready for writing, in which case this hack will + * lead to an unclean shutdown and lost session on the other end. + */ + SSL_set_shutdown(s->ssl, SSL_RECEIVED_SHUTDOWN); + SSL_shutdown(s->ssl); + log_socket_event(s, "SSL shutdown received, socket to be closed", 0); + } + } + SSL_free(s->ssl); + } - if (s->fd >= 0) { - socket_closesocket(s->fd); - s->fd = -1; - } - } + if (s->fd >= 0) { + socket_closesocket(s->fd); + s->fd = -1; + } + } } -void detach_socket_net_data(ioa_socket_handle s) -{ - if(s) { - EVENT_DEL(s->read_event); - s->read_cb = NULL; - s->read_ctx = NULL; - if(s->list_ev) { - evconnlistener_free(s->list_ev); - s->list_ev = NULL; - } - s->acb = NULL; - s->acbarg = NULL; - BUFFEREVENT_FREE(s->conn_bev); - s->conn_arg=NULL; - s->conn_cb=NULL; - BUFFEREVENT_FREE(s->bev); - } +void detach_socket_net_data(ioa_socket_handle s) { + if (s) { + EVENT_DEL(s->read_event); + s->read_cb = NULL; + s->read_ctx = NULL; + if (s->list_ev) { + evconnlistener_free(s->list_ev); + s->list_ev = NULL; + } + s->acb = NULL; + s->acbarg = NULL; + BUFFEREVENT_FREE(s->conn_bev); + s->conn_arg = NULL; + s->conn_cb = NULL; + BUFFEREVENT_FREE(s->bev); + } } -void close_ioa_socket(ioa_socket_handle s) -{ - if (s) { +void close_ioa_socket(ioa_socket_handle s) { + if (s) { - if(s->magic != SOCKET_MAGIC) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s wrong magic on socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)s, s->st, s->sat); - return; - } + if (s->magic != SOCKET_MAGIC) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s wrong magic on socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__, (long)s, + s->st, s->sat); + return; + } - if(s->done) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s double free on socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)s, s->st, s->sat); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__,(long)s); - return; - } + if (s->done) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s double free on socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__, (long)s, + s->st, s->sat); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__, (long)s); + return; + } - s->done = 1; + s->done = 1; - while(!buffer_list_empty(&(s->bufs))) - pop_elem_from_buffer_list(&(s->bufs)); + while (!buffer_list_empty(&(s->bufs))) + pop_elem_from_buffer_list(&(s->bufs)); - ioa_network_buffer_delete(s->e, s->defer_nbh); + ioa_network_buffer_delete(s->e, s->defer_nbh); - if(s->bound && s->e && s->e->tp && - ((s->sat == RELAY_SOCKET)||(s->sat == RELAY_RTCP_SOCKET))) { - turnipports_release(s->e->tp, - ((s->st == TCP_SOCKET) ? STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE : STUN_ATTRIBUTE_TRANSPORT_UDP_VALUE), - &(s->local_addr)); - } + if (s->bound && s->e && s->e->tp && ((s->sat == RELAY_SOCKET) || (s->sat == RELAY_RTCP_SOCKET))) { + turnipports_release( + s->e->tp, ((s->st == TCP_SOCKET) ? STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE : STUN_ATTRIBUTE_TRANSPORT_UDP_VALUE), + &(s->local_addr)); + } - if(s->special_session) { - free(s->special_session); - s->special_session = NULL; - } - s->special_session_size = 0; + if (s->special_session) { + free(s->special_session); + s->special_session = NULL; + } + s->special_session_size = 0; - delete_socket_from_map(s); - delete_socket_from_parent(s); + delete_socket_from_map(s); + delete_socket_from_parent(s); - close_socket_net_data(s); + close_socket_net_data(s); - s->session = NULL; - s->sub_session = NULL; - s->magic = 0; + s->session = NULL; + s->sub_session = NULL; + s->magic = 0; - free(s); - } + free(s); + } } -ioa_socket_handle detach_ioa_socket(ioa_socket_handle s) -{ - ioa_socket_handle ret = NULL; +ioa_socket_handle detach_ioa_socket(ioa_socket_handle s) { + ioa_socket_handle ret = NULL; - if (!s) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Detaching NULL socket\n"); - } else { - if((s->magic != SOCKET_MAGIC)||(s->done)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s detach on bad socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)s, s->st, s->sat); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__,(long)s); - return ret; - } - if(s->tobeclosed) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s detach on tobeclosed socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)s, s->st, s->sat); - return ret; - } - if(!(s->e)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s detach on socket without engine: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)s, s->st, s->sat); - return ret; - } + if (!s) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Detaching NULL socket\n"); + } else { + if ((s->magic != SOCKET_MAGIC) || (s->done)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s detach on bad socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__, (long)s, + s->st, s->sat); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__, (long)s); + return ret; + } + if (s->tobeclosed) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s detach on tobeclosed socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__, + (long)s, s->st, s->sat); + return ret; + } + if (!(s->e)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s detach on socket without engine: 0x%lx, st=%d, sat=%d\n", + __FUNCTION__, (long)s, s->st, s->sat); + return ret; + } - s->tobeclosed = 1; + s->tobeclosed = 1; - if(s->parent_s) { - if((s->st != UDP_SOCKET) && (s->st != DTLS_SOCKET)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s detach on non-UDP child socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)s, s->st, s->sat); - return ret; - } - } + if (s->parent_s) { + if ((s->st != UDP_SOCKET) && (s->st != DTLS_SOCKET)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s detach on non-UDP child socket: 0x%lx, st=%d, sat=%d\n", + __FUNCTION__, (long)s, s->st, s->sat); + return ret; + } + } - evutil_socket_t udp_fd = -1; + evutil_socket_t udp_fd = -1; - if(s->parent_s) { - udp_fd = socket(s->local_addr.ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL); - if (udp_fd < 0) { - perror("socket"); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"%s: Cannot allocate new socket\n",__FUNCTION__); - return ret; - } - if(sock_bind_to_device(udp_fd, (unsigned char*)(s->e->relay_ifname))<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot bind udp server socket to device %s\n",(char*)(s->e->relay_ifname)); - } + if (s->parent_s) { + udp_fd = socket(s->local_addr.ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL); + if (udp_fd < 0) { + perror("socket"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot allocate new socket\n", __FUNCTION__); + return ret; + } + if (sock_bind_to_device(udp_fd, (unsigned char *)(s->e->relay_ifname)) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot bind udp server socket to device %s\n", + (char *)(s->e->relay_ifname)); + } - if(addr_bind(udp_fd,&(s->local_addr),1,1,UDP_SOCKET)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot bind new detached udp server socket to local addr\n"); - close(udp_fd); - return ret; - } + if (addr_bind(udp_fd, &(s->local_addr), 1, 1, UDP_SOCKET) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot bind new detached udp server socket to local addr\n"); + close(udp_fd); + return ret; + } - int connect_err=0; - if(addr_connect(udp_fd, &(s->remote_addr), &connect_err)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot connect new detached udp server socket to remote addr\n"); - close(udp_fd); - return ret; - } - set_raw_socket_ttl_options(udp_fd, s->local_addr.ss.sa_family); - set_raw_socket_tos_options(udp_fd, s->local_addr.ss.sa_family); - } + int connect_err = 0; + if (addr_connect(udp_fd, &(s->remote_addr), &connect_err) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot connect new detached udp server socket to remote addr\n"); + close(udp_fd); + return ret; + } + set_raw_socket_ttl_options(udp_fd, s->local_addr.ss.sa_family); + set_raw_socket_tos_options(udp_fd, s->local_addr.ss.sa_family); + } - detach_socket_net_data(s); + detach_socket_net_data(s); - while(!buffer_list_empty(&(s->bufs))) - pop_elem_from_buffer_list(&(s->bufs)); + while (!buffer_list_empty(&(s->bufs))) + pop_elem_from_buffer_list(&(s->bufs)); - ioa_network_buffer_delete(s->e, s->defer_nbh); + ioa_network_buffer_delete(s->e, s->defer_nbh); - ret = (ioa_socket*)calloc(sizeof(ioa_socket), 1); - if(!ret) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"%s: Cannot allocate new socket structure\n",__FUNCTION__); - if(udp_fd>=0) - close(udp_fd); - return ret; - } + ret = (ioa_socket *)calloc(sizeof(ioa_socket), 1); + if (!ret) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot allocate new socket structure\n", __FUNCTION__); + if (udp_fd >= 0) + close(udp_fd); + return ret; + } - memset(ret,0,sizeof(ioa_socket)); + memset(ret, 0, sizeof(ioa_socket)); - ret->magic = SOCKET_MAGIC; + ret->magic = SOCKET_MAGIC; - SSL* ssl = s->ssl; - set_socket_ssl(s,NULL); - set_socket_ssl(ret,ssl); - ret->fd = s->fd; + SSL *ssl = s->ssl; + set_socket_ssl(s, NULL); + set_socket_ssl(ret, ssl); + ret->fd = s->fd; - ret->family = get_ioa_socket_address_family(s); + ret->family = get_ioa_socket_address_family(s); - ret->st = s->st; - ret->sat = s->sat; - ret->bound = s->bound; - ret->local_addr_known = s->local_addr_known; - addr_cpy(&(ret->local_addr),&(s->local_addr)); - ret->connected = s->connected; - addr_cpy(&(ret->remote_addr),&(s->remote_addr)); + ret->st = s->st; + ret->sat = s->sat; + ret->bound = s->bound; + ret->local_addr_known = s->local_addr_known; + addr_cpy(&(ret->local_addr), &(s->local_addr)); + ret->connected = s->connected; + addr_cpy(&(ret->remote_addr), &(s->remote_addr)); - delete_socket_from_map(s); - delete_socket_from_parent(s); + delete_socket_from_map(s); + delete_socket_from_parent(s); - if(udp_fd>=0) { + if (udp_fd >= 0) { - ret->fd = udp_fd; + ret->fd = udp_fd; - set_socket_options(ret); - } + set_socket_options(ret); + } - ret->current_ttl = s->current_ttl; - ret->default_ttl = s->default_ttl; + ret->current_ttl = s->current_ttl; + ret->default_ttl = s->default_ttl; - ret->current_tos = s->current_tos; - ret->default_tos = s->default_tos; + ret->current_tos = s->current_tos; + ret->default_tos = s->default_tos; - s->fd = -1; - } + s->fd = -1; + } - return ret; + return ret; } -ts_ur_super_session *get_ioa_socket_session(ioa_socket_handle s) -{ - if(s) - return s->session; - return NULL; +ts_ur_super_session *get_ioa_socket_session(ioa_socket_handle s) { + if (s) + return s->session; + return NULL; } -void set_ioa_socket_session(ioa_socket_handle s, ts_ur_super_session *ss) -{ - if(s) - s->session = ss; +void set_ioa_socket_session(ioa_socket_handle s, ts_ur_super_session *ss) { + if (s) + s->session = ss; } -void clear_ioa_socket_session_if(ioa_socket_handle s, void *ss) -{ - if(s && ((void*)(s->session)==ss)) { - s->session=NULL; - } +void clear_ioa_socket_session_if(ioa_socket_handle s, void *ss) { + if (s && ((void *)(s->session) == ss)) { + s->session = NULL; + } } -tcp_connection *get_ioa_socket_sub_session(ioa_socket_handle s) -{ - if(s) - return s->sub_session; - return NULL; +tcp_connection *get_ioa_socket_sub_session(ioa_socket_handle s) { + if (s) + return s->sub_session; + return NULL; } -void set_ioa_socket_sub_session(ioa_socket_handle s, tcp_connection *tc) -{ - if(s) - s->sub_session = tc; +void set_ioa_socket_sub_session(ioa_socket_handle s, tcp_connection *tc) { + if (s) + s->sub_session = tc; } int get_ioa_socket_address_family(ioa_socket_handle s) { - int first_time = 1; - beg: - if (!(s && (s->magic == SOCKET_MAGIC) && !(s->done))) { - return AF_INET; - } else if(first_time && s->parent_s && (s != s->parent_s)) { - first_time = 0; - s = s->parent_s; - goto beg; - } else { - return s->family; - } + int first_time = 1; +beg: + if (!(s && (s->magic == SOCKET_MAGIC) && !(s->done))) { + return AF_INET; + } else if (first_time && s->parent_s && (s != s->parent_s)) { + first_time = 0; + s = s->parent_s; + goto beg; + } else { + return s->family; + } } -SOCKET_TYPE get_ioa_socket_type(ioa_socket_handle s) -{ - if(s) - return s->st; +SOCKET_TYPE get_ioa_socket_type(ioa_socket_handle s) { + if (s) + return s->st; - return UNKNOWN_SOCKET; + return UNKNOWN_SOCKET; } -SOCKET_APP_TYPE get_ioa_socket_app_type(ioa_socket_handle s) -{ - if(s) - return s->sat; - return UNKNOWN_APP_SOCKET; +SOCKET_APP_TYPE get_ioa_socket_app_type(ioa_socket_handle s) { + if (s) + return s->sat; + return UNKNOWN_APP_SOCKET; } void set_ioa_socket_app_type(ioa_socket_handle s, SOCKET_APP_TYPE sat) { - if(s) - s->sat = sat; + if (s) + s->sat = sat; } -ioa_addr* get_local_addr_from_ioa_socket(ioa_socket_handle s) -{ - if (s && (s->magic == SOCKET_MAGIC) && !(s->done)) { +ioa_addr *get_local_addr_from_ioa_socket(ioa_socket_handle s) { + if (s && (s->magic == SOCKET_MAGIC) && !(s->done)) { - if(s->parent_s) { - s = s->parent_s; - } + if (s->parent_s) { + s = s->parent_s; + } - if (s->local_addr_known) { - return &(s->local_addr); - } else if (s->bound && (addr_get_port(&(s->local_addr)) > 0)) { - s->local_addr_known = 1; - return &(s->local_addr); - } else { - ioa_addr tmpaddr; - if (addr_get_from_sock(s->fd, &tmpaddr) == 0) { - if(addr_get_port(&tmpaddr)>0) { - s->local_addr_known = 1; - s->bound = 1; - if(addr_any(&(s->local_addr))) { - addr_cpy(&(s->local_addr),&tmpaddr); - } else { - addr_set_port(&(s->local_addr),addr_get_port(&tmpaddr)); - } - return &(s->local_addr); - } - if(addr_any(&(s->local_addr))) { - addr_cpy(&(s->local_addr),&tmpaddr); - } - return &(s->local_addr); - } - } - } + if (s->local_addr_known) { + return &(s->local_addr); + } else if (s->bound && (addr_get_port(&(s->local_addr)) > 0)) { + s->local_addr_known = 1; + return &(s->local_addr); + } else { + ioa_addr tmpaddr; + if (addr_get_from_sock(s->fd, &tmpaddr) == 0) { + if (addr_get_port(&tmpaddr) > 0) { + s->local_addr_known = 1; + s->bound = 1; + if (addr_any(&(s->local_addr))) { + addr_cpy(&(s->local_addr), &tmpaddr); + } else { + addr_set_port(&(s->local_addr), addr_get_port(&tmpaddr)); + } + return &(s->local_addr); + } + if (addr_any(&(s->local_addr))) { + addr_cpy(&(s->local_addr), &tmpaddr); + } + return &(s->local_addr); + } + } + } - return NULL; + return NULL; } -ioa_addr* get_remote_addr_from_ioa_socket(ioa_socket_handle s) -{ - if (s && (s->magic == SOCKET_MAGIC) && !(s->done)) { +ioa_addr *get_remote_addr_from_ioa_socket(ioa_socket_handle s) { + if (s && (s->magic == SOCKET_MAGIC) && !(s->done)) { - if (s->connected) { - return &(s->remote_addr); - } - } + if (s->connected) { + return &(s->remote_addr); + } + } - return NULL; + return NULL; } -int get_local_mtu_ioa_socket(ioa_socket_handle s) -{ - if(s) { - if(s->parent_s) - s = s->parent_s; +int get_local_mtu_ioa_socket(ioa_socket_handle s) { + if (s) { + if (s->parent_s) + s = s->parent_s; - return get_socket_mtu(s->fd, s->family, (s->e && eve(s->e->verbose))); - } - return -1; + return get_socket_mtu(s->fd, s->family, (s->e && eve(s->e->verbose))); + } + return -1; } /* * Return: -1 - error, 0 or >0 - OK * *read_len -1 - no data, >=0 - data available */ -int ssl_read(evutil_socket_t fd, SSL* ssl, ioa_network_buffer_handle nbh, int verbose) -{ - int ret = 0; +int ssl_read(evutil_socket_t fd, SSL *ssl, ioa_network_buffer_handle nbh, int verbose) { + int ret = 0; - if (!ssl || !nbh) - return -1; + if (!ssl || !nbh) + return -1; - char* buffer = (char*)ioa_network_buffer_data(nbh); - int buf_size = (int)ioa_network_buffer_get_capacity_udp(); - int read_len = (int)ioa_network_buffer_get_size(nbh); + char *buffer = (char *)ioa_network_buffer_data(nbh); + int buf_size = (int)ioa_network_buffer_get_capacity_udp(); + int read_len = (int)ioa_network_buffer_get_size(nbh); - if(read_len < 1) - return -1; + if (read_len < 1) + return -1; - char *new_buffer = buffer + buf_size; - int old_buffer_len = read_len; + char *new_buffer = buffer + buf_size; + int old_buffer_len = read_len; - int len = 0; + int len = 0; - if (eve(verbose)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: before read...\n", __FUNCTION__); - } + if (eve(verbose)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: before read...\n", __FUNCTION__); + } - BIO *wbio = SSL_get_wbio(ssl); - if(wbio) { - BIO_set_fd(wbio,fd,BIO_NOCLOSE); - } + BIO *wbio = SSL_get_wbio(ssl); + if (wbio) { + BIO_set_fd(wbio, fd, BIO_NOCLOSE); + } - BIO* rbio = BIO_new_mem_buf(buffer, old_buffer_len); - BIO_set_mem_eof_return(rbio, -1); + BIO *rbio = BIO_new_mem_buf(buffer, old_buffer_len); + BIO_set_mem_eof_return(rbio, -1); #if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined LIBRESSL_VERSION_NUMBER && LIBRESSL_VERSION_NUMBER < 0x3040000fL) - ssl->rbio = rbio; + ssl->rbio = rbio; #else - SSL_set0_rbio(ssl,rbio); + SSL_set0_rbio(ssl, rbio); #endif - int if1 = SSL_is_init_finished(ssl); + int if1 = SSL_is_init_finished(ssl); - do { - len = SSL_read(ssl, new_buffer, buf_size); - } while (len < 0 && (errno == EINTR)); + do { + len = SSL_read(ssl, new_buffer, buf_size); + } while (len < 0 && (errno == EINTR)); - int if2 = SSL_is_init_finished(ssl); + int if2 = SSL_is_init_finished(ssl); - if (eve(verbose)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: after read: %d\n", __FUNCTION__, len); - } + if (eve(verbose)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: after read: %d\n", __FUNCTION__, len); + } - if(SSL_get_shutdown(ssl)) { + if (SSL_get_shutdown(ssl)) { - ret = -1; + ret = -1; - } else if (!if1 && if2) { + } else if (!if1 && if2) { #if (OPENSSL_VERSION_NUMBER >= 0x30000000L) - if(verbose && SSL_get1_peer_certificate(ssl)) { + if (verbose && SSL_get1_peer_certificate(ssl)) { #else - if(verbose && SSL_get_peer_certificate(ssl)) { + if (verbose && SSL_get_peer_certificate(ssl)) { #endif - printf("\n------------------------------------------------------------\n"); - X509_NAME_print_ex_fp(stdout, X509_get_subject_name(SSL_get_peer_certificate(ssl)), 1, - XN_FLAG_MULTILINE); - printf("\n\n Cipher: %s\n", SSL_CIPHER_get_name(SSL_get_current_cipher(ssl))); - printf("\n------------------------------------------------------------\n\n"); - } + printf("\n------------------------------------------------------------\n"); + X509_NAME_print_ex_fp(stdout, X509_get_subject_name(SSL_get_peer_certificate(ssl)), 1, XN_FLAG_MULTILINE); + printf("\n\n Cipher: %s\n", SSL_CIPHER_get_name(SSL_get_current_cipher(ssl))); + printf("\n------------------------------------------------------------\n\n"); + } - ret = 0; + ret = 0; - } else if (len < 0 && ((errno == ENOBUFS) || (errno == EAGAIN))) { - if (eve(verbose)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: ENOBUFS/EAGAIN\n", __FUNCTION__); - } - ret = 0; - } else { + } else if (len < 0 && ((errno == ENOBUFS) || (errno == EAGAIN))) { + if (eve(verbose)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: ENOBUFS/EAGAIN\n", __FUNCTION__); + } + ret = 0; + } else { - if (eve(verbose)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: read %d bytes\n", __FUNCTION__, (int) len); - } + if (eve(verbose)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: read %d bytes\n", __FUNCTION__, (int)len); + } - if (len >= 0) { - ret = len; - } else { - switch (SSL_get_error(ssl, len)){ - case SSL_ERROR_NONE: - //??? - ret = 0; - break; - case SSL_ERROR_WANT_READ: - ret = 0; - break; - case SSL_ERROR_WANT_WRITE: - ret = 0; - break; - case SSL_ERROR_ZERO_RETURN: - ret = 0; - break; - case SSL_ERROR_SYSCALL: - { - int err = errno; - if (handle_socket_error()) { - ret = 0; - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS Socket read error: %d\n", err); - ret = -1; - } - break; - } - case SSL_ERROR_SSL: - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SSL read error: "); - char buf[65536]; - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s (%d)\n", ERR_error_string(ERR_get_error(), buf), SSL_get_error(ssl, len)); - } - if (verbose) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SSL connection closed.\n"); - ret = -1; - break; - default: - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Unexpected error while reading!\n"); - } - ret = -1; - } - } - } + if (len >= 0) { + ret = len; + } else { + switch (SSL_get_error(ssl, len)) { + case SSL_ERROR_NONE: + //??? + ret = 0; + break; + case SSL_ERROR_WANT_READ: + ret = 0; + break; + case SSL_ERROR_WANT_WRITE: + ret = 0; + break; + case SSL_ERROR_ZERO_RETURN: + ret = 0; + break; + case SSL_ERROR_SYSCALL: { + int err = errno; + if (handle_socket_error()) { + ret = 0; + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS Socket read error: %d\n", err); + ret = -1; + } + break; + } + case SSL_ERROR_SSL: + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SSL read error: "); + char buf[65536]; + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s (%d)\n", ERR_error_string(ERR_get_error(), buf), + SSL_get_error(ssl, len)); + } + if (verbose) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SSL connection closed.\n"); + ret = -1; + break; + default: + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Unexpected error while reading!\n"); + } + ret = -1; + } + } + } - if(ret>0) { - ioa_network_buffer_add_offset_size(nbh, (uint16_t)buf_size, 0, (size_t)ret); - } + if (ret > 0) { + ioa_network_buffer_add_offset_size(nbh, (uint16_t)buf_size, 0, (size_t)ret); + } #if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined LIBRESSL_VERSION_NUMBER && LIBRESSL_VERSION_NUMBER < 0x3040000fL) - ssl->rbio = NULL; - BIO_free(rbio); + ssl->rbio = NULL; + BIO_free(rbio); #else - SSL_set0_rbio(ssl,NULL); + SSL_set0_rbio(ssl, NULL); #endif - return ret; + return ret; } -static int socket_readerr(evutil_socket_t fd, ioa_addr *orig_addr) -{ - if ((fd < 0) || !orig_addr) - return -1; +static int socket_readerr(evutil_socket_t fd, ioa_addr *orig_addr) { + if ((fd < 0) || !orig_addr) + return -1; #if defined(CMSG_SPACE) && defined(MSG_ERRQUEUE) && defined(IP_RECVERR) - #ifdef _MSC_VER - //TODO: implement it!!! - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "The socket_readerr is not implement in _MSC_VER"); - #else - uint8_t ecmsg[TURN_CMSG_SZ+1]; - int flags = MSG_ERRQUEUE; - int len = 0; +#ifdef _MSC_VER + // TODO: implement it!!! + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "The socket_readerr is not implement in _MSC_VER"); +#else + uint8_t ecmsg[TURN_CMSG_SZ + 1]; + int flags = MSG_ERRQUEUE; + int len = 0; - struct msghdr msg; - struct iovec iov; - char buffer[65536]; + struct msghdr msg; + struct iovec iov; + char buffer[65536]; - char *cmsg = (char*)ecmsg; + char *cmsg = (char *)ecmsg; - msg.msg_control = cmsg; - msg.msg_controllen = TURN_CMSG_SZ; - /* CMSG_SPACE(sizeof(recv_ttl)+sizeof(recv_tos)) */ + msg.msg_control = cmsg; + msg.msg_controllen = TURN_CMSG_SZ; + /* CMSG_SPACE(sizeof(recv_ttl)+sizeof(recv_tos)) */ - msg.msg_name = orig_addr; - msg.msg_namelen = (socklen_t)get_ioa_addr_len(orig_addr); - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_iov->iov_base = buffer; - msg.msg_iov->iov_len = sizeof(buffer); - msg.msg_flags = 0; + msg.msg_name = orig_addr; + msg.msg_namelen = (socklen_t)get_ioa_addr_len(orig_addr); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_iov->iov_base = buffer; + msg.msg_iov->iov_len = sizeof(buffer); + msg.msg_flags = 0; - int try_cycle = 0; + int try_cycle = 0; - do { + do { - do { - len = recvmsg(fd,&msg,flags); - } while (len < 0 && (errno == EINTR)); + do { + len = recvmsg(fd, &msg, flags); + } while (len < 0 && (errno == EINTR)); - } while((len>0)&&(try_cycle++ 0) && (try_cycle++ < MAX_ERRORS_IN_UDP_BATCH)); - #endif +#endif #endif - return 0; + return 0; } typedef unsigned char recv_ttl_t; typedef unsigned char recv_tos_t; -int udp_recvfrom(evutil_socket_t fd, ioa_addr* orig_addr, const ioa_addr *like_addr, char* buffer, int buf_size, int *ttl, int *tos, char *ecmsg, int flags, uint32_t *errcode) -{ - int len = 0; +int udp_recvfrom(evutil_socket_t fd, ioa_addr *orig_addr, const ioa_addr *like_addr, char *buffer, int buf_size, + int *ttl, int *tos, char *ecmsg, int flags, uint32_t *errcode) { + int len = 0; - if (fd < 0 || !orig_addr || !like_addr || !buffer) - return -1; + if (fd < 0 || !orig_addr || !like_addr || !buffer) + return -1; - if(errcode) - *errcode = 0; + if (errcode) + *errcode = 0; - int slen = get_ioa_addr_len(like_addr); - recv_ttl_t recv_ttl = TTL_DEFAULT; - recv_tos_t recv_tos = TOS_DEFAULT; + int slen = get_ioa_addr_len(like_addr); + recv_ttl_t recv_ttl = TTL_DEFAULT; + recv_tos_t recv_tos = TOS_DEFAULT; #if defined(_MSC_VER) || !defined(CMSG_SPACE) - do { - len = recvfrom(fd, buffer, buf_size, flags, (struct sockaddr*) orig_addr, (socklen_t*) &slen); - } while (len < 0 && (errno == EINTR)); - if(len<0 && errcode) - *errcode = (uint32_t)errno; + do { + len = recvfrom(fd, buffer, buf_size, flags, (struct sockaddr *)orig_addr, (socklen_t *)&slen); + } while (len < 0 && (errno == EINTR)); + if (len < 0 && errcode) + *errcode = (uint32_t)errno; #else - struct msghdr msg; - struct iovec iov; + struct msghdr msg; + struct iovec iov; - char *cmsg = (char*)ecmsg; + char *cmsg = (char *)ecmsg; - msg.msg_control = cmsg; - msg.msg_controllen = TURN_CMSG_SZ; - /* CMSG_SPACE(sizeof(recv_ttl)+sizeof(recv_tos)) */ + msg.msg_control = cmsg; + msg.msg_controllen = TURN_CMSG_SZ; + /* CMSG_SPACE(sizeof(recv_ttl)+sizeof(recv_tos)) */ - msg.msg_name = orig_addr; - msg.msg_namelen = (socklen_t)slen; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_iov->iov_base = buffer; - msg.msg_iov->iov_len = (size_t)buf_size; - msg.msg_flags = 0; + msg.msg_name = orig_addr; + msg.msg_namelen = (socklen_t)slen; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_iov->iov_base = buffer; + msg.msg_iov->iov_len = (size_t)buf_size; + msg.msg_flags = 0; #if defined(MSG_ERRQUEUE) - int try_cycle = 0; - try_again: + int try_cycle = 0; +try_again: #endif - do { - len = recvmsg(fd,&msg,flags); - } while (len < 0 && (errno == EINTR)); + do { + len = recvmsg(fd, &msg, flags); + } while (len < 0 && (errno == EINTR)); #if defined(MSG_ERRQUEUE) - if(flags & MSG_ERRQUEUE) { - if((len>0)&&(try_cycle++ 0) && (try_cycle++ < MAX_ERRORS_IN_UDP_BATCH)) + goto try_again; + } - if((len<0) && (!(flags & MSG_ERRQUEUE))) { - //Linux - int eflags = MSG_ERRQUEUE | MSG_DONTWAIT; - uint32_t errcode1 = 0; - udp_recvfrom(fd, orig_addr, like_addr, buffer, buf_size, ttl, tos, ecmsg, eflags, &errcode1); - //try again... - do { - len = recvmsg(fd,&msg,flags); - } while (len < 0 && (errno == EINTR)); - } + if ((len < 0) && (!(flags & MSG_ERRQUEUE))) { + // Linux + int eflags = MSG_ERRQUEUE | MSG_DONTWAIT; + uint32_t errcode1 = 0; + udp_recvfrom(fd, orig_addr, like_addr, buffer, buf_size, ttl, tos, ecmsg, eflags, &errcode1); + // try again... + do { + len = recvmsg(fd, &msg, flags); + } while (len < 0 && (errno == EINTR)); + } #endif - if (len >= 0) { + if (len >= 0) { - struct cmsghdr *cmsgh; + struct cmsghdr *cmsgh; - // Receive auxiliary data in msg - for (cmsgh = CMSG_FIRSTHDR(&msg); cmsgh != NULL; cmsgh - = CMSG_NXTHDR(&msg,cmsgh)) { - int l = cmsgh->cmsg_level; - int t = cmsgh->cmsg_type; + // Receive auxiliary data in msg + for (cmsgh = CMSG_FIRSTHDR(&msg); cmsgh != NULL; cmsgh = CMSG_NXTHDR(&msg, cmsgh)) { + int l = cmsgh->cmsg_level; + int t = cmsgh->cmsg_type; - switch(l) { - case IPPROTO_IP: - switch(t) { + switch (l) { + case IPPROTO_IP: + switch (t) { #if defined(IP_RECVTTL) && !defined(__sparc_v9__) - case IP_RECVTTL: - case IP_TTL: - recv_ttl = *((recv_ttl_t *) CMSG_DATA(cmsgh)); - break; + case IP_RECVTTL: + case IP_TTL: + recv_ttl = *((recv_ttl_t *)CMSG_DATA(cmsgh)); + break; #endif #if defined(IP_RECVTOS) - case IP_RECVTOS: - case IP_TOS: - recv_tos = *((recv_tos_t *) CMSG_DATA(cmsgh)); - break; + case IP_RECVTOS: + case IP_TOS: + recv_tos = *((recv_tos_t *)CMSG_DATA(cmsgh)); + break; #endif #if defined(IP_RECVERR) - case IP_RECVERR: - { - struct turn_sock_extended_err *e=(struct turn_sock_extended_err*) CMSG_DATA(cmsgh); - if(errcode) - *errcode = e->ee_errno; - } - break; + case IP_RECVERR: { + struct turn_sock_extended_err *e = (struct turn_sock_extended_err *)CMSG_DATA(cmsgh); + if (errcode) + *errcode = e->ee_errno; + } break; #endif - default: - ; - /* no break */ - }; - break; - case IPPROTO_IPV6: - switch(t) { + default:; + /* no break */ + }; + break; + case IPPROTO_IPV6: + switch (t) { #if defined(IPV6_RECVHOPLIMIT) && !defined(__sparc_v9__) - case IPV6_RECVHOPLIMIT: - case IPV6_HOPLIMIT: - recv_ttl = *((recv_ttl_t *) CMSG_DATA(cmsgh)); - break; + case IPV6_RECVHOPLIMIT: + case IPV6_HOPLIMIT: + recv_ttl = *((recv_ttl_t *)CMSG_DATA(cmsgh)); + break; #endif #if defined(IPV6_RECVTCLASS) - case IPV6_RECVTCLASS: - case IPV6_TCLASS: - recv_tos = *((recv_tos_t *) CMSG_DATA(cmsgh)); - break; + case IPV6_RECVTCLASS: + case IPV6_TCLASS: + recv_tos = *((recv_tos_t *)CMSG_DATA(cmsgh)); + break; #endif #if defined(IPV6_RECVERR) - case IPV6_RECVERR: - { - struct turn_sock_extended_err *e=(struct turn_sock_extended_err*) CMSG_DATA(cmsgh); - if(errcode) - *errcode = e->ee_errno; - } - break; + case IPV6_RECVERR: { + struct turn_sock_extended_err *e = (struct turn_sock_extended_err *)CMSG_DATA(cmsgh); + if (errcode) + *errcode = e->ee_errno; + } break; #endif - default: - ; - /* no break */ - }; - break; - default: - ; - /* no break */ - }; - } - } + default:; + /* no break */ + }; + break; + default:; + /* no break */ + }; + } + } #endif - *ttl = recv_ttl; + *ttl = recv_ttl; - CORRECT_RAW_TTL(*ttl); + CORRECT_RAW_TTL(*ttl); - *tos = recv_tos; + *tos = recv_tos; - CORRECT_RAW_TOS(*tos); + CORRECT_RAW_TOS(*tos); - return len; + return len; } #if TLS_SUPPORTED -static TURN_TLS_TYPE check_tentative_tls(ioa_socket_raw fd) -{ - TURN_TLS_TYPE ret = TURN_TLS_NO; +static TURN_TLS_TYPE check_tentative_tls(ioa_socket_raw fd) { + TURN_TLS_TYPE ret = TURN_TLS_NO; - char s[12]; - int len = 0; + char s[12]; + int len = 0; - do { - len = (int)recv(fd, s, sizeof(s), MSG_PEEK); - } while (len < 0 && (errno == EINTR)); + do { + len = (int)recv(fd, s, sizeof(s), MSG_PEEK); + } while (len < 0 && (errno == EINTR)); - if(len>0 && ((size_t)len == sizeof(s))) { - if((s[0]==22)&&(s[1]==3)&&(s[5]==1)&&(s[9]==3)) { - char max_supported = (char)(TURN_TLS_TOTAL-2); - if(s[10] > max_supported) - ret = TURN_TLS_SSL23; /* compatibility mode */ - else - ret = (TURN_TLS_TYPE)(s[10]+1); - } else if((s[2]==1)&&(s[3]==3)) { - ret = TURN_TLS_SSL23; /* compatibility mode */ - } - } + if (len > 0 && ((size_t)len == sizeof(s))) { + if ((s[0] == 22) && (s[1] == 3) && (s[5] == 1) && (s[9] == 3)) { + char max_supported = (char)(TURN_TLS_TOTAL - 2); + if (s[10] > max_supported) + ret = TURN_TLS_SSL23; /* compatibility mode */ + else + ret = (TURN_TLS_TYPE)(s[10] + 1); + } else if ((s[2] == 1) && (s[3] == 3)) { + ret = TURN_TLS_SSL23; /* compatibility mode */ + } + } - return ret; + return ret; } #endif - -static size_t proxy_string_field(char *field, size_t max, uint8_t *buf, size_t index, size_t len) -{ - size_t count = 0; - while((index < len) && (count < max)) { - if((0x20 == buf[index]) || (0x0D == buf[index])) { - field[count] = 0x00; - return ++index; - } - field[count++] = buf[index++]; - } - return 0; +static size_t proxy_string_field(char *field, size_t max, uint8_t *buf, size_t index, size_t len) { + size_t count = 0; + while ((index < len) && (count < max)) { + if ((0x20 == buf[index]) || (0x0D == buf[index])) { + field[count] = 0x00; + return ++index; + } + field[count++] = buf[index++]; + } + return 0; } -static ssize_t socket_parse_proxy_v1(ioa_socket_handle s, uint8_t *buf, size_t len) -{ - if(len < 11) { - return 0 ; - } +static ssize_t socket_parse_proxy_v1(ioa_socket_handle s, uint8_t *buf, size_t len) { + if (len < 11) { + return 0; + } - /* Check for proxy-v1 magic field */ - char magic[] = {0x50, 0x52, 0x4F, 0x58, 0x59, 0x20}; - if(memcmp(magic, buf, sizeof(magic))) { - return -1; - } + /* Check for proxy-v1 magic field */ + char magic[] = {0x50, 0x52, 0x4F, 0x58, 0x59, 0x20}; + if (memcmp(magic, buf, sizeof(magic))) { + return -1; + } - /* Read family */ - char tcp4[] = {0x54, 0x43, 0x50, 0x34, 0x20}; - char tcp6[] = {0x54, 0x43, 0x50, 0x36, 0x20}; - int family; - if(0 == memcmp(tcp4, &buf[6], sizeof(tcp4))) { /* IPv4 */ - family = AF_INET; - } else if(0 == memcmp(tcp6, &buf[6], sizeof(tcp6))) { /* IPv6 */ - family = AF_INET6; - } else { - return -1; - } + /* Read family */ + char tcp4[] = {0x54, 0x43, 0x50, 0x34, 0x20}; + char tcp6[] = {0x54, 0x43, 0x50, 0x36, 0x20}; + int family; + if (0 == memcmp(tcp4, &buf[6], sizeof(tcp4))) { /* IPv4 */ + family = AF_INET; + } else if (0 == memcmp(tcp6, &buf[6], sizeof(tcp6))) { /* IPv6 */ + family = AF_INET6; + } else { + return -1; + } - char saddr[40]; - char daddr[40]; - char sport[6]; - char dport[6]; + char saddr[40]; + char daddr[40]; + char sport[6]; + char dport[6]; - size_t tlen = 11; - /* Read source address */ - tlen = proxy_string_field(saddr, sizeof(saddr), buf, tlen, len); - if(0 == tlen) return -1; + size_t tlen = 11; + /* Read source address */ + tlen = proxy_string_field(saddr, sizeof(saddr), buf, tlen, len); + if (0 == tlen) + return -1; - /* Read dest address */ - tlen = proxy_string_field(daddr, sizeof(daddr), buf, tlen, len); - if(0 == tlen) return -1; + /* Read dest address */ + tlen = proxy_string_field(daddr, sizeof(daddr), buf, tlen, len); + if (0 == tlen) + return -1; - /* Read source port */ - tlen = proxy_string_field(sport, sizeof(sport), buf, tlen, len); - if(0 == tlen) return -1; + /* Read source port */ + tlen = proxy_string_field(sport, sizeof(sport), buf, tlen, len); + if (0 == tlen) + return -1; - /* Read dest port */ - tlen = proxy_string_field(dport, sizeof(dport), buf, tlen, len); - if(0 == tlen) return -1; + /* Read dest port */ + tlen = proxy_string_field(dport, sizeof(dport), buf, tlen, len); + if (0 == tlen) + return -1; - /* Final line feed */ - if ((len <= tlen) || (0x0A != buf[tlen])) return -1; + /* Final line feed */ + if ((len <= tlen) || (0x0A != buf[tlen])) + return -1; - tlen++; + tlen++; - int sport_int = atoi(sport); - int dport_int = atoi(dport); - if((sport_int < 0) || (0xFFFF < sport_int)) return -1; - if((dport_int < 0) || (0xFFFF < dport_int)) return -1; + int sport_int = atoi(sport); + int dport_int = atoi(dport); + if ((sport_int < 0) || (0xFFFF < sport_int)) + return -1; + if ((dport_int < 0) || (0xFFFF < dport_int)) + return -1; - if (AF_INET == family) { - struct sockaddr_in remote, local; - remote.sin_family = local.sin_family = AF_INET; - if(1 != inet_pton(AF_INET, saddr, &remote.sin_addr.s_addr)) return -1; - if(1 != inet_pton(AF_INET, daddr, &local.sin_addr.s_addr)) return -1; - remote.sin_port = htons((uint16_t)sport_int); - local.sin_port = htons((uint16_t)dport_int); + if (AF_INET == family) { + struct sockaddr_in remote, local; + remote.sin_family = local.sin_family = AF_INET; + if (1 != inet_pton(AF_INET, saddr, &remote.sin_addr.s_addr)) + return -1; + if (1 != inet_pton(AF_INET, daddr, &local.sin_addr.s_addr)) + return -1; + remote.sin_port = htons((uint16_t)sport_int); + local.sin_port = htons((uint16_t)dport_int); - addr_cpy4(&(s->local_addr), &local); - addr_cpy4(&(s->remote_addr), &remote); + addr_cpy4(&(s->local_addr), &local); + addr_cpy4(&(s->remote_addr), &remote); - } else { - struct sockaddr_in6 remote, local; - remote.sin6_family = local.sin6_family = AF_INET6; - if(1 != inet_pton(AF_INET6, saddr, &remote.sin6_addr.s6_addr)) return -1; - if(1 != inet_pton(AF_INET6, daddr, &local.sin6_addr.s6_addr)) return -1; - remote.sin6_port = htons((uint16_t)sport_int); - local.sin6_port = htons((uint16_t)dport_int); + } else { + struct sockaddr_in6 remote, local; + remote.sin6_family = local.sin6_family = AF_INET6; + if (1 != inet_pton(AF_INET6, saddr, &remote.sin6_addr.s6_addr)) + return -1; + if (1 != inet_pton(AF_INET6, daddr, &local.sin6_addr.s6_addr)) + return -1; + remote.sin6_port = htons((uint16_t)sport_int); + local.sin6_port = htons((uint16_t)dport_int); - addr_cpy6(&(s->local_addr), &local); - addr_cpy6(&(s->remote_addr), &remote); - } - return tlen; + addr_cpy6(&(s->local_addr), &local); + addr_cpy6(&(s->remote_addr), &remote); + } + return tlen; } -static ssize_t socket_parse_proxy_v2(ioa_socket_handle s, uint8_t *buf, size_t len) -{ - if(len < 16){ - return 0 ; - } +static ssize_t socket_parse_proxy_v2(ioa_socket_handle s, uint8_t *buf, size_t len) { + if (len < 16) { + return 0; + } - /* Check for proxy-v2 magic field */ - char magic[] = {0x0D, 0x0A, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x51, 0x55, 0x49, 0x54, 0x0A}; - if(memcmp(magic, buf, sizeof(magic))){ - return -1; - } + /* Check for proxy-v2 magic field */ + char magic[] = {0x0D, 0x0A, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x51, 0x55, 0x49, 0x54, 0x0A}; + if (memcmp(magic, buf, sizeof(magic))) { + return -1; + } - /* Check version */ - uint8_t version = buf[12] >> 4; - if(version != 2) return -1; + /* Check version */ + uint8_t version = buf[12] >> 4; + if (version != 2) + return -1; - /* Read data */ - uint8_t command = buf[12] & 0xF; - uint8_t family = buf[13] >> 4; - uint8_t proto = buf[13] & 0xF; - size_t plen = ((size_t)buf[14] << 8) | buf[15]; + /* Read data */ + uint8_t command = buf[12] & 0xF; + uint8_t family = buf[13] >> 4; + uint8_t proto = buf[13] & 0xF; + size_t plen = ((size_t)buf[14] << 8) | buf[15]; - size_t tlen = 16 + plen; - if(len < tlen) return 0; + size_t tlen = 16 + plen; + if (len < tlen) + return 0; - /* A local connection is used by the proxy itself and does not carry a valid address */ - if(command == 0) return tlen; + /* A local connection is used by the proxy itself and does not carry a valid address */ + if (command == 0) + return tlen; - /* Accept only proxied TCP connections */ - if(command != 1 || proto != 1) return -1; + /* Accept only proxied TCP connections */ + if (command != 1 || proto != 1) + return -1; - /* Read the address */ - if(family == 1 && plen >= 12){ /* IPv4 */ - struct sockaddr_in remote, local; - remote.sin_family = local.sin_family = AF_INET; - memcpy(&remote.sin_addr.s_addr, &buf[16], 4); - memcpy(&local.sin_addr.s_addr, &buf[20], 4); - memcpy(&remote.sin_port, &buf[24], 2); - memcpy(&local.sin_port, &buf[26], 2); + /* Read the address */ + if (family == 1 && plen >= 12) { /* IPv4 */ + struct sockaddr_in remote, local; + remote.sin_family = local.sin_family = AF_INET; + memcpy(&remote.sin_addr.s_addr, &buf[16], 4); + memcpy(&local.sin_addr.s_addr, &buf[20], 4); + memcpy(&remote.sin_port, &buf[24], 2); + memcpy(&local.sin_port, &buf[26], 2); - addr_cpy4(&(s->local_addr), &local); - addr_cpy4(&(s->remote_addr), &remote); + addr_cpy4(&(s->local_addr), &local); + addr_cpy4(&(s->remote_addr), &remote); - }else if(family == 2 && plen >= 36){ /* IPv6 */ - struct sockaddr_in6 remote, local; - remote.sin6_family = local.sin6_family = AF_INET6; - memcpy(&remote.sin6_addr.s6_addr, &buf[16], 16); - memcpy(&local.sin6_addr.s6_addr, &buf[32], 16); - memcpy(&remote.sin6_port, &buf[48], 2); - memcpy(&local.sin6_port, &buf[50], 2); + } else if (family == 2 && plen >= 36) { /* IPv6 */ + struct sockaddr_in6 remote, local; + remote.sin6_family = local.sin6_family = AF_INET6; + memcpy(&remote.sin6_addr.s6_addr, &buf[16], 16); + memcpy(&local.sin6_addr.s6_addr, &buf[32], 16); + memcpy(&remote.sin6_port, &buf[48], 2); + memcpy(&local.sin6_port, &buf[50], 2); - addr_cpy6(&(s->local_addr), &local); - addr_cpy6(&(s->remote_addr), &remote); + addr_cpy6(&(s->local_addr), &local); + addr_cpy6(&(s->remote_addr), &remote); - }else{ - return -1; - } + } else { + return -1; + } - return tlen; + return tlen; } -static ssize_t socket_parse_proxy(ioa_socket_handle s, uint8_t *buf, size_t len) -{ - ssize_t tlen = socket_parse_proxy_v2(s, buf, len); - if(-1 == tlen) { - tlen = socket_parse_proxy_v1(s, buf, len); - } +static ssize_t socket_parse_proxy(ioa_socket_handle s, uint8_t *buf, size_t len) { + ssize_t tlen = socket_parse_proxy_v2(s, buf, len); + if (-1 == tlen) { + tlen = socket_parse_proxy_v1(s, buf, len); + } - return tlen; + return tlen; } -static int socket_input_worker(ioa_socket_handle s) -{ - int len = 0; - int ret = 0; - size_t app_msg_len = 0; - int ttl = TTL_IGNORE; - int tos = TOS_IGNORE; - ioa_addr remote_addr; +static int socket_input_worker(ioa_socket_handle s) { + int len = 0; + int ret = 0; + size_t app_msg_len = 0; + int ttl = TTL_IGNORE; + int tos = TOS_IGNORE; + ioa_addr remote_addr; - int try_again = 0; - int try_ok = 0; - int try_cycle = 0; - const int MAX_TRIES = 16; + int try_again = 0; + int try_ok = 0; + int try_cycle = 0; + const int MAX_TRIES = 16; - if(!s) - return 0; + if (!s) + return 0; - if((s->magic != SOCKET_MAGIC)||(s->done)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)s, s->st, s->sat); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__,(long)s); - return -1; - } + if ((s->magic != SOCKET_MAGIC) || (s->done)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__, (long)s, s->st, s->sat); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__, (long)s); + return -1; + } - if(!(s->e)) - return 0; + if (!(s->e)) + return 0; - if(s->tobeclosed) - return 0; + if (s->tobeclosed) + return 0; - if(s->connected) - addr_cpy(&remote_addr,&(s->remote_addr)); + if (s->connected) + addr_cpy(&remote_addr, &(s->remote_addr)); - if(tcp_congestion_control && s->sub_session && s->bev) { - if(s == s->sub_session->client_s && (s->sub_session->peer_s)) { - if(!is_socket_writeable(s->sub_session->peer_s, STUN_BUFFER_SIZE,__FUNCTION__,0)) { - if(bufferevent_enabled(s->bev,EV_READ)) { - bufferevent_disable(s->bev,EV_READ); - } - } - } else if(s == s->sub_session->peer_s && (s->sub_session->client_s)) { - if(!is_socket_writeable(s->sub_session->client_s, STUN_BUFFER_SIZE,__FUNCTION__,1)) { - if(bufferevent_enabled(s->bev,EV_READ)) { - bufferevent_disable(s->bev,EV_READ); - } - } - } - } + if (tcp_congestion_control && s->sub_session && s->bev) { + if (s == s->sub_session->client_s && (s->sub_session->peer_s)) { + if (!is_socket_writeable(s->sub_session->peer_s, STUN_BUFFER_SIZE, __FUNCTION__, 0)) { + if (bufferevent_enabled(s->bev, EV_READ)) { + bufferevent_disable(s->bev, EV_READ); + } + } + } else if (s == s->sub_session->peer_s && (s->sub_session->client_s)) { + if (!is_socket_writeable(s->sub_session->client_s, STUN_BUFFER_SIZE, __FUNCTION__, 1)) { + if (bufferevent_enabled(s->bev, EV_READ)) { + bufferevent_disable(s->bev, EV_READ); + } + } + } + } - if((s->st == TLS_SOCKET)||(s->st == TLS_SCTP_SOCKET)) { + if ((s->st == TLS_SOCKET) || (s->st == TLS_SCTP_SOCKET)) { #if TLS_SUPPORTED - SSL *ctx = bufferevent_openssl_get_ssl(s->bev); - if(!ctx || SSL_get_shutdown(ctx)) { - s->tobeclosed = 1; - return 0; - } + SSL *ctx = bufferevent_openssl_get_ssl(s->bev); + if (!ctx || SSL_get_shutdown(ctx)) { + s->tobeclosed = 1; + return 0; + } #endif - } else if(s->st == DTLS_SOCKET) { - if(!(s->ssl) || SSL_get_shutdown(s->ssl)) { - s->tobeclosed = 1; - return 0; - } - } + } else if (s->st == DTLS_SOCKET) { + if (!(s->ssl) || SSL_get_shutdown(s->ssl)) { + s->tobeclosed = 1; + return 0; + } + } - if(!(s->e)) - return 0; + if (!(s->e)) + return 0; - if(s->st == TENTATIVE_TCP_SOCKET) { - EVENT_DEL(s->read_event); + if (s->st == TENTATIVE_TCP_SOCKET) { + EVENT_DEL(s->read_event); #if TLS_SUPPORTED - TURN_TLS_TYPE tls_type = check_tentative_tls(s->fd); - if(tls_type) { - s->st = TLS_SOCKET; - if(s->ssl) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on socket: 0x%lx, st=%d, sat=%d: ssl already exist\n", __FUNCTION__,(long)s, s->st, s->sat); - } - if(s->bev) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on socket: 0x%lx, st=%d, sat=%d: bev already exist\n", __FUNCTION__,(long)s, s->st, s->sat); - } + TURN_TLS_TYPE tls_type = check_tentative_tls(s->fd); + if (tls_type) { + s->st = TLS_SOCKET; + if (s->ssl) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on socket: 0x%lx, st=%d, sat=%d: ssl already exist\n", __FUNCTION__, + (long)s, s->st, s->sat); + } + if (s->bev) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on socket: 0x%lx, st=%d, sat=%d: bev already exist\n", __FUNCTION__, + (long)s, s->st, s->sat); + } - if(s->e->tls_ctx) { - set_socket_ssl(s,SSL_new(s->e->tls_ctx)); - } + if (s->e->tls_ctx) { + set_socket_ssl(s, SSL_new(s->e->tls_ctx)); + } - if(s->ssl) { - s->bev = bufferevent_openssl_socket_new(s->e->event_base, - s->fd, - s->ssl, - BUFFEREVENT_SSL_ACCEPTING, - TURN_BUFFEREVENTS_OPTIONS); - bufferevent_setcb(s->bev, socket_input_handler_bev, socket_output_handler_bev, - eventcb_bev, s); - bufferevent_setwatermark(s->bev, EV_READ|EV_WRITE, 0, BUFFEREVENT_HIGH_WATERMARK); - bufferevent_enable(s->bev, EV_READ|EV_WRITE); /* Start reading. */ - } - } else -#endif //TLS_SUPPORTED - { - s->st = TCP_SOCKET; - if(s->bev) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on socket: 0x%lx, st=%d, sat=%d: bev already exist\n", __FUNCTION__,(long)s, s->st, s->sat); - } - s->bev = bufferevent_socket_new(s->e->event_base, - s->fd, - TURN_BUFFEREVENTS_OPTIONS); - bufferevent_setcb(s->bev, socket_input_handler_bev, socket_output_handler_bev, - eventcb_bev, s); - bufferevent_setwatermark(s->bev, EV_READ|EV_WRITE, 0, BUFFEREVENT_HIGH_WATERMARK); - bufferevent_enable(s->bev, EV_READ|EV_WRITE); /* Start reading. */ - } - } else if(s->st == TENTATIVE_SCTP_SOCKET) { - EVENT_DEL(s->read_event); + if (s->ssl) { + s->bev = bufferevent_openssl_socket_new(s->e->event_base, s->fd, s->ssl, BUFFEREVENT_SSL_ACCEPTING, + TURN_BUFFEREVENTS_OPTIONS); + bufferevent_setcb(s->bev, socket_input_handler_bev, socket_output_handler_bev, eventcb_bev, s); + bufferevent_setwatermark(s->bev, EV_READ | EV_WRITE, 0, BUFFEREVENT_HIGH_WATERMARK); + bufferevent_enable(s->bev, EV_READ | EV_WRITE); /* Start reading. */ + } + } else +#endif // TLS_SUPPORTED + { + s->st = TCP_SOCKET; + if (s->bev) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on socket: 0x%lx, st=%d, sat=%d: bev already exist\n", __FUNCTION__, + (long)s, s->st, s->sat); + } + s->bev = bufferevent_socket_new(s->e->event_base, s->fd, TURN_BUFFEREVENTS_OPTIONS); + bufferevent_setcb(s->bev, socket_input_handler_bev, socket_output_handler_bev, eventcb_bev, s); + bufferevent_setwatermark(s->bev, EV_READ | EV_WRITE, 0, BUFFEREVENT_HIGH_WATERMARK); + bufferevent_enable(s->bev, EV_READ | EV_WRITE); /* Start reading. */ + } + } else if (s->st == TENTATIVE_SCTP_SOCKET) { + EVENT_DEL(s->read_event); #if TLS_SUPPORTED - TURN_TLS_TYPE tls_type = check_tentative_tls(s->fd); - if(tls_type) { - s->st = TLS_SCTP_SOCKET; - if(s->ssl) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on socket: 0x%lx, st=%d, sat=%d: ssl already exist\n", __FUNCTION__,(long)s, s->st, s->sat); - } - if(s->bev) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on socket: 0x%lx, st=%d, sat=%d: bev already exist\n", __FUNCTION__,(long)s, s->st, s->sat); - } - if(s->e->tls_ctx) { - set_socket_ssl(s,SSL_new(s->e->tls_ctx)); - } - if(s->ssl) { - s->bev = bufferevent_openssl_socket_new(s->e->event_base, - s->fd, - s->ssl, - BUFFEREVENT_SSL_ACCEPTING, - TURN_BUFFEREVENTS_OPTIONS); - bufferevent_setcb(s->bev, socket_input_handler_bev, socket_output_handler_bev, - eventcb_bev, s); - bufferevent_setwatermark(s->bev, EV_READ|EV_WRITE, 0, BUFFEREVENT_HIGH_WATERMARK); - bufferevent_enable(s->bev, EV_READ|EV_WRITE); /* Start reading. */ - } - } else -#endif //TLS_SUPPORTED - { - s->st = SCTP_SOCKET; - if(s->bev) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on socket: 0x%lx, st=%d, sat=%d: bev already exist\n", __FUNCTION__,(long)s, s->st, s->sat); - } - s->bev = bufferevent_socket_new(s->e->event_base, - s->fd, - TURN_BUFFEREVENTS_OPTIONS); - bufferevent_setcb(s->bev, socket_input_handler_bev, socket_output_handler_bev, - eventcb_bev, s); - bufferevent_setwatermark(s->bev, EV_READ|EV_WRITE, 0, BUFFEREVENT_HIGH_WATERMARK); - bufferevent_enable(s->bev, EV_READ|EV_WRITE); /* Start reading. */ - } - } + TURN_TLS_TYPE tls_type = check_tentative_tls(s->fd); + if (tls_type) { + s->st = TLS_SCTP_SOCKET; + if (s->ssl) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on socket: 0x%lx, st=%d, sat=%d: ssl already exist\n", __FUNCTION__, + (long)s, s->st, s->sat); + } + if (s->bev) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on socket: 0x%lx, st=%d, sat=%d: bev already exist\n", __FUNCTION__, + (long)s, s->st, s->sat); + } + if (s->e->tls_ctx) { + set_socket_ssl(s, SSL_new(s->e->tls_ctx)); + } + if (s->ssl) { + s->bev = bufferevent_openssl_socket_new(s->e->event_base, s->fd, s->ssl, BUFFEREVENT_SSL_ACCEPTING, + TURN_BUFFEREVENTS_OPTIONS); + bufferevent_setcb(s->bev, socket_input_handler_bev, socket_output_handler_bev, eventcb_bev, s); + bufferevent_setwatermark(s->bev, EV_READ | EV_WRITE, 0, BUFFEREVENT_HIGH_WATERMARK); + bufferevent_enable(s->bev, EV_READ | EV_WRITE); /* Start reading. */ + } + } else +#endif // TLS_SUPPORTED + { + s->st = SCTP_SOCKET; + if (s->bev) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on socket: 0x%lx, st=%d, sat=%d: bev already exist\n", __FUNCTION__, + (long)s, s->st, s->sat); + } + s->bev = bufferevent_socket_new(s->e->event_base, s->fd, TURN_BUFFEREVENTS_OPTIONS); + bufferevent_setcb(s->bev, socket_input_handler_bev, socket_output_handler_bev, eventcb_bev, s); + bufferevent_setwatermark(s->bev, EV_READ | EV_WRITE, 0, BUFFEREVENT_HIGH_WATERMARK); + bufferevent_enable(s->bev, EV_READ | EV_WRITE); /* Start reading. */ + } + } - try_start: +try_start: - if(!(s->e)) - return 0; + if (!(s->e)) + return 0; - try_again=0; - try_ok=0; + try_again = 0; + try_ok = 0; - stun_buffer_list_elem *buf_elem = new_blist_elem(s->e); - len = -1; + stun_buffer_list_elem *buf_elem = new_blist_elem(s->e); + len = -1; - if(s->bev) { /* TCP & TLS & SCTP & SCTP/TLS */ - struct evbuffer *inbuf = bufferevent_get_input(s->bev); - if(inbuf) { - ev_ssize_t blen = evbuffer_copyout(inbuf, buf_elem->buf.buf, STUN_BUFFER_SIZE); + if (s->bev) { /* TCP & TLS & SCTP & SCTP/TLS */ + struct evbuffer *inbuf = bufferevent_get_input(s->bev); + if (inbuf) { + ev_ssize_t blen = evbuffer_copyout(inbuf, buf_elem->buf.buf, STUN_BUFFER_SIZE); - if(blen>0) { - int mlen = 0; + if (blen > 0) { + int mlen = 0; - if(blen>(ev_ssize_t)STUN_BUFFER_SIZE) - blen=(ev_ssize_t)STUN_BUFFER_SIZE; + if (blen > (ev_ssize_t)STUN_BUFFER_SIZE) + blen = (ev_ssize_t)STUN_BUFFER_SIZE; - if(s->st == TCP_SOCKET_PROXY){ - ssize_t tlen = socket_parse_proxy(s, buf_elem->buf.buf, blen); - blen = 0; - if (tlen < 0){ - s->tobeclosed = 1; - s->broken = 1; - ret = -1; - log_socket_event(s, "proxy protocol violated",1); - }else if(tlen > 0){ - bufferevent_read(s->bev, buf_elem->buf.buf, tlen); + if (s->st == TCP_SOCKET_PROXY) { + ssize_t tlen = socket_parse_proxy(s, buf_elem->buf.buf, blen); + blen = 0; + if (tlen < 0) { + s->tobeclosed = 1; + s->broken = 1; + ret = -1; + log_socket_event(s, "proxy protocol violated", 1); + } else if (tlen > 0) { + bufferevent_read(s->bev, buf_elem->buf.buf, tlen); - blen = evbuffer_copyout(inbuf, buf_elem->buf.buf, STUN_BUFFER_SIZE); - s->st = TCP_SOCKET; - } - } + blen = evbuffer_copyout(inbuf, buf_elem->buf.buf, STUN_BUFFER_SIZE); + s->st = TCP_SOCKET; + } + } - if(blen){ - if(is_stream_socket(s->st) && ((s->sat == TCP_CLIENT_DATA_SOCKET)||(s->sat==TCP_RELAY_DATA_SOCKET))) { - mlen = blen; - } else { - mlen = stun_get_message_len_str(buf_elem->buf.buf, blen, 1, &app_msg_len); - } + if (blen) { + if (is_stream_socket(s->st) && ((s->sat == TCP_CLIENT_DATA_SOCKET) || (s->sat == TCP_RELAY_DATA_SOCKET))) { + mlen = blen; + } else { + mlen = stun_get_message_len_str(buf_elem->buf.buf, blen, 1, &app_msg_len); + } - if(mlen>0 && mlen<=(int)blen) { - len = (int)bufferevent_read(s->bev, buf_elem->buf.buf, mlen); - if(len < 0) { - ret = -1; - s->tobeclosed = 1; - s->broken = 1; - log_socket_event(s, "socket read failed, to be closed",1); - } else if((s->st == TLS_SOCKET)||(s->st == TLS_SCTP_SOCKET)) { + if (mlen > 0 && mlen <= (int)blen) { + len = (int)bufferevent_read(s->bev, buf_elem->buf.buf, mlen); + if (len < 0) { + ret = -1; + s->tobeclosed = 1; + s->broken = 1; + log_socket_event(s, "socket read failed, to be closed", 1); + } else if ((s->st == TLS_SOCKET) || (s->st == TLS_SCTP_SOCKET)) { #if TLS_SUPPORTED - SSL *ctx = bufferevent_openssl_get_ssl(s->bev); - if(!ctx || SSL_get_shutdown(ctx)) { - ret = -1; - s->tobeclosed = 1; - } + SSL *ctx = bufferevent_openssl_get_ssl(s->bev); + if (!ctx || SSL_get_shutdown(ctx)) { + ret = -1; + s->tobeclosed = 1; + } #endif - } - if(ret != -1) { - ret = len; - } - } - } - } else if(blen<0) { - s->tobeclosed = 1; - s->broken = 1; - ret = -1; - log_socket_event(s, "socket buffer copy failed, to be closed",1); - } - } else { - s->tobeclosed = 1; - s->broken = 1; - ret = -1; - log_socket_event(s, "socket input failed, socket to be closed",1); - } + } + if (ret != -1) { + ret = len; + } + } + } + } else if (blen < 0) { + s->tobeclosed = 1; + s->broken = 1; + ret = -1; + log_socket_event(s, "socket buffer copy failed, to be closed", 1); + } + } else { + s->tobeclosed = 1; + s->broken = 1; + ret = -1; + log_socket_event(s, "socket input failed, socket to be closed", 1); + } - if(len == 0) - len = -1; - } else if(s->fd>=0){ /* UDP and DTLS */ - ret = udp_recvfrom(s->fd, &remote_addr, &(s->local_addr), (char*)(buf_elem->buf.buf), UDP_STUN_BUFFER_SIZE, &ttl, &tos, s->e->cmsg, 0, NULL); - len = ret; - if(s->ssl && (len>0)) { /* DTLS */ - send_ssl_backlog_buffers(s); - buf_elem->buf.len = (size_t)len; - ret = ssl_read(s->fd, s->ssl, (ioa_network_buffer_handle)buf_elem, (s->e ? s->e->verbose : TURN_VERBOSE_NONE)); - addr_cpy(&remote_addr,&(s->remote_addr)); - if(ret < 0) { - len = -1; - s->tobeclosed = 1; - s->broken = 1; - log_socket_event(s, "SSL read failed, to be closed",0); - } else { - len = (int)ioa_network_buffer_get_size((ioa_network_buffer_handle)buf_elem); - } - if((ret!=-1)&&(len>0)) - try_again = 1; - } else { /* UDP */ - if(ret>=0) - try_again = 1; - } - } else { - s->tobeclosed = 1; - s->broken = 1; - ret = -1; - log_socket_event(s, "socket unknown error, to be closed",1); - } + if (len == 0) + len = -1; + } else if (s->fd >= 0) { /* UDP and DTLS */ + ret = udp_recvfrom(s->fd, &remote_addr, &(s->local_addr), (char *)(buf_elem->buf.buf), UDP_STUN_BUFFER_SIZE, &ttl, + &tos, s->e->cmsg, 0, NULL); + len = ret; + if (s->ssl && (len > 0)) { /* DTLS */ + send_ssl_backlog_buffers(s); + buf_elem->buf.len = (size_t)len; + ret = ssl_read(s->fd, s->ssl, (ioa_network_buffer_handle)buf_elem, (s->e ? s->e->verbose : TURN_VERBOSE_NONE)); + addr_cpy(&remote_addr, &(s->remote_addr)); + if (ret < 0) { + len = -1; + s->tobeclosed = 1; + s->broken = 1; + log_socket_event(s, "SSL read failed, to be closed", 0); + } else { + len = (int)ioa_network_buffer_get_size((ioa_network_buffer_handle)buf_elem); + } + if ((ret != -1) && (len > 0)) + try_again = 1; + } else { /* UDP */ + if (ret >= 0) + try_again = 1; + } + } else { + s->tobeclosed = 1; + s->broken = 1; + ret = -1; + log_socket_event(s, "socket unknown error, to be closed", 1); + } - if ((ret!=-1) && (len >= 0)) { + if ((ret != -1) && (len >= 0)) { - if(app_msg_len) - buf_elem->buf.len = app_msg_len; - else - buf_elem->buf.len = len; + if (app_msg_len) + buf_elem->buf.len = app_msg_len; + else + buf_elem->buf.len = len; - if(ioa_socket_check_bandwidth(s,buf_elem,1)) { + if (ioa_socket_check_bandwidth(s, buf_elem, 1)) { - if(s->read_cb) { - ioa_net_data nd; + if (s->read_cb) { + ioa_net_data nd; - memset(&nd, 0, sizeof(ioa_net_data)); - addr_cpy(&(nd.src_addr),&remote_addr); - nd.nbh = buf_elem; - nd.recv_ttl = ttl; - nd.recv_tos = tos; + memset(&nd, 0, sizeof(ioa_net_data)); + addr_cpy(&(nd.src_addr), &remote_addr); + nd.nbh = buf_elem; + nd.recv_ttl = ttl; + nd.recv_tos = tos; - s->read_cb(s, IOA_EV_READ, &nd, s->read_ctx, 1); + s->read_cb(s, IOA_EV_READ, &nd, s->read_ctx, 1); - if(nd.nbh) - free_blist_elem(s->e,buf_elem); + if (nd.nbh) + free_blist_elem(s->e, buf_elem); - buf_elem = NULL; + buf_elem = NULL; - try_ok = 1; + try_ok = 1; - } else { - ioa_network_buffer_delete(s->e, s->defer_nbh); - s->defer_nbh = buf_elem; - buf_elem = NULL; - } - } - } + } else { + ioa_network_buffer_delete(s->e, s->defer_nbh); + s->defer_nbh = buf_elem; + buf_elem = NULL; + } + } + } - if(buf_elem) { - free_blist_elem(s->e,buf_elem); - buf_elem = NULL; - } + if (buf_elem) { + free_blist_elem(s->e, buf_elem); + buf_elem = NULL; + } - if(try_again && try_ok && !(s->done) && - !(s->tobeclosed) && ((++try_cycle)parent_s)) { - goto try_start; - } + if (try_again && try_ok && !(s->done) && !(s->tobeclosed) && ((++try_cycle) < MAX_TRIES) && !(s->parent_s)) { + goto try_start; + } - return len; + return len; } -static void socket_input_handler(evutil_socket_t fd, short what, void* arg) -{ +static void socket_input_handler(evutil_socket_t fd, short what, void *arg) { - if (!(what & EV_READ)) - return; + if (!(what & EV_READ)) + return; - if(!arg) { - read_spare_buffer(fd); - return; - } + if (!arg) { + read_spare_buffer(fd); + return; + } - ioa_socket_handle s = (ioa_socket_handle)arg; + ioa_socket_handle s = (ioa_socket_handle)arg; - if(!s) { - read_spare_buffer(fd); - return; - } + if (!s) { + read_spare_buffer(fd); + return; + } - if((s->magic != SOCKET_MAGIC)||(s->done)) { - read_spare_buffer(fd); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on bad socket, ev=%d: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(int)what,(long)s, s->st, s->sat); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__,(long)s); - return; - } + if ((s->magic != SOCKET_MAGIC) || (s->done)) { + read_spare_buffer(fd); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on bad socket, ev=%d: 0x%lx, st=%d, sat=%d\n", __FUNCTION__, (int)what, + (long)s, s->st, s->sat); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__, (long)s); + return; + } - if(fd != s->fd) { - read_spare_buffer(fd); - return; - } + if (fd != s->fd) { + read_spare_buffer(fd); + return; + } - if (!ioa_socket_tobeclosed(s)) - socket_input_worker(s); - else - read_spare_buffer(fd); + if (!ioa_socket_tobeclosed(s)) + socket_input_worker(s); + else + read_spare_buffer(fd); - if((s->magic != SOCKET_MAGIC)||(s->done)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s (1) on socket, ev=%d: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(int)what,(long)s, s->st, s->sat); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__,(long)s); - return; - } + if ((s->magic != SOCKET_MAGIC) || (s->done)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s (1) on socket, ev=%d: 0x%lx, st=%d, sat=%d\n", __FUNCTION__, (int)what, + (long)s, s->st, s->sat); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__, (long)s); + return; + } - close_ioa_socket_after_processing_if_necessary(s); + close_ioa_socket_after_processing_if_necessary(s); } -void close_ioa_socket_after_processing_if_necessary(ioa_socket_handle s) -{ - if (s && ioa_socket_tobeclosed(s)) { +void close_ioa_socket_after_processing_if_necessary(ioa_socket_handle s) { + if (s && ioa_socket_tobeclosed(s)) { - if(s->special_session) { - free(s->special_session); - s->special_session = NULL; - } - s->special_session_size = 0; + if (s->special_session) { + free(s->special_session); + s->special_session = NULL; + } + s->special_session_size = 0; - if(!(s->session) && !(s->sub_session)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s https server socket closed: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)s, get_ioa_socket_type(s), get_ioa_socket_app_type(s)); - IOA_CLOSE_SOCKET(s); - return; - } + if (!(s->session) && !(s->sub_session)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s https server socket closed: 0x%lx, st=%d, sat=%d\n", __FUNCTION__, (long)s, + get_ioa_socket_type(s), get_ioa_socket_app_type(s)); + IOA_CLOSE_SOCKET(s); + return; + } - switch (s->sat){ - case TCP_CLIENT_DATA_SOCKET: - case TCP_RELAY_DATA_SOCKET: - { - tcp_connection *tc = s->sub_session; - if (tc) { - s->sub_session = NULL; - delete_tcp_connection(tc); - } - } - break; - default: - { - ts_ur_super_session *ss = s->session; - if (ss) { - turn_turnserver *server = (turn_turnserver *) ss->server; - if (server) { - shutdown_client_connection(server, ss, 0, "general"); - } - } - } - } - } + switch (s->sat) { + case TCP_CLIENT_DATA_SOCKET: + case TCP_RELAY_DATA_SOCKET: { + tcp_connection *tc = s->sub_session; + if (tc) { + s->sub_session = NULL; + delete_tcp_connection(tc); + } + } break; + default: { + ts_ur_super_session *ss = s->session; + if (ss) { + turn_turnserver *server = (turn_turnserver *)ss->server; + if (server) { + shutdown_client_connection(server, ss, 0, "general"); + } + } + } + } + } } -static void socket_output_handler_bev(struct bufferevent *bev, void* arg) -{ +static void socket_output_handler_bev(struct bufferevent *bev, void *arg) { - UNUSED_ARG(bev); - UNUSED_ARG(arg); + UNUSED_ARG(bev); + UNUSED_ARG(arg); - if (tcp_congestion_control) { + if (tcp_congestion_control) { - if (bev && arg) { + if (bev && arg) { - ioa_socket_handle s = (ioa_socket_handle) arg; + ioa_socket_handle s = (ioa_socket_handle)arg; - if(s->in_write) - return; + if (s->in_write) + return; - if ((s->magic != SOCKET_MAGIC)||(s->done)||(bev != s->bev)) { - return; - } + if ((s->magic != SOCKET_MAGIC) || (s->done) || (bev != s->bev)) { + return; + } - if (s->tobeclosed) { - if (bufferevent_enabled(bev,EV_READ)) { - bufferevent_disable(bev,EV_READ); - } - return; - } + if (s->tobeclosed) { + if (bufferevent_enabled(bev, EV_READ)) { + bufferevent_disable(bev, EV_READ); + } + return; + } - if (s->sub_session) { + if (s->sub_session) { - if (s == s->sub_session->client_s) { - if (s->sub_session->peer_s && s->sub_session->peer_s->bev) { - if (!bufferevent_enabled(s->sub_session->peer_s->bev, - EV_READ)) { - if (is_socket_writeable(s->sub_session->peer_s, - STUN_BUFFER_SIZE, __FUNCTION__, 3)) { - bufferevent_enable(s->sub_session->peer_s->bev,EV_READ); - socket_input_handler_bev( - s->sub_session->peer_s->bev, - s->sub_session->peer_s); - } - } - } - } else if (s == s->sub_session->peer_s) { - if (s->sub_session->client_s - && s->sub_session->client_s->bev) { - if (!bufferevent_enabled(s->sub_session->client_s->bev, - EV_READ)) { - if (is_socket_writeable(s->sub_session->client_s, - STUN_BUFFER_SIZE, __FUNCTION__, 4)) { - bufferevent_enable(s->sub_session->client_s->bev, EV_READ); - socket_input_handler_bev( - s->sub_session->client_s->bev, - s->sub_session->client_s); - } - } - } - } - } - } - } + if (s == s->sub_session->client_s) { + if (s->sub_session->peer_s && s->sub_session->peer_s->bev) { + if (!bufferevent_enabled(s->sub_session->peer_s->bev, EV_READ)) { + if (is_socket_writeable(s->sub_session->peer_s, STUN_BUFFER_SIZE, __FUNCTION__, 3)) { + bufferevent_enable(s->sub_session->peer_s->bev, EV_READ); + socket_input_handler_bev(s->sub_session->peer_s->bev, s->sub_session->peer_s); + } + } + } + } else if (s == s->sub_session->peer_s) { + if (s->sub_session->client_s && s->sub_session->client_s->bev) { + if (!bufferevent_enabled(s->sub_session->client_s->bev, EV_READ)) { + if (is_socket_writeable(s->sub_session->client_s, STUN_BUFFER_SIZE, __FUNCTION__, 4)) { + bufferevent_enable(s->sub_session->client_s->bev, EV_READ); + socket_input_handler_bev(s->sub_session->client_s->bev, s->sub_session->client_s); + } + } + } + } + } + } + } } -static int read_spare_buffer_bev(struct bufferevent *bev) -{ - if(bev) { - char some_buffer[8192]; - bufferevent_read(bev, some_buffer, sizeof(some_buffer)); - } - return 0; +static int read_spare_buffer_bev(struct bufferevent *bev) { + if (bev) { + char some_buffer[8192]; + bufferevent_read(bev, some_buffer, sizeof(some_buffer)); + } + return 0; } -static void socket_input_handler_bev(struct bufferevent *bev, void* arg) -{ +static void socket_input_handler_bev(struct bufferevent *bev, void *arg) { - if (bev) { + if (bev) { - if(!arg) { - read_spare_buffer_bev(bev); - return; - } + if (!arg) { + read_spare_buffer_bev(bev); + return; + } - ioa_socket_handle s = (ioa_socket_handle) arg; + ioa_socket_handle s = (ioa_socket_handle)arg; - if(bev != s->bev) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx: wrong bev\n", __FUNCTION__,(long)s); - read_spare_buffer_bev(bev); - return; - } + if (bev != s->bev) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx: wrong bev\n", __FUNCTION__, (long)s); + read_spare_buffer_bev(bev); + return; + } - if((s->magic != SOCKET_MAGIC)||(s->done)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__, (long) s, s->st, s->sat); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__,(long)s); - read_spare_buffer_bev(bev); - return; - } + if ((s->magic != SOCKET_MAGIC) || (s->done)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__, (long)s, s->st, + s->sat); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__, (long)s); + read_spare_buffer_bev(bev); + return; + } - { - size_t cycle = 0; - do { - if(ioa_socket_tobeclosed(s)) { - read_spare_buffer_bev(s->bev); - break; - } - if (socket_input_worker(s) <= 0) - break; - } while((cycle++<128) && (s->bev)); - } + { + size_t cycle = 0; + do { + if (ioa_socket_tobeclosed(s)) { + read_spare_buffer_bev(s->bev); + break; + } + if (socket_input_worker(s) <= 0) + break; + } while ((cycle++ < 128) && (s->bev)); + } - if((s->magic != SOCKET_MAGIC)||(s->done)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s (1) on socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__, (long) s, s->st, s->sat); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__,(long)s); - return; - } + if ((s->magic != SOCKET_MAGIC) || (s->done)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s (1) on socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__, (long)s, s->st, + s->sat); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__, (long)s); + return; + } - close_ioa_socket_after_processing_if_necessary(s); - } + close_ioa_socket_after_processing_if_necessary(s); + } } -static void eventcb_bev(struct bufferevent *bev, short events, void *arg) -{ - UNUSED_ARG(bev); +static void eventcb_bev(struct bufferevent *bev, short events, void *arg) { + UNUSED_ARG(bev); - if (events & BEV_EVENT_CONNECTED) { - // Connect okay - } else if (events & (BEV_EVENT_ERROR | BEV_EVENT_EOF)) { - if (arg) { - ioa_socket_handle s = (ioa_socket_handle) arg; + if (events & BEV_EVENT_CONNECTED) { + // Connect okay + } else if (events & (BEV_EVENT_ERROR | BEV_EVENT_EOF)) { + if (arg) { + ioa_socket_handle s = (ioa_socket_handle)arg; - if(!is_stream_socket(s->st)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s: socket type is wrong on the socket: 0x%lx, st=%d, sat=%d\n",__FUNCTION__,(long)s,s->st,s->sat); - return; - } + if (!is_stream_socket(s->st)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s: socket type is wrong on the socket: 0x%lx, st=%d, sat=%d\n", + __FUNCTION__, (long)s, s->st, s->sat); + return; + } - if(s->magic != SOCKET_MAGIC) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s: magic is wrong on the socket: 0x%lx, st=%d, sat=%d\n",__FUNCTION__,(long)s,s->st,s->sat); - return; - } + if (s->magic != SOCKET_MAGIC) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s: magic is wrong on the socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__, + (long)s, s->st, s->sat); + return; + } - if (s->done) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s: closed socket: 0x%lx (1): done=%d, fd=%d, br=%d, st=%d, sat=%d, tbc=%d\n", __FUNCTION__, (long) s, (int) s->done, - (int) s->fd, s->broken, s->st, s->sat, s->tobeclosed); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__,(long)s); - return; - } + if (s->done) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, + "!!! %s: closed socket: 0x%lx (1): done=%d, fd=%d, br=%d, st=%d, sat=%d, tbc=%d\n", __FUNCTION__, + (long)s, (int)s->done, (int)s->fd, s->broken, s->st, s->sat, s->tobeclosed); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__, (long)s); + return; + } - if (events & BEV_EVENT_ERROR) - s->broken = 1; + if (events & BEV_EVENT_ERROR) + s->broken = 1; - s->tobeclosed = 1; + s->tobeclosed = 1; - if(s->special_session) { - free(s->special_session); - s->special_session = NULL; - } - s->special_session_size = 0; + if (s->special_session) { + free(s->special_session); + s->special_session = NULL; + } + s->special_session_size = 0; - if(!(s->session) && !(s->sub_session)) { - char sraddr[129]="\0"; - addr_to_string(&(s->remote_addr),(uint8_t*)sraddr); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s https server socket closed: 0x%lx, st=%d, sat=%d, remote addr=%s\n", __FUNCTION__,(long)s, get_ioa_socket_type(s), get_ioa_socket_app_type(s),sraddr); - IOA_CLOSE_SOCKET(s); - return; - } + if (!(s->session) && !(s->sub_session)) { + char sraddr[129] = "\0"; + addr_to_string(&(s->remote_addr), (uint8_t *)sraddr); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s https server socket closed: 0x%lx, st=%d, sat=%d, remote addr=%s\n", + __FUNCTION__, (long)s, get_ioa_socket_type(s), get_ioa_socket_app_type(s), sraddr); + IOA_CLOSE_SOCKET(s); + return; + } - switch (s->sat){ - case TCP_CLIENT_DATA_SOCKET: - case TCP_RELAY_DATA_SOCKET: - { - tcp_connection *tc = s->sub_session; - if (tc) { - s->sub_session = NULL; - delete_tcp_connection(tc); - } - } - break; - default: - { - ts_ur_super_session *ss = s->session; - if (ss) { - turn_turnserver *server = (turn_turnserver *) ss->server; - if (server) { + switch (s->sat) { + case TCP_CLIENT_DATA_SOCKET: + case TCP_RELAY_DATA_SOCKET: { + tcp_connection *tc = s->sub_session; + if (tc) { + s->sub_session = NULL; + delete_tcp_connection(tc); + } + } break; + default: { + ts_ur_super_session *ss = s->session; + if (ss) { + turn_turnserver *server = (turn_turnserver *)ss->server; + if (server) { - - { - char sraddr[129]="\0"; - addr_to_string(&(s->remote_addr),(uint8_t*)sraddr); - if (events & BEV_EVENT_EOF) { - if(server->verbose) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"session %018llu: %s socket closed remotely %s\n", - (unsigned long long)(ss->id),socket_type_name(s->st),sraddr); - if(s == ss->client_socket) { - char msg[256]; - snprintf(msg,sizeof(msg)-1,"%s connection closed by client (callback)",socket_type_name(s->st)); - shutdown_client_connection(server, ss, 0, msg); - } else if(s == ss->alloc.relay_sessions[ALLOC_IPV4_INDEX].s) { - char msg[256]; - snprintf(msg,sizeof(msg)-1,"%s connection closed by peer (ipv4 callback)",socket_type_name(s->st)); - shutdown_client_connection(server, ss, 0, msg); - } else if(s == ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].s) { - char msg[256]; - snprintf(msg,sizeof(msg)-1,"%s connection closed by peer (ipv6 callback)",socket_type_name(s->st)); - shutdown_client_connection(server, ss, 0, msg); - } else { - char msg[256]; - snprintf(msg,sizeof(msg)-1,"%s connection closed by remote party (callback)",socket_type_name(s->st)); - shutdown_client_connection(server, ss, 0, msg); - } - } else if (events & BEV_EVENT_ERROR) { - if(EVUTIL_SOCKET_ERROR()) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"session %018llu: %s socket error: %s %s\n",(unsigned long long)(ss->id), - socket_type_name(s->st),evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()), sraddr); - } else if(server->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"session %018llu: %s socket disconnected: %s\n", - (unsigned long long)(ss->id),socket_type_name(s->st),sraddr); - } - char msg[256]; - snprintf(msg,sizeof(msg)-1,"%s socket buffer operation error (callback)",socket_type_name(s->st)); - shutdown_client_connection(server, ss, 0, msg); - } - } - } - } - } - }; - } - } + { + char sraddr[129] = "\0"; + addr_to_string(&(s->remote_addr), (uint8_t *)sraddr); + if (events & BEV_EVENT_EOF) { + if (server->verbose) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "session %018llu: %s socket closed remotely %s\n", + (unsigned long long)(ss->id), socket_type_name(s->st), sraddr); + if (s == ss->client_socket) { + char msg[256]; + snprintf(msg, sizeof(msg) - 1, "%s connection closed by client (callback)", socket_type_name(s->st)); + shutdown_client_connection(server, ss, 0, msg); + } else if (s == ss->alloc.relay_sessions[ALLOC_IPV4_INDEX].s) { + char msg[256]; + snprintf(msg, sizeof(msg) - 1, "%s connection closed by peer (ipv4 callback)", + socket_type_name(s->st)); + shutdown_client_connection(server, ss, 0, msg); + } else if (s == ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].s) { + char msg[256]; + snprintf(msg, sizeof(msg) - 1, "%s connection closed by peer (ipv6 callback)", + socket_type_name(s->st)); + shutdown_client_connection(server, ss, 0, msg); + } else { + char msg[256]; + snprintf(msg, sizeof(msg) - 1, "%s connection closed by remote party (callback)", + socket_type_name(s->st)); + shutdown_client_connection(server, ss, 0, msg); + } + } else if (events & BEV_EVENT_ERROR) { + if (EVUTIL_SOCKET_ERROR()) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "session %018llu: %s socket error: %s %s\n", + (unsigned long long)(ss->id), socket_type_name(s->st), + evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()), sraddr); + } else if (server->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "session %018llu: %s socket disconnected: %s\n", + (unsigned long long)(ss->id), socket_type_name(s->st), sraddr); + } + char msg[256]; + snprintf(msg, sizeof(msg) - 1, "%s socket buffer operation error (callback)", socket_type_name(s->st)); + shutdown_client_connection(server, ss, 0, msg); + } + } + } + } + } + }; + } + } } -static int ssl_send(ioa_socket_handle s, const char* buffer, int len, int verbose) -{ +static int ssl_send(ioa_socket_handle s, const char *buffer, int len, int verbose) { - if (!s || !(s->ssl) || !buffer || (s->fd<0)) - return -1; + if (!s || !(s->ssl) || !buffer || (s->fd < 0)) + return -1; - SSL *ssl = s->ssl; + SSL *ssl = s->ssl; - if (eve(verbose)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: before write: buffer=0x%lx, len=%d\n", __FUNCTION__,(long)buffer,len); - } + if (eve(verbose)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: before write: buffer=0x%lx, len=%d\n", __FUNCTION__, (long)buffer, len); + } - if(s->parent_s) { - /* Trick only for "children" sockets: */ - BIO *wbio = SSL_get_wbio(ssl); - if(!wbio) - return -1; - int fd = BIO_get_fd(wbio,0); - int sfd = s->parent_s->fd; - if(sfd >= 0) { - if(fd != sfd) { - BIO_set_fd(wbio,sfd,BIO_NOCLOSE); - } - } - } else { - BIO *wbio = SSL_get_wbio(ssl); - if(!wbio) - return -1; - int fd = BIO_get_fd(wbio,0); - if(fd != s->fd) { - BIO_set_fd(wbio,s->fd,BIO_NOCLOSE); - } - } + if (s->parent_s) { + /* Trick only for "children" sockets: */ + BIO *wbio = SSL_get_wbio(ssl); + if (!wbio) + return -1; + int fd = BIO_get_fd(wbio, 0); + int sfd = s->parent_s->fd; + if (sfd >= 0) { + if (fd != sfd) { + BIO_set_fd(wbio, sfd, BIO_NOCLOSE); + } + } + } else { + BIO *wbio = SSL_get_wbio(ssl); + if (!wbio) + return -1; + int fd = BIO_get_fd(wbio, 0); + if (fd != s->fd) { + BIO_set_fd(wbio, s->fd, BIO_NOCLOSE); + } + } - int rc = 0; - int try_again = 1; + int rc = 0; + int try_again = 1; #if !defined(TURN_IP_RECVERR) - try_again = 0; + try_again = 0; #endif - try_start: +try_start: - do { - rc = SSL_write(ssl, buffer, len); - } while (rc < 0 && errno == EINTR); + do { + rc = SSL_write(ssl, buffer, len); + } while (rc < 0 && errno == EINTR); - if (eve(verbose)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: after write: %d\n", __FUNCTION__,rc); - } + if (eve(verbose)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: after write: %d\n", __FUNCTION__, rc); + } - if (rc < 0 && ((errno == ENOBUFS) || (errno == EAGAIN))) { - if (eve(verbose)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: ENOBUFS/EAGAIN\n", __FUNCTION__); - } - return 0; - } + if (rc < 0 && ((errno == ENOBUFS) || (errno == EAGAIN))) { + if (eve(verbose)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: ENOBUFS/EAGAIN\n", __FUNCTION__); + } + return 0; + } - if (rc >= 0) { + if (rc >= 0) { - if (eve(verbose)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: wrote %d bytes\n", __FUNCTION__, (int) rc); - } + if (eve(verbose)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: wrote %d bytes\n", __FUNCTION__, (int)rc); + } - return rc; + return rc; - } else { + } else { - if (eve(verbose)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: failure: rc=%d, err=%d\n", __FUNCTION__, (int)rc,(int)SSL_get_error(ssl, rc)); - } + if (eve(verbose)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: failure: rc=%d, err=%d\n", __FUNCTION__, (int)rc, + (int)SSL_get_error(ssl, rc)); + } - switch (SSL_get_error(ssl, rc)){ - case SSL_ERROR_NONE: - //??? - if (eve(verbose)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "wrote %d bytes\n", (int) rc); - } - return 0; - case SSL_ERROR_WANT_WRITE: - return 0; - case SSL_ERROR_WANT_READ: - return 0; - case SSL_ERROR_SYSCALL: - { - int err = errno; - if (!handle_socket_error()) { - if(s->st == DTLS_SOCKET) { - if(is_connreset()) { - if(try_again) { - BIO *wbio = SSL_get_wbio(ssl); - if(wbio) { - int fd = BIO_get_fd(wbio,0); - if(fd>=0) { - try_again = 0; - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS Socket, tring to recover write operation...\n"); - socket_readerr(fd, &(s->local_addr)); - goto try_start; - } - } - } - } - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS Socket lost packet... fine\n"); - return 0; - } - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS Socket write error unrecoverable: %d; buffer=0x%lx, len=%d, ssl=0x%lx\n", err, (long)buffer, (int)len, (long)ssl); - return -1; - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS Socket write error recoverable: %d\n", err); - return 0; - } - } - case SSL_ERROR_SSL: - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SSL write error: "); - char buf[65536]; - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s (%d)\n", ERR_error_string(ERR_get_error(), buf), - SSL_get_error(ssl, rc)); - } - return -1; - default: - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Unexpected error while writing!\n"); - } - return -1; - } - } + switch (SSL_get_error(ssl, rc)) { + case SSL_ERROR_NONE: + //??? + if (eve(verbose)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "wrote %d bytes\n", (int)rc); + } + return 0; + case SSL_ERROR_WANT_WRITE: + return 0; + case SSL_ERROR_WANT_READ: + return 0; + case SSL_ERROR_SYSCALL: { + int err = errno; + if (!handle_socket_error()) { + if (s->st == DTLS_SOCKET) { + if (is_connreset()) { + if (try_again) { + BIO *wbio = SSL_get_wbio(ssl); + if (wbio) { + int fd = BIO_get_fd(wbio, 0); + if (fd >= 0) { + try_again = 0; + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS Socket, tring to recover write operation...\n"); + socket_readerr(fd, &(s->local_addr)); + goto try_start; + } + } + } + } + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS Socket lost packet... fine\n"); + return 0; + } + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, + "DTLS Socket write error unrecoverable: %d; buffer=0x%lx, len=%d, ssl=0x%lx\n", err, (long)buffer, + (int)len, (long)ssl); + return -1; + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS Socket write error recoverable: %d\n", err); + return 0; + } + } + case SSL_ERROR_SSL: + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SSL write error: "); + char buf[65536]; + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s (%d)\n", ERR_error_string(ERR_get_error(), buf), SSL_get_error(ssl, rc)); + } + return -1; + default: + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Unexpected error while writing!\n"); + } + return -1; + } + } } -static int send_ssl_backlog_buffers(ioa_socket_handle s) -{ - int ret = 0; - if(s) { - stun_buffer_list_elem *buf_elem = s->bufs.head; - while(buf_elem) { - int rc = ssl_send(s, (char*)buf_elem->buf.buf + buf_elem->buf.offset - buf_elem->buf.coffset, (size_t)buf_elem->buf.len, (s->e ? s->e->verbose : TURN_VERBOSE_NONE)); - if(rc<1) - break; - ++ret; - pop_elem_from_buffer_list(&(s->bufs)); - buf_elem = s->bufs.head; - } - } +static int send_ssl_backlog_buffers(ioa_socket_handle s) { + int ret = 0; + if (s) { + stun_buffer_list_elem *buf_elem = s->bufs.head; + while (buf_elem) { + int rc = ssl_send(s, (char *)buf_elem->buf.buf + buf_elem->buf.offset - buf_elem->buf.coffset, + (size_t)buf_elem->buf.len, (s->e ? s->e->verbose : TURN_VERBOSE_NONE)); + if (rc < 1) + break; + ++ret; + pop_elem_from_buffer_list(&(s->bufs)); + buf_elem = s->bufs.head; + } + } - return ret; + return ret; } int is_connreset(void) { - switch (errno) { - case ECONNRESET: - case ECONNREFUSED: - return 1; - default: - ; - } - return 0; + switch (errno) { + case ECONNRESET: + case ECONNREFUSED: + return 1; + default:; + } + return 0; } int would_block(void) { #if defined(EWOULDBLOCK) - if(errno == EWOULDBLOCK) - return 1; + if (errno == EWOULDBLOCK) + return 1; #endif - return (errno == EAGAIN); + return (errno == EAGAIN); } -int udp_send(ioa_socket_handle s, const ioa_addr* dest_addr, const char* buffer, int len) -{ - int rc = 0; - evutil_socket_t fd = -1; +int udp_send(ioa_socket_handle s, const ioa_addr *dest_addr, const char *buffer, int len) { + int rc = 0; + evutil_socket_t fd = -1; - if(!s) - return -1; + if (!s) + return -1; - if(s->parent_s) - fd = s->parent_s->fd; - else - fd = s->fd; + if (s->parent_s) + fd = s->parent_s->fd; + else + fd = s->fd; - if(fd>=0) { + if (fd >= 0) { - int try_again = 1; + int try_again = 1; - int cycle; + int cycle; #if !defined(TURN_IP_RECVERR) - try_again = 0; + try_again = 0; #endif - try_start: + try_start: - cycle = 0; + cycle = 0; - if (dest_addr) { + if (dest_addr) { - int slen = get_ioa_addr_len(dest_addr); + int slen = get_ioa_addr_len(dest_addr); - do { - rc = sendto(fd, buffer, len, 0, (const struct sockaddr*) dest_addr, (socklen_t) slen); - } while ( - ((rc < 0) && (errno == EINTR)) || - ((rc<0) && is_connreset() && (++cyclelocal_addr)); - goto try_start; - } - //Lost packet - sent to nowhere... fine. - rc = len; - } - } - } + if (rc < 0) { + if ((errno == ENOBUFS) || (errno == EAGAIN)) { + // Lost packet due to overload ... fine. + rc = len; + } else if (is_connreset()) { + if (try_again) { + try_again = 0; + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "UDP Socket, tring to recover write operation...\n"); + socket_readerr(fd, &(s->local_addr)); + goto try_start; + } + // Lost packet - sent to nowhere... fine. + rc = len; + } + } + } - return rc; + return rc; } -int send_data_from_ioa_socket_nbh(ioa_socket_handle s, ioa_addr* dest_addr, - ioa_network_buffer_handle nbh, - int ttl, int tos, int *skip) -{ - int ret = -1; +int send_data_from_ioa_socket_nbh(ioa_socket_handle s, ioa_addr *dest_addr, ioa_network_buffer_handle nbh, int ttl, + int tos, int *skip) { + int ret = -1; - if(!s) { - ioa_network_buffer_delete(NULL, nbh); - return -1; - } + if (!s) { + ioa_network_buffer_delete(NULL, nbh); + return -1; + } - if (s->done || (s->fd == -1)) { - TURN_LOG_FUNC( - TURN_LOG_LEVEL_INFO, - "!!! %s: (1) Trying to send data from closed socket: 0x%lx (1): done=%d, fd=%d, st=%d, sat=%d\n", - __FUNCTION__, (long) s, (int) s->done, - (int) s->fd, s->st, s->sat); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__,(long)s); + if (s->done || (s->fd == -1)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, + "!!! %s: (1) Trying to send data from closed socket: 0x%lx (1): done=%d, fd=%d, st=%d, sat=%d\n", + __FUNCTION__, (long)s, (int)s->done, (int)s->fd, s->st, s->sat); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__, (long)s); - } else if (nbh) { - if(!ioa_socket_check_bandwidth(s,nbh,0)) { - /* Bandwidth exhausted, we pretend everything is fine: */ - ret = (int)(ioa_network_buffer_get_size(nbh)); - if(skip) *skip = 1; - } else { - if (!ioa_socket_tobeclosed(s) && s->e) { + } else if (nbh) { + if (!ioa_socket_check_bandwidth(s, nbh, 0)) { + /* Bandwidth exhausted, we pretend everything is fine: */ + ret = (int)(ioa_network_buffer_get_size(nbh)); + if (skip) + *skip = 1; + } else { + if (!ioa_socket_tobeclosed(s) && s->e) { - if (!(s->done || (s->fd == -1))) { - set_socket_ttl(s, ttl); - set_socket_tos(s, tos); + if (!(s->done || (s->fd == -1))) { + set_socket_ttl(s, ttl); + set_socket_tos(s, tos); - if (s->connected && s->bev) { - if ((s->st == TLS_SOCKET)||(s->st == TLS_SCTP_SOCKET)) { + if (s->connected && s->bev) { + if ((s->st == TLS_SOCKET) || (s->st == TLS_SCTP_SOCKET)) { #if TLS_SUPPORTED - SSL *ctx = bufferevent_openssl_get_ssl(s->bev); - if (!ctx || SSL_get_shutdown(ctx)) { - s->tobeclosed = 1; - ret = 0; - } + SSL *ctx = bufferevent_openssl_get_ssl(s->bev); + if (!ctx || SSL_get_shutdown(ctx)) { + s->tobeclosed = 1; + ret = 0; + } #endif - } + } - if (!(s->tobeclosed)) { + if (!(s->tobeclosed)) { - ret = (int) ioa_network_buffer_get_size(nbh); + ret = (int)ioa_network_buffer_get_size(nbh); - if (!tcp_congestion_control || is_socket_writeable( - s, (size_t) ret, __FUNCTION__, 2)) { - s->in_write = 1; - if (bufferevent_write(s->bev, - ioa_network_buffer_data(nbh), - ioa_network_buffer_get_size(nbh)) < 0) { - ret = -1; - perror("bufev send"); - log_socket_event( - s, - "socket write failed, to be closed", - 1); - s->tobeclosed = 1; - s->broken = 1; - } - /* - bufferevent_flush(s->bev, - EV_READ|EV_WRITE, - BEV_FLUSH); - */ - s->in_write = 0; - } else { - //drop the packet - ; - } - } - } else if (s->ssl) { - send_ssl_backlog_buffers(s); - ret = ssl_send( - s, - (char*) ioa_network_buffer_data(nbh), - ioa_network_buffer_get_size(nbh), - (s->e ? s->e->verbose : TURN_VERBOSE_NONE)); - if (ret < 0) - s->tobeclosed = 1; - else if (ret == 0) - add_buffer_to_buffer_list( - &(s->bufs), - (char*) ioa_network_buffer_data(nbh), - ioa_network_buffer_get_size(nbh)); - } else if (s->fd >= 0) { + if (!tcp_congestion_control || is_socket_writeable(s, (size_t)ret, __FUNCTION__, 2)) { + s->in_write = 1; + if (bufferevent_write(s->bev, ioa_network_buffer_data(nbh), ioa_network_buffer_get_size(nbh)) < 0) { + ret = -1; + perror("bufev send"); + log_socket_event(s, "socket write failed, to be closed", 1); + s->tobeclosed = 1; + s->broken = 1; + } + /* + bufferevent_flush(s->bev, + EV_READ|EV_WRITE, + BEV_FLUSH); + */ + s->in_write = 0; + } else { + // drop the packet + ; + } + } + } else if (s->ssl) { + send_ssl_backlog_buffers(s); + ret = ssl_send(s, (char *)ioa_network_buffer_data(nbh), ioa_network_buffer_get_size(nbh), + (s->e ? s->e->verbose : TURN_VERBOSE_NONE)); + if (ret < 0) + s->tobeclosed = 1; + else if (ret == 0) + add_buffer_to_buffer_list(&(s->bufs), (char *)ioa_network_buffer_data(nbh), + ioa_network_buffer_get_size(nbh)); + } else if (s->fd >= 0) { - if (s->connected && !(s->parent_s)) { - dest_addr = NULL; /* ignore dest_addr */ - } else if (!dest_addr) { - dest_addr = &(s->remote_addr); - } + if (s->connected && !(s->parent_s)) { + dest_addr = NULL; /* ignore dest_addr */ + } else if (!dest_addr) { + dest_addr = &(s->remote_addr); + } - ret = udp_send(s, - dest_addr, - (char*) ioa_network_buffer_data(nbh),ioa_network_buffer_get_size(nbh)); - if (ret < 0) { - s->tobeclosed = 1; + ret = udp_send(s, dest_addr, (char *)ioa_network_buffer_data(nbh), ioa_network_buffer_get_size(nbh)); + if (ret < 0) { + s->tobeclosed = 1; #if defined(EADDRNOTAVAIL) - int perr=errno; + int perr = errno; #endif - perror("udp send"); + perror("udp send"); #if defined(EADDRNOTAVAIL) - if(dest_addr && (perr==EADDRNOTAVAIL)) { - char sfrom[129]; - addr_to_string(&(s->local_addr), (uint8_t*)sfrom); - char sto[129]; - addr_to_string(dest_addr, (uint8_t*)sto); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: network error: address unreachable from %s to %s\n", - __FUNCTION__,sfrom,sto); - } + if (dest_addr && (perr == EADDRNOTAVAIL)) { + char sfrom[129]; + addr_to_string(&(s->local_addr), (uint8_t *)sfrom); + char sto[129]; + addr_to_string(dest_addr, (uint8_t *)sto); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: network error: address unreachable from %s to %s\n", + __FUNCTION__, sfrom, sto); + } #endif - } - } - } - } - } - } + } + } + } + } + } + } - ioa_network_buffer_delete(s->e, nbh); + ioa_network_buffer_delete(s->e, nbh); - return ret; + return ret; } -int send_data_from_ioa_socket_tcp(ioa_socket_handle s, const void *data, size_t sz) -{ - int ret = -1; +int send_data_from_ioa_socket_tcp(ioa_socket_handle s, const void *data, size_t sz) { + int ret = -1; - if(s && data) { + if (s && data) { - if (s->done || (s->fd == -1) || ioa_socket_tobeclosed(s) || !(s->e)) { - TURN_LOG_FUNC( - TURN_LOG_LEVEL_INFO, - "!!! %s: (1) Trying to send data from bad socket: 0x%lx (1): done=%d, fd=%d, st=%d, sat=%d\n", - __FUNCTION__, (long) s, (int) s->done, - (int) s->fd, s->st, s->sat); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__,(long)s); + if (s->done || (s->fd == -1) || ioa_socket_tobeclosed(s) || !(s->e)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, + "!!! %s: (1) Trying to send data from bad socket: 0x%lx (1): done=%d, fd=%d, st=%d, sat=%d\n", + __FUNCTION__, (long)s, (int)s->done, (int)s->fd, s->st, s->sat); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__, (long)s); - } else if (s->connected && s->bev) { - if ((s->st == TLS_SOCKET)||(s->st == TLS_SCTP_SOCKET)) { + } else if (s->connected && s->bev) { + if ((s->st == TLS_SOCKET) || (s->st == TLS_SCTP_SOCKET)) { #if TLS_SUPPORTED - SSL *ctx = bufferevent_openssl_get_ssl(s->bev); - if (!ctx || SSL_get_shutdown(ctx)) { - s->tobeclosed = 1; - ret = 0; - } + SSL *ctx = bufferevent_openssl_get_ssl(s->bev); + if (!ctx || SSL_get_shutdown(ctx)) { + s->tobeclosed = 1; + ret = 0; + } #endif - } + } - if (!(s->tobeclosed)) { + if (!(s->tobeclosed)) { - ret = (int)sz; + ret = (int)sz; - s->in_write = 1; - if (bufferevent_write(s->bev, data, sz) < 0) { - ret = -1; - perror("bufev send"); - log_socket_event(s, "socket write failed, to be closed", 1); - s->tobeclosed = 1; - s->broken = 1; - } - s->in_write = 0; - } - } - } + s->in_write = 1; + if (bufferevent_write(s->bev, data, sz) < 0) { + ret = -1; + perror("bufev send"); + log_socket_event(s, "socket write failed, to be closed", 1); + s->tobeclosed = 1; + s->broken = 1; + } + s->in_write = 0; + } + } + } - return ret; + return ret; } -int send_str_from_ioa_socket_tcp(ioa_socket_handle s, const void *data) -{ - if(data) { - return send_data_from_ioa_socket_tcp(s, data, strlen((const char*)data)); - } else { - return 0; - } +int send_str_from_ioa_socket_tcp(ioa_socket_handle s, const void *data) { + if (data) { + return send_data_from_ioa_socket_tcp(s, data, strlen((const char *)data)); + } else { + return 0; + } } -int send_ulong_from_ioa_socket_tcp(ioa_socket_handle s, size_t data) -{ - char str[129]; - snprintf(str,sizeof(str)-1,"%lu",(unsigned long)data); +int send_ulong_from_ioa_socket_tcp(ioa_socket_handle s, size_t data) { + char str[129]; + snprintf(str, sizeof(str) - 1, "%lu", (unsigned long)data); - return send_str_from_ioa_socket_tcp(s,str); + return send_str_from_ioa_socket_tcp(s, str); } -int register_callback_on_ioa_socket(ioa_engine_handle e, ioa_socket_handle s, int event_type, ioa_net_event_handler cb, void* ctx, int clean_preexisting) -{ - if(s) { +int register_callback_on_ioa_socket(ioa_engine_handle e, ioa_socket_handle s, int event_type, ioa_net_event_handler cb, + void *ctx, int clean_preexisting) { + if (s) { - if (event_type & IOA_EV_READ) { + if (event_type & IOA_EV_READ) { - if(e) - s->e = e; + if (e) + s->e = e; - if(s->e && !(s->parent_s)) { + if (s->e && !(s->parent_s)) { - switch(s->st) { - case DTLS_SOCKET: - case UDP_SOCKET: - if(s->read_event) { - if(!clean_preexisting) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: software error: buffer preset 1\n", __FUNCTION__); - return -1; - } - } else { - s->read_event = event_new(s->e->event_base,s->fd, EV_READ|EV_PERSIST, socket_input_handler, s); - event_add(s->read_event,NULL); - } - break; - case TENTATIVE_TCP_SOCKET: - case TENTATIVE_SCTP_SOCKET: - if(s->bev) { - if(!clean_preexisting) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: software error: buffer preset 2\n", __FUNCTION__); - return -1; - } - } else if(s->read_event) { - if(!clean_preexisting) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: software error: buffer preset 3\n", __FUNCTION__); - return -1; - } - } else { - s->read_event = event_new(s->e->event_base,s->fd, EV_READ|EV_PERSIST, socket_input_handler, s); - event_add(s->read_event,NULL); - } - break; - case SCTP_SOCKET: - case TCP_SOCKET: - case TCP_SOCKET_PROXY: - if(s->bev) { - if(!clean_preexisting) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: software error: buffer preset 4\n", __FUNCTION__); - return -1; - } - } else { + switch (s->st) { + case DTLS_SOCKET: + case UDP_SOCKET: + if (s->read_event) { + if (!clean_preexisting) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: software error: buffer preset 1\n", __FUNCTION__); + return -1; + } + } else { + s->read_event = event_new(s->e->event_base, s->fd, EV_READ | EV_PERSIST, socket_input_handler, s); + event_add(s->read_event, NULL); + } + break; + case TENTATIVE_TCP_SOCKET: + case TENTATIVE_SCTP_SOCKET: + if (s->bev) { + if (!clean_preexisting) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: software error: buffer preset 2\n", __FUNCTION__); + return -1; + } + } else if (s->read_event) { + if (!clean_preexisting) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: software error: buffer preset 3\n", __FUNCTION__); + return -1; + } + } else { + s->read_event = event_new(s->e->event_base, s->fd, EV_READ | EV_PERSIST, socket_input_handler, s); + event_add(s->read_event, NULL); + } + break; + case SCTP_SOCKET: + case TCP_SOCKET: + case TCP_SOCKET_PROXY: + if (s->bev) { + if (!clean_preexisting) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: software error: buffer preset 4\n", __FUNCTION__); + return -1; + } + } else { #if TLS_SUPPORTED - if((s->sat != TCP_CLIENT_DATA_SOCKET) && (s->sat != TCP_RELAY_DATA_SOCKET) && check_tentative_tls(s->fd)) { - s->tobeclosed = 1; - return -1; - } + if ((s->sat != TCP_CLIENT_DATA_SOCKET) && (s->sat != TCP_RELAY_DATA_SOCKET) && check_tentative_tls(s->fd)) { + s->tobeclosed = 1; + return -1; + } #endif - s->bev = bufferevent_socket_new(s->e->event_base, - s->fd, - TURN_BUFFEREVENTS_OPTIONS); - bufferevent_setcb(s->bev, socket_input_handler_bev, socket_output_handler_bev, - eventcb_bev, s); - bufferevent_setwatermark(s->bev, EV_READ|EV_WRITE, 0, BUFFEREVENT_HIGH_WATERMARK); - bufferevent_enable(s->bev, EV_READ|EV_WRITE); /* Start reading. */ - } - break; - case TLS_SCTP_SOCKET: - case TLS_SOCKET: - if(s->bev) { - if(!clean_preexisting) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: software error: buffer preset 5\n", __FUNCTION__); - return -1; - } - } else { + s->bev = bufferevent_socket_new(s->e->event_base, s->fd, TURN_BUFFEREVENTS_OPTIONS); + bufferevent_setcb(s->bev, socket_input_handler_bev, socket_output_handler_bev, eventcb_bev, s); + bufferevent_setwatermark(s->bev, EV_READ | EV_WRITE, 0, BUFFEREVENT_HIGH_WATERMARK); + bufferevent_enable(s->bev, EV_READ | EV_WRITE); /* Start reading. */ + } + break; + case TLS_SCTP_SOCKET: + case TLS_SOCKET: + if (s->bev) { + if (!clean_preexisting) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: software error: buffer preset 5\n", __FUNCTION__); + return -1; + } + } else { #if TLS_SUPPORTED - if(!(s->ssl)) { - //??? how we can get to this point ??? - set_socket_ssl(s,SSL_new(e->tls_ctx)); - s->bev = bufferevent_openssl_socket_new(s->e->event_base, - s->fd, - s->ssl, - BUFFEREVENT_SSL_ACCEPTING, - TURN_BUFFEREVENTS_OPTIONS); - } else { - s->bev = bufferevent_openssl_socket_new(s->e->event_base, - s->fd, - s->ssl, - BUFFEREVENT_SSL_OPEN, - TURN_BUFFEREVENTS_OPTIONS); - } - bufferevent_setcb(s->bev, socket_input_handler_bev, socket_output_handler_bev, - eventcb_bev, s); - bufferevent_setwatermark(s->bev, EV_READ|EV_WRITE, 0, BUFFEREVENT_HIGH_WATERMARK); - bufferevent_enable(s->bev, EV_READ|EV_WRITE); /* Start reading. */ + if (!(s->ssl)) { + //??? how we can get to this point ??? + set_socket_ssl(s, SSL_new(e->tls_ctx)); + s->bev = bufferevent_openssl_socket_new(s->e->event_base, s->fd, s->ssl, BUFFEREVENT_SSL_ACCEPTING, + TURN_BUFFEREVENTS_OPTIONS); + } else { + s->bev = bufferevent_openssl_socket_new(s->e->event_base, s->fd, s->ssl, BUFFEREVENT_SSL_OPEN, + TURN_BUFFEREVENTS_OPTIONS); + } + bufferevent_setcb(s->bev, socket_input_handler_bev, socket_output_handler_bev, eventcb_bev, s); + bufferevent_setwatermark(s->bev, EV_READ | EV_WRITE, 0, BUFFEREVENT_HIGH_WATERMARK); + bufferevent_enable(s->bev, EV_READ | EV_WRITE); /* Start reading. */ #endif - } - break; - default: - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: software error: unknown socket type: %d\n", __FUNCTION__,(int)(s->st)); - return -1; - } - } + } + break; + default: + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: software error: unknown socket type: %d\n", __FUNCTION__, + (int)(s->st)); + return -1; + } + } - s->read_cb = cb; - s->read_ctx = ctx; - return 0; - } - } + s->read_cb = cb; + s->read_ctx = ctx; + return 0; + } + } - /* unsupported event or else */ - return -1; + /* unsupported event or else */ + return -1; } -int ioa_socket_tobeclosed(ioa_socket_handle s) -{ - if(s) { - if(s->magic != SOCKET_MAGIC) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s: magic is wrong on the socket: 0x%lx, st=%d, sat=%d\n",__FUNCTION__,(long)s,s->st,s->sat); - return 1; - } +int ioa_socket_tobeclosed(ioa_socket_handle s) { + if (s) { + if (s->magic != SOCKET_MAGIC) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s: magic is wrong on the socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__, + (long)s, s->st, s->sat); + return 1; + } - if(s->done) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s: check on already closed socket: 0x%lx, st=%d, sat=%d\n",__FUNCTION__,(long)s,s->st,s->sat); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__,(long)s); - return 1; - } - if(s->tobeclosed) { - return 1; - } else if(s->broken) { - s->tobeclosed = 1; - log_socket_event(s, "socket broken", 0); - return 1; - } else if(s->fd < 0) { - s->tobeclosed = 1; - log_socket_event(s, "socket fd<0", 0); - return 1; - } else if(s->ssl) { - if(SSL_get_shutdown(s->ssl)) { - s->tobeclosed = 1; - log_socket_event(s, "socket SSL shutdown", 0); - return 1; - } - } - } - return 0; + if (s->done) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s: check on already closed socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__, + (long)s, s->st, s->sat); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__, (long)s); + return 1; + } + if (s->tobeclosed) { + return 1; + } else if (s->broken) { + s->tobeclosed = 1; + log_socket_event(s, "socket broken", 0); + return 1; + } else if (s->fd < 0) { + s->tobeclosed = 1; + log_socket_event(s, "socket fd<0", 0); + return 1; + } else if (s->ssl) { + if (SSL_get_shutdown(s->ssl)) { + s->tobeclosed = 1; + log_socket_event(s, "socket SSL shutdown", 0); + return 1; + } + } + } + return 0; } -void set_ioa_socket_tobeclosed(ioa_socket_handle s) -{ - if(s) - s->tobeclosed = 1; +void set_ioa_socket_tobeclosed(ioa_socket_handle s) { + if (s) + s->tobeclosed = 1; } /* * Network buffer functions */ -ioa_network_buffer_handle ioa_network_buffer_allocate(ioa_engine_handle e) -{ - stun_buffer_list_elem *buf_elem = new_blist_elem(e); - buf_elem->buf.len = 0; - buf_elem->buf.offset = 0; - buf_elem->buf.coffset = 0; - return buf_elem; +ioa_network_buffer_handle ioa_network_buffer_allocate(ioa_engine_handle e) { + stun_buffer_list_elem *buf_elem = new_blist_elem(e); + buf_elem->buf.len = 0; + buf_elem->buf.offset = 0; + buf_elem->buf.coffset = 0; + return buf_elem; } /* We do not use special header in this simple implementation */ -void ioa_network_buffer_header_init(ioa_network_buffer_handle nbh) -{ - UNUSED_ARG(nbh); -} +void ioa_network_buffer_header_init(ioa_network_buffer_handle nbh) { UNUSED_ARG(nbh); } -uint8_t *ioa_network_buffer_data(ioa_network_buffer_handle nbh) -{ - stun_buffer_list_elem *buf_elem = (stun_buffer_list_elem *)nbh; - return buf_elem->buf.buf + buf_elem->buf.offset - buf_elem->buf.coffset; -} - -size_t ioa_network_buffer_get_size(ioa_network_buffer_handle nbh) -{ - if(!nbh) - return 0; - else { - stun_buffer_list_elem *buf_elem = (stun_buffer_list_elem *)nbh; - return (size_t)(buf_elem->buf.len); - } -} - -size_t ioa_network_buffer_get_capacity(ioa_network_buffer_handle nbh) -{ - if(!nbh) - return 0; - else { - stun_buffer_list_elem *buf_elem = (stun_buffer_list_elem *)nbh; - if(buf_elem->buf.offset < STUN_BUFFER_SIZE) { - return (STUN_BUFFER_SIZE - buf_elem->buf.offset); - } - return 0; - } -} - -size_t ioa_network_buffer_get_capacity_udp(void) -{ - return UDP_STUN_BUFFER_SIZE; -} - -void ioa_network_buffer_set_size(ioa_network_buffer_handle nbh, size_t len) -{ +uint8_t *ioa_network_buffer_data(ioa_network_buffer_handle nbh) { stun_buffer_list_elem *buf_elem = (stun_buffer_list_elem *)nbh; - buf_elem->buf.len=(size_t)len; + return buf_elem->buf.buf + buf_elem->buf.offset - buf_elem->buf.coffset; } -void ioa_network_buffer_add_offset_size(ioa_network_buffer_handle nbh, uint16_t offset, uint8_t coffset, size_t len) -{ - stun_buffer_list_elem *buf_elem = (stun_buffer_list_elem *)nbh; - buf_elem->buf.len=(size_t)len; - buf_elem->buf.offset += offset; - buf_elem->buf.coffset += coffset; - - if((buf_elem->buf.offset + buf_elem->buf.len - buf_elem->buf.coffset)>=sizeof(buf_elem->buf.buf) || - (buf_elem->buf.offset + sizeof(buf_elem->buf.channel) < buf_elem->buf.coffset) - ) { - buf_elem->buf.coffset = 0; - buf_elem->buf.len = 0; - buf_elem->buf.offset = 0; +size_t ioa_network_buffer_get_size(ioa_network_buffer_handle nbh) { + if (!nbh) + return 0; + else { + stun_buffer_list_elem *buf_elem = (stun_buffer_list_elem *)nbh; + return (size_t)(buf_elem->buf.len); } } -uint16_t ioa_network_buffer_get_offset(ioa_network_buffer_handle nbh) -{ +size_t ioa_network_buffer_get_capacity(ioa_network_buffer_handle nbh) { + if (!nbh) + return 0; + else { + stun_buffer_list_elem *buf_elem = (stun_buffer_list_elem *)nbh; + if (buf_elem->buf.offset < STUN_BUFFER_SIZE) { + return (STUN_BUFFER_SIZE - buf_elem->buf.offset); + } + return 0; + } +} + +size_t ioa_network_buffer_get_capacity_udp(void) { return UDP_STUN_BUFFER_SIZE; } + +void ioa_network_buffer_set_size(ioa_network_buffer_handle nbh, size_t len) { + stun_buffer_list_elem *buf_elem = (stun_buffer_list_elem *)nbh; + buf_elem->buf.len = (size_t)len; +} + +void ioa_network_buffer_add_offset_size(ioa_network_buffer_handle nbh, uint16_t offset, uint8_t coffset, size_t len) { + stun_buffer_list_elem *buf_elem = (stun_buffer_list_elem *)nbh; + buf_elem->buf.len = (size_t)len; + buf_elem->buf.offset += offset; + buf_elem->buf.coffset += coffset; + + if ((buf_elem->buf.offset + buf_elem->buf.len - buf_elem->buf.coffset) >= sizeof(buf_elem->buf.buf) || + (buf_elem->buf.offset + sizeof(buf_elem->buf.channel) < buf_elem->buf.coffset)) { + buf_elem->buf.coffset = 0; + buf_elem->buf.len = 0; + buf_elem->buf.offset = 0; + } +} + +uint16_t ioa_network_buffer_get_offset(ioa_network_buffer_handle nbh) { stun_buffer_list_elem *buf_elem = (stun_buffer_list_elem *)nbh; return buf_elem->buf.offset; } -uint8_t ioa_network_buffer_get_coffset(ioa_network_buffer_handle nbh) -{ +uint8_t ioa_network_buffer_get_coffset(ioa_network_buffer_handle nbh) { stun_buffer_list_elem *buf_elem = (stun_buffer_list_elem *)nbh; return buf_elem->buf.coffset; } void ioa_network_buffer_delete(ioa_engine_handle e, ioa_network_buffer_handle nbh) { stun_buffer_list_elem *buf_elem = (stun_buffer_list_elem *)nbh; - free_blist_elem(e,buf_elem); + free_blist_elem(e, buf_elem); } /////////// REPORTING STATUS ///////////////////// -const char* get_ioa_socket_cipher(ioa_socket_handle s) -{ - if(s && s->ssl) { - return SSL_get_cipher(s->ssl); - } - return "no SSL"; +const char *get_ioa_socket_cipher(ioa_socket_handle s) { + if (s && s->ssl) { + return SSL_get_cipher(s->ssl); + } + return "no SSL"; } -const char* get_ioa_socket_ssl_method(ioa_socket_handle s) -{ - if(s && s->ssl) { - return turn_get_ssl_method(s->ssl, "UNKNOWN"); - } - return "no SSL"; +const char *get_ioa_socket_ssl_method(ioa_socket_handle s) { + if (s && s->ssl) { + return turn_get_ssl_method(s->ssl, "UNKNOWN"); + } + return "no SSL"; } -void turn_report_allocation_set(void *a, turn_time_t lifetime, int refresh) -{ - if(a) { - ts_ur_super_session *ss = (ts_ur_super_session*)(((allocation*)a)->owner); - if(ss) { - const char* status="new"; - if(refresh) - status="refreshed"; - turn_turnserver *server = (turn_turnserver*)ss->server; - if(server) { - ioa_engine_handle e = turn_server_get_engine(server); - if(e && e->verbose && ss->client_socket) { - if(ss->client_socket->ssl) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"session %018llu: %s, realm=<%s>, username=<%s>, lifetime=%lu, cipher=%s, method=%s\n", (unsigned long long)ss->id, status, (char*)ss->realm_options.name, (char*)ss->username, (unsigned long)lifetime, SSL_get_cipher(ss->client_socket->ssl), - turn_get_ssl_method(ss->client_socket->ssl, "UNKNOWN")); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"session %018llu: %s, realm=<%s>, username=<%s>, lifetime=%lu\n", (unsigned long long)ss->id, status, (char*)ss->realm_options.name, (char*)ss->username, (unsigned long)lifetime); - } - } +void turn_report_allocation_set(void *a, turn_time_t lifetime, int refresh) { + if (a) { + ts_ur_super_session *ss = (ts_ur_super_session *)(((allocation *)a)->owner); + if (ss) { + const char *status = "new"; + if (refresh) + status = "refreshed"; + turn_turnserver *server = (turn_turnserver *)ss->server; + if (server) { + ioa_engine_handle e = turn_server_get_engine(server); + if (e && e->verbose && ss->client_socket) { + if (ss->client_socket->ssl) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, + "session %018llu: %s, realm=<%s>, username=<%s>, lifetime=%lu, cipher=%s, method=%s\n", + (unsigned long long)ss->id, status, (char *)ss->realm_options.name, (char *)ss->username, + (unsigned long)lifetime, SSL_get_cipher(ss->client_socket->ssl), + turn_get_ssl_method(ss->client_socket->ssl, "UNKNOWN")); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "session %018llu: %s, realm=<%s>, username=<%s>, lifetime=%lu\n", + (unsigned long long)ss->id, status, (char *)ss->realm_options.name, (char *)ss->username, + (unsigned long)lifetime); + } + } #if !defined(TURN_NO_HIREDIS) - { - char key[1024]; - if(ss->realm_options.name[0]) { - snprintf(key,sizeof(key),"turn/realm/%s/user/%s/allocation/%018llu/status",ss->realm_options.name,(char*)ss->username, (unsigned long long)ss->id); - } else { - snprintf(key,sizeof(key),"turn/user/%s/allocation/%018llu/status",(char*)ss->username, (unsigned long long)ss->id); - } - uint8_t saddr[129]; - uint8_t rsaddr[129]; - addr_to_string(get_local_addr_from_ioa_socket(ss->client_socket), saddr); - addr_to_string(get_remote_addr_from_ioa_socket(ss->client_socket), rsaddr); - const char *type = socket_type_name(get_ioa_socket_type(ss->client_socket)); - const char *ssl = ss->client_socket->ssl ? turn_get_ssl_method(ss->client_socket->ssl, "UNKNOWN") : "NONE"; - const char *cipher = ss->client_socket->ssl ? get_ioa_socket_cipher(ss->client_socket) : "NONE"; - send_message_to_redis(e->rch, "set", key, "%s lifetime=%lu, type=%s, local=%s, remote=%s, ssl=%s, cipher=%s", status, (unsigned long)lifetime, type, saddr, rsaddr, ssl, cipher); - send_message_to_redis(e->rch, "publish", key, "%s lifetime=%lu, type=%s, local=%s, remote=%s, ssl=%s, cipher=%s", status, (unsigned long)lifetime, type, saddr, rsaddr, ssl, cipher); - } + { + char key[1024]; + if (ss->realm_options.name[0]) { + snprintf(key, sizeof(key), "turn/realm/%s/user/%s/allocation/%018llu/status", ss->realm_options.name, + (char *)ss->username, (unsigned long long)ss->id); + } else { + snprintf(key, sizeof(key), "turn/user/%s/allocation/%018llu/status", (char *)ss->username, + (unsigned long long)ss->id); + } + uint8_t saddr[129]; + uint8_t rsaddr[129]; + addr_to_string(get_local_addr_from_ioa_socket(ss->client_socket), saddr); + addr_to_string(get_remote_addr_from_ioa_socket(ss->client_socket), rsaddr); + const char *type = socket_type_name(get_ioa_socket_type(ss->client_socket)); + const char *ssl = ss->client_socket->ssl ? turn_get_ssl_method(ss->client_socket->ssl, "UNKNOWN") : "NONE"; + const char *cipher = ss->client_socket->ssl ? get_ioa_socket_cipher(ss->client_socket) : "NONE"; + send_message_to_redis(e->rch, "set", key, "%s lifetime=%lu, type=%s, local=%s, remote=%s, ssl=%s, cipher=%s", + status, (unsigned long)lifetime, type, saddr, rsaddr, ssl, cipher); + send_message_to_redis(e->rch, "publish", key, + "%s lifetime=%lu, type=%s, local=%s, remote=%s, ssl=%s, cipher=%s", status, + (unsigned long)lifetime, type, saddr, rsaddr, ssl, cipher); + } #endif #if !defined(TURN_NO_PROMETHEUS) - { - if (!refresh) - prom_inc_allocation(get_ioa_socket_type(ss->client_socket)); - } + { + if (!refresh) + prom_inc_allocation(get_ioa_socket_type(ss->client_socket)); + } #endif - } - } - } + } + } + } } -void turn_report_allocation_delete(void *a, SOCKET_TYPE socket_type) -{ - if(a) { - ts_ur_super_session *ss = (ts_ur_super_session*)(((allocation*)a)->owner); - if(ss) { - turn_turnserver *server = (turn_turnserver*)ss->server; - if(server) { - ioa_engine_handle e = turn_server_get_engine(server); - if(e && e->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"session %018llu: delete: realm=<%s>, username=<%s>\n", (unsigned long long)ss->id, (char*)ss->realm_options.name, (char*)ss->username); - } +void turn_report_allocation_delete(void *a, SOCKET_TYPE socket_type) { + if (a) { + ts_ur_super_session *ss = (ts_ur_super_session *)(((allocation *)a)->owner); + if (ss) { + turn_turnserver *server = (turn_turnserver *)ss->server; + if (server) { + ioa_engine_handle e = turn_server_get_engine(server); + if (e && e->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "session %018llu: delete: realm=<%s>, username=<%s>\n", + (unsigned long long)ss->id, (char *)ss->realm_options.name, (char *)ss->username); + } #if !defined(TURN_NO_HIREDIS) - { - char key[1024]; - if(ss->realm_options.name[0]) { - snprintf(key,sizeof(key),"turn/realm/%s/user/%s/allocation/%018llu/status",ss->realm_options.name,(char*)ss->username, (unsigned long long)ss->id); - } else { - snprintf(key,sizeof(key),"turn/user/%s/allocation/%018llu/status",(char*)ss->username, (unsigned long long)ss->id); - } - send_message_to_redis(e->rch, "del", key, ""); - send_message_to_redis(e->rch, "publish", key, "deleted"); + { + char key[1024]; + if (ss->realm_options.name[0]) { + snprintf(key, sizeof(key), "turn/realm/%s/user/%s/allocation/%018llu/status", ss->realm_options.name, + (char *)ss->username, (unsigned long long)ss->id); + } else { + snprintf(key, sizeof(key), "turn/user/%s/allocation/%018llu/status", (char *)ss->username, + (unsigned long long)ss->id); + } + send_message_to_redis(e->rch, "del", key, ""); + send_message_to_redis(e->rch, "publish", key, "deleted"); - // report total traffic usage for this allocation - if(ss->realm_options.name[0]) { - snprintf(key, sizeof(key), "turn/realm/%s/user/%s/allocation/%018llu/total_traffic", ss->realm_options.name, (char*)ss->username, (unsigned long long)ss->id); - } else { - snprintf(key, sizeof(key), "turn/user/%s/allocation/%018llu/total_traffic", (char*)ss->username, (unsigned long long)ss->id); - } - send_message_to_redis(e->rch, "publish", key, "rcvp=%lu, rcvb=%lu, sentp=%lu, sentb=%lu", (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes)); - if (ss->realm_options.name[0]) { - snprintf(key, sizeof(key), "turn/realm/%s/user/%s/allocation/%018llu/total_traffic/peer", ss->realm_options.name, (char*)ss->username, (unsigned long long)(ss->id)); - } - else { - snprintf(key, sizeof(key), "turn/user/%s/allocation/%018llu/total_traffic/peer", (char*)ss->username, (unsigned long long)(ss->id)); - } - send_message_to_redis(e->rch, "publish", key, "rcvp=%lu, rcvb=%lu, sentp=%lu, sentb=%lu", (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes)); - } + // report total traffic usage for this allocation + if (ss->realm_options.name[0]) { + snprintf(key, sizeof(key), "turn/realm/%s/user/%s/allocation/%018llu/total_traffic", ss->realm_options.name, + (char *)ss->username, (unsigned long long)ss->id); + } else { + snprintf(key, sizeof(key), "turn/user/%s/allocation/%018llu/total_traffic", (char *)ss->username, + (unsigned long long)ss->id); + } + send_message_to_redis(e->rch, "publish", key, "rcvp=%lu, rcvb=%lu, sentp=%lu, sentb=%lu", + (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), + (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes)); + if (ss->realm_options.name[0]) { + snprintf(key, sizeof(key), "turn/realm/%s/user/%s/allocation/%018llu/total_traffic/peer", + ss->realm_options.name, (char *)ss->username, (unsigned long long)(ss->id)); + } else { + snprintf(key, sizeof(key), "turn/user/%s/allocation/%018llu/total_traffic/peer", (char *)ss->username, + (unsigned long long)(ss->id)); + } + send_message_to_redis(e->rch, "publish", key, "rcvp=%lu, rcvb=%lu, sentp=%lu, sentb=%lu", + (unsigned long)(ss->t_peer_received_packets), + (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), + (unsigned long)(ss->t_peer_sent_bytes)); + } #endif #if !defined(TURN_NO_PROMETHEUS) - { - if(ss->realm_options.name[0]){ + { + if (ss->realm_options.name[0]) { - // Set prometheus traffic metrics - prom_set_finished_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), false); - prom_set_finished_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), true); - } else { - // Set prometheus traffic metrics - prom_set_finished_traffic(NULL, (const char*)ss->username, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), false); - prom_set_finished_traffic(NULL, (const char*)ss->username, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), true); - } - prom_dec_allocation(socket_type); - } + // Set prometheus traffic metrics + prom_set_finished_traffic(ss->realm_options.name, (const char *)ss->username, + (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), + (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), false); + prom_set_finished_traffic( + ss->realm_options.name, (const char *)ss->username, (unsigned long)(ss->t_peer_received_packets), + (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), + (unsigned long)(ss->t_peer_sent_bytes), true); + } else { + // Set prometheus traffic metrics + prom_set_finished_traffic(NULL, (const char *)ss->username, (unsigned long)(ss->t_received_packets), + (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), + (unsigned long)(ss->t_sent_bytes), false); + prom_set_finished_traffic(NULL, (const char *)ss->username, (unsigned long)(ss->t_peer_received_packets), + (unsigned long)(ss->t_peer_received_bytes), + (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), + true); + } + prom_dec_allocation(socket_type); + } #endif - } - } - } + } + } + } } -void turn_report_session_usage(void *session, int force_invalid) -{ - if(session) { - ts_ur_super_session *ss = (ts_ur_super_session *)session; - turn_turnserver *server = (turn_turnserver*)ss->server; - if(server && (ss->received_packets || ss->sent_packets || force_invalid)) { - ioa_engine_handle e = turn_server_get_engine(server); - if(((ss->received_packets+ss->sent_packets+ss->peer_received_packets+ss->peer_sent_packets)&4095)==0 || force_invalid) { - if(e && e->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"session %018llu: usage: realm=<%s>, username=<%s>, rp=%lu, rb=%lu, sp=%lu, sb=%lu\n", (unsigned long long)(ss->id), (char*)ss->realm_options.name, (char*)ss->username, (unsigned long)(ss->received_packets), (unsigned long)(ss->received_bytes),(unsigned long)(ss->sent_packets),(unsigned long)(ss->sent_bytes)); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "session %018llu: peer usage: realm=<%s>, username=<%s>, rp=%lu, rb=%lu, sp=%lu, sb=%lu\n", (unsigned long long)(ss->id), (char*)ss->realm_options.name, (char*)ss->username, (unsigned long)(ss->peer_received_packets), (unsigned long)(ss->peer_received_bytes), (unsigned long)(ss->peer_sent_packets), (unsigned long)(ss->peer_sent_bytes)); - } +void turn_report_session_usage(void *session, int force_invalid) { + if (session) { + ts_ur_super_session *ss = (ts_ur_super_session *)session; + turn_turnserver *server = (turn_turnserver *)ss->server; + if (server && (ss->received_packets || ss->sent_packets || force_invalid)) { + ioa_engine_handle e = turn_server_get_engine(server); + if (((ss->received_packets + ss->sent_packets + ss->peer_received_packets + ss->peer_sent_packets) & 4095) == 0 || + force_invalid) { + if (e && e->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, + "session %018llu: usage: realm=<%s>, username=<%s>, rp=%lu, rb=%lu, sp=%lu, sb=%lu\n", + (unsigned long long)(ss->id), (char *)ss->realm_options.name, (char *)ss->username, + (unsigned long)(ss->received_packets), (unsigned long)(ss->received_bytes), + (unsigned long)(ss->sent_packets), (unsigned long)(ss->sent_bytes)); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, + "session %018llu: peer usage: realm=<%s>, username=<%s>, rp=%lu, rb=%lu, sp=%lu, sb=%lu\n", + (unsigned long long)(ss->id), (char *)ss->realm_options.name, (char *)ss->username, + (unsigned long)(ss->peer_received_packets), (unsigned long)(ss->peer_received_bytes), + (unsigned long)(ss->peer_sent_packets), (unsigned long)(ss->peer_sent_bytes)); + } #if !defined(TURN_NO_HIREDIS) - { - char key[1024]; - if(ss->realm_options.name[0]) { - snprintf(key,sizeof(key),"turn/realm/%s/user/%s/allocation/%018llu/traffic",ss->realm_options.name,(char*)ss->username, (unsigned long long)(ss->id)); - } else { - snprintf(key,sizeof(key),"turn/user/%s/allocation/%018llu/traffic",(char*)ss->username, (unsigned long long)(ss->id)); - } - send_message_to_redis(e->rch, "publish", key, "rcvp=%lu, rcvb=%lu, sentp=%lu, sentb=%lu",(unsigned long)(ss->received_packets), (unsigned long)(ss->received_bytes),(unsigned long)(ss->sent_packets),(unsigned long)(ss->sent_bytes)); - if (ss->realm_options.name[0]) { - snprintf(key, sizeof(key), "turn/realm/%s/user/%s/allocation/%018llu/traffic/peer", ss->realm_options.name, (char*)ss->username, (unsigned long long)(ss->id)); - } - else { - snprintf(key, sizeof(key), "turn/user/%s/allocation/%018llu/traffic/peer", (char*)ss->username, (unsigned long long)(ss->id)); - } - send_message_to_redis(e->rch, "publish", key, "rcvp=%lu, rcvb=%lu, sentp=%lu, sentb=%lu", (unsigned long)(ss->peer_received_packets), (unsigned long)(ss->peer_received_bytes), (unsigned long)(ss->peer_sent_packets), (unsigned long)(ss->peer_sent_bytes)); - } + { + char key[1024]; + if (ss->realm_options.name[0]) { + snprintf(key, sizeof(key), "turn/realm/%s/user/%s/allocation/%018llu/traffic", ss->realm_options.name, + (char *)ss->username, (unsigned long long)(ss->id)); + } else { + snprintf(key, sizeof(key), "turn/user/%s/allocation/%018llu/traffic", (char *)ss->username, + (unsigned long long)(ss->id)); + } + send_message_to_redis(e->rch, "publish", key, "rcvp=%lu, rcvb=%lu, sentp=%lu, sentb=%lu", + (unsigned long)(ss->received_packets), (unsigned long)(ss->received_bytes), + (unsigned long)(ss->sent_packets), (unsigned long)(ss->sent_bytes)); + if (ss->realm_options.name[0]) { + snprintf(key, sizeof(key), "turn/realm/%s/user/%s/allocation/%018llu/traffic/peer", ss->realm_options.name, + (char *)ss->username, (unsigned long long)(ss->id)); + } else { + snprintf(key, sizeof(key), "turn/user/%s/allocation/%018llu/traffic/peer", (char *)ss->username, + (unsigned long long)(ss->id)); + } + send_message_to_redis(e->rch, "publish", key, "rcvp=%lu, rcvb=%lu, sentp=%lu, sentb=%lu", + (unsigned long)(ss->peer_received_packets), (unsigned long)(ss->peer_received_bytes), + (unsigned long)(ss->peer_sent_packets), (unsigned long)(ss->peer_sent_bytes)); + } #endif - ss->t_received_packets += ss->received_packets; - ss->t_received_bytes += ss->received_bytes; - ss->t_sent_packets += ss->sent_packets; - ss->t_sent_bytes += ss->sent_bytes; - ss->t_peer_received_packets += ss->peer_received_packets; - ss->t_peer_received_bytes += ss->peer_received_bytes; - ss->t_peer_sent_packets += ss->peer_sent_packets; - ss->t_peer_sent_bytes += ss->peer_sent_bytes; + ss->t_received_packets += ss->received_packets; + ss->t_received_bytes += ss->received_bytes; + ss->t_sent_packets += ss->sent_packets; + ss->t_sent_bytes += ss->sent_bytes; + ss->t_peer_received_packets += ss->peer_received_packets; + ss->t_peer_received_bytes += ss->peer_received_bytes; + ss->t_peer_sent_packets += ss->peer_sent_packets; + ss->t_peer_sent_bytes += ss->peer_sent_bytes; - { - turn_time_t ct = get_turn_server_time(server); - if(ct != ss->start_time) { - ct = ct - ss->start_time; - ss->received_rate = (uint32_t)(ss->t_received_bytes / ct); - ss->sent_rate = (uint32_t)(ss->t_sent_bytes / ct); - ss->total_rate = ss->received_rate + ss->sent_rate; - ss->peer_received_rate = (uint32_t)(ss->t_peer_received_bytes / ct); - ss->peer_sent_rate = (uint32_t)(ss->t_peer_sent_bytes / ct); - ss->peer_total_rate = ss->peer_received_rate + ss->peer_sent_rate; - } - } + { + turn_time_t ct = get_turn_server_time(server); + if (ct != ss->start_time) { + ct = ct - ss->start_time; + ss->received_rate = (uint32_t)(ss->t_received_bytes / ct); + ss->sent_rate = (uint32_t)(ss->t_sent_bytes / ct); + ss->total_rate = ss->received_rate + ss->sent_rate; + ss->peer_received_rate = (uint32_t)(ss->t_peer_received_bytes / ct); + ss->peer_sent_rate = (uint32_t)(ss->t_peer_sent_bytes / ct); + ss->peer_total_rate = ss->peer_received_rate + ss->peer_sent_rate; + } + } - report_turn_session_info(server,ss,force_invalid); + report_turn_session_info(server, ss, force_invalid); - ss->received_packets=0; - ss->received_bytes=0; - ss->sent_packets=0; - ss->sent_bytes=0; - ss->peer_received_packets = 0; - ss->peer_received_bytes = 0; - ss->peer_sent_packets = 0; - ss->peer_sent_bytes = 0; - } - } - } + ss->received_packets = 0; + ss->received_bytes = 0; + ss->sent_packets = 0; + ss->sent_bytes = 0; + ss->peer_received_packets = 0; + ss->peer_received_bytes = 0; + ss->peer_sent_packets = 0; + ss->peer_sent_bytes = 0; + } + } + } } /////////////// SSL /////////////////// - -const char* get_ioa_socket_tls_cipher(ioa_socket_handle s) -{ - if(s && (s->ssl)) - return SSL_get_cipher(s->ssl); - return ""; +const char *get_ioa_socket_tls_cipher(ioa_socket_handle s) { + if (s && (s->ssl)) + return SSL_get_cipher(s->ssl); + return ""; } -const char* get_ioa_socket_tls_method(ioa_socket_handle s) -{ - if(s && (s->ssl)) - return turn_get_ssl_method(s->ssl,"UNKNOWN"); - return ""; +const char *get_ioa_socket_tls_method(ioa_socket_handle s) { + if (s && (s->ssl)) + return turn_get_ssl_method(s->ssl, "UNKNOWN"); + return ""; } ///////////// Super Memory Region ////////////// -#define TURN_SM_SIZE (1024<<11) +#define TURN_SM_SIZE (1024 << 11) struct _super_memory { - TURN_MUTEX_DECLARE(mutex_sm) - char **super_memory; - size_t *sm_allocated; - size_t sm_total_sz; - size_t sm_chunk; - uint32_t id; + TURN_MUTEX_DECLARE(mutex_sm) + char **super_memory; + size_t *sm_allocated; + size_t sm_total_sz; + size_t sm_chunk; + uint32_t id; }; -static void init_super_memory_region(super_memory_t *r) -{ - if(r) { - memset(r, 0, sizeof(super_memory_t)); +static void init_super_memory_region(super_memory_t *r) { + if (r) { + memset(r, 0, sizeof(super_memory_t)); - r->super_memory = (char**)malloc(sizeof(char*)); - r->super_memory[0] = (char*)calloc(1, TURN_SM_SIZE); + r->super_memory = (char **)malloc(sizeof(char *)); + r->super_memory[0] = (char *)calloc(1, TURN_SM_SIZE); - r->sm_allocated = (size_t*)malloc(sizeof(size_t)); - r->sm_allocated[0] = 0; + r->sm_allocated = (size_t *)malloc(sizeof(size_t)); + r->sm_allocated[0] = 0; - r->sm_total_sz = TURN_SM_SIZE; - r->sm_chunk = 0; + r->sm_total_sz = TURN_SM_SIZE; + r->sm_chunk = 0; - while(r->id == 0) - r->id = (uint32_t)turn_random(); + while (r->id == 0) + r->id = (uint32_t)turn_random(); - TURN_MUTEX_INIT(&r->mutex_sm); - } + TURN_MUTEX_INIT(&r->mutex_sm); + } } -void init_super_memory(void) -{ - ; +void init_super_memory(void) { ; } + +super_memory_t *new_super_memory_region(void) { + super_memory_t *r = (super_memory_t *)malloc(sizeof(super_memory_t)); + init_super_memory_region(r); + return r; } -super_memory_t* new_super_memory_region(void) -{ - super_memory_t* r = (super_memory_t*)malloc(sizeof(super_memory_t)); - init_super_memory_region(r); - return r; +void *allocate_super_memory_region_func(super_memory_t *r, size_t size, const char *file, const char *func, int line) { + UNUSED_ARG(file); + UNUSED_ARG(func); + UNUSED_ARG(line); + + void *ret = NULL; + + if (!r) { + ret = calloc(1, size); + return ret; + } + + TURN_MUTEX_LOCK(&r->mutex_sm); + + size = ((size_t)((size + sizeof(void *)) / (sizeof(void *)))) * sizeof(void *); + + if (size >= TURN_SM_SIZE) { + + TURN_LOG_FUNC( + TURN_LOG_LEVEL_INFO, + "(%s:%s:%d): Size too large for super memory: region id = %u, chunk=%lu, total=%lu, allocated=%lu, want=%lu\n", + file, func, line, (unsigned int)r->id, (unsigned long)r->sm_chunk, (unsigned long)r->sm_total_sz, + (unsigned long)r->sm_allocated[r->sm_chunk], (unsigned long)size); + + } else { + + size_t i = 0; + char *region = NULL; + size_t *rsz = NULL; + for (i = 0; i <= r->sm_chunk; ++i) { + + size_t left = (size_t)r->sm_total_sz - r->sm_allocated[i]; + + if (left < size + sizeof(void *)) { + continue; + } else { + region = r->super_memory[i]; + rsz = r->sm_allocated + i; + break; + } + } + + if (!region) { + r->sm_chunk += 1; + r->super_memory = (char **)realloc(r->super_memory, (r->sm_chunk + 1) * sizeof(char *)); + r->super_memory[r->sm_chunk] = (char *)calloc(1, TURN_SM_SIZE); + r->sm_allocated = (size_t *)realloc(r->sm_allocated, (r->sm_chunk + 1) * sizeof(size_t)); + r->sm_allocated[r->sm_chunk] = 0; + region = r->super_memory[r->sm_chunk]; + rsz = r->sm_allocated + r->sm_chunk; + } + + { + char *ptr = region + *rsz; + + memset(ptr, 0, size); + + *rsz += size; + + ret = ptr; + } + } + + TURN_MUTEX_UNLOCK(&r->mutex_sm); + + if (!ret) { + ret = calloc(1, size); + } + + return ret; } -void* allocate_super_memory_region_func(super_memory_t *r, size_t size, const char* file, const char* func, int line) -{ - UNUSED_ARG(file); - UNUSED_ARG(func); - UNUSED_ARG(line); - - void *ret = NULL; - - if(!r) { - ret = calloc(1, size); - return ret; - } - - TURN_MUTEX_LOCK(&r->mutex_sm); - - size = ((size_t)((size+sizeof(void*))/(sizeof(void*)))) * sizeof(void*); - - if(size>=TURN_SM_SIZE) { - - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"(%s:%s:%d): Size too large for super memory: region id = %u, chunk=%lu, total=%lu, allocated=%lu, want=%lu\n",file,func,line,(unsigned int)r->id, (unsigned long)r->sm_chunk, (unsigned long)r->sm_total_sz, (unsigned long)r->sm_allocated[r->sm_chunk],(unsigned long)size); - - } else { - - size_t i = 0; - char *region = NULL; - size_t *rsz = NULL; - for(i=0;i<=r->sm_chunk;++i) { - - size_t left = (size_t)r->sm_total_sz - r->sm_allocated[i]; - - if(leftsuper_memory[i]; - rsz = r->sm_allocated + i; - break; - } - } - - if(!region) { - r->sm_chunk += 1; - r->super_memory = (char**)realloc(r->super_memory,(r->sm_chunk+1) * sizeof(char*)); - r->super_memory[r->sm_chunk] = (char*)calloc(1, TURN_SM_SIZE); - r->sm_allocated = (size_t*)realloc(r->sm_allocated,(r->sm_chunk+1) * sizeof(size_t)); - r->sm_allocated[r->sm_chunk] = 0; - region = r->super_memory[r->sm_chunk]; - rsz = r->sm_allocated + r->sm_chunk; - } - - { - char* ptr = region + *rsz; - - memset(ptr, 0, size); - - *rsz += size; - - ret = ptr; - } - } - - TURN_MUTEX_UNLOCK(&r->mutex_sm); - - if(!ret) { - ret = calloc(1, size); - } - - return ret; -} - -void* allocate_super_memory_engine_func(ioa_engine_handle e, size_t size, const char* file, const char* func, int line) -{ - if(e) - return allocate_super_memory_region_func(e->sm,size,file,func,line); - return allocate_super_memory_region_func(NULL,size,file,func,line); +void *allocate_super_memory_engine_func(ioa_engine_handle e, size_t size, const char *file, const char *func, + int line) { + if (e) + return allocate_super_memory_region_func(e->sm, size, file, func, line); + return allocate_super_memory_region_func(NULL, size, file, func, line); } ////////////////////////////////////////////////// diff --git a/src/apps/relay/ns_ioalib_impl.h b/src/apps/relay/ns_ioalib_impl.h index 4907002..39b984f 100644 --- a/src/apps/relay/ns_ioalib_impl.h +++ b/src/apps/relay/ns_ioalib_impl.h @@ -35,19 +35,19 @@ #ifndef __IOA_LIBIMPL__ #define __IOA_LIBIMPL__ -#include -#include #include +#include +#include #include #include "ns_turn_openssl.h" #include "ns_turn_ioalib.h" -#include "turn_ports.h" -#include "ns_turn_maps_rtcp.h" #include "ns_turn_maps.h" +#include "ns_turn_maps_rtcp.h" #include "ns_turn_server.h" +#include "turn_ports.h" #include "apputils.h" #include "stun_buffer.h" @@ -66,19 +66,19 @@ extern "C" { #define MAX_BUFFER_QUEUE_SIZE_PER_ENGINE (64) #define MAX_SOCKET_BUFFER_BACKLOG (16) -#define BUFFEREVENT_HIGH_WATERMARK (128<<10) -#define BUFFEREVENT_MAX_UDP_TO_TCP_WRITE (64<<9) -#define BUFFEREVENT_MAX_TCP_TO_TCP_WRITE (192<<10) +#define BUFFEREVENT_HIGH_WATERMARK (128 << 10) +#define BUFFEREVENT_MAX_UDP_TO_TCP_WRITE (64 << 9) +#define BUFFEREVENT_MAX_TCP_TO_TCP_WRITE (192 << 10) typedef struct _stun_buffer_list_elem { - struct _stun_buffer_list_elem *next; - stun_buffer buf; + struct _stun_buffer_list_elem *next; + stun_buffer buf; } stun_buffer_list_elem; typedef struct _stun_buffer_list { - stun_buffer_list_elem *head; - stun_buffer_list_elem *tail; - size_t tsz; + stun_buffer_list_elem *head; + stun_buffer_list_elem *tail; + size_t tsz; } stun_buffer_list; /* @@ -86,40 +86,40 @@ typedef struct _stun_buffer_list { */ struct cb_socket_message { - turnserver_id id; - tcp_connection_id connection_id; - stun_tid tid; - ioa_socket_handle s; - int message_integrity; - ioa_net_data nd; - int can_resume; + turnserver_id id; + tcp_connection_id connection_id; + stun_tid tid; + ioa_socket_handle s; + int message_integrity; + ioa_net_data nd; + int can_resume; }; struct cancelled_session_message { - turnsession_id id; + turnsession_id id; }; struct relay_server { - turnserver_id id; - super_memory_t* sm; - struct event_base* event_base; - struct bufferevent *in_buf; - struct bufferevent *out_buf; - struct bufferevent *auth_in_buf; - struct bufferevent *auth_out_buf; - ioa_engine_handle ioa_eng; - turn_turnserver server; - pthread_t thr; + turnserver_id id; + super_memory_t *sm; + struct event_base *event_base; + struct bufferevent *in_buf; + struct bufferevent *out_buf; + struct bufferevent *auth_in_buf; + struct bufferevent *auth_out_buf; + ioa_engine_handle ioa_eng; + turn_turnserver server; + pthread_t thr; }; struct message_to_relay { - MESSAGE_TO_RELAY_TYPE t; - struct relay_server *relay_server; - union { - struct socket_message sm; - struct cb_socket_message cb_sm; - struct cancelled_session_message csm; - } m; + MESSAGE_TO_RELAY_TYPE t; + struct relay_server *relay_server; + union { + struct socket_message sm; + struct cb_socket_message cb_sm; + struct cancelled_session_message csm; + } m; }; struct relay_server; @@ -133,20 +133,19 @@ typedef int (*ioa_engine_udp_event_handler)(relay_server_handle rs, struct messa #define PREDEF_TIMERS_NUM (14) extern const int predef_timer_intervals[PREDEF_TIMERS_NUM]; -struct _ioa_engine -{ +struct _ioa_engine { super_memory_t *sm; struct event_base *event_base; int deallocate_eb; int verbose; - turnipports* tp; + turnipports *tp; rtcp_map *map_rtcp; stun_buffer_list bufs; SSL_CTX *tls_ctx; SSL_CTX *dtls_ctx; turn_time_t jiffie; /* bandwidth check interval */ ioa_timer_handle timer_ev; - char cmsg[TURN_CMSG_SZ+1]; + char cmsg[TURN_CMSG_SZ + 1]; int predef_timer_intervals[PREDEF_TIMERS_NUM]; struct timeval predef_timers[PREDEF_TIMERS_NUM]; /* Relays */ @@ -161,71 +160,69 @@ struct _ioa_engine #define SOCKET_MAGIC (0xABACADEF) struct traffic_bytes { - band_limit_t jiffie_bytes_read; - band_limit_t jiffie_bytes_write; + band_limit_t jiffie_bytes_read; + band_limit_t jiffie_bytes_write; }; -struct _ioa_socket -{ - evutil_socket_t fd; - struct _ioa_socket *parent_s; - uint32_t magic; - ur_addr_map *sockets_container; /* relay container for UDP sockets */ - struct bufferevent *bev; - ioa_network_buffer_handle defer_nbh; - int family; - SOCKET_TYPE st; - SOCKET_APP_TYPE sat; - SSL* ssl; - uint32_t ssl_renegs; - int in_write; - int bound; - int local_addr_known; - ioa_addr local_addr; - int connected; - ioa_addr remote_addr; - ioa_engine_handle e; - struct event *read_event; - ioa_net_event_handler read_cb; - void *read_ctx; - int done; - ts_ur_super_session* session; - int current_df_relay_flag; - /* RFC6156: if IPv6 is involved, do not use DF: */ - int do_not_use_df; - int tobeclosed; - int broken; - int default_ttl; - int current_ttl; - int default_tos; - int current_tos; - stun_buffer_list bufs; - turn_time_t jiffie; /* bandwidth check interval */ - struct traffic_bytes data_traffic; - struct traffic_bytes control_traffic; - /* RFC 6062 ==>> */ - //Connection session: - tcp_connection *sub_session; - //Connect: - struct bufferevent *conn_bev; - connect_cb conn_cb; - void *conn_arg; - //Accept: - struct evconnlistener *list_ev; - accept_cb acb; - void *acbarg; - /* <<== RFC 6062 */ - void *special_session; - size_t special_session_size; +struct _ioa_socket { + evutil_socket_t fd; + struct _ioa_socket *parent_s; + uint32_t magic; + ur_addr_map *sockets_container; /* relay container for UDP sockets */ + struct bufferevent *bev; + ioa_network_buffer_handle defer_nbh; + int family; + SOCKET_TYPE st; + SOCKET_APP_TYPE sat; + SSL *ssl; + uint32_t ssl_renegs; + int in_write; + int bound; + int local_addr_known; + ioa_addr local_addr; + int connected; + ioa_addr remote_addr; + ioa_engine_handle e; + struct event *read_event; + ioa_net_event_handler read_cb; + void *read_ctx; + int done; + ts_ur_super_session *session; + int current_df_relay_flag; + /* RFC6156: if IPv6 is involved, do not use DF: */ + int do_not_use_df; + int tobeclosed; + int broken; + int default_ttl; + int current_ttl; + int default_tos; + int current_tos; + stun_buffer_list bufs; + turn_time_t jiffie; /* bandwidth check interval */ + struct traffic_bytes data_traffic; + struct traffic_bytes control_traffic; + /* RFC 6062 ==>> */ + // Connection session: + tcp_connection *sub_session; + // Connect: + struct bufferevent *conn_bev; + connect_cb conn_cb; + void *conn_arg; + // Accept: + struct evconnlistener *list_ev; + accept_cb acb; + void *acbarg; + /* <<== RFC 6062 */ + void *special_session; + size_t special_session_size; }; -typedef struct _timer_event -{ - struct event *ev; - ioa_engine_handle e; - ioa_timer_event_handler cb; - void *ctx; - char* txt; +typedef struct _timer_event { + struct event *ev; + ioa_engine_handle e; + ioa_timer_event_handler cb; + void *ctx; + char *txt; } timer_event; /////////////////////////////////// @@ -233,24 +230,26 @@ typedef struct _timer_event /* realm */ void create_default_realm(void); -int get_realm_data(char* name, realm_params_t* rp); +int get_realm_data(char *name, realm_params_t *rp); /* engine handling */ -ioa_engine_handle create_ioa_engine(super_memory_t *sm, - struct event_base *eb, turnipports* tp, - const char* relay_if, - size_t relays_number, char **relay_addrs, int default_relays, - int verbose +ioa_engine_handle create_ioa_engine(super_memory_t *sm, struct event_base *eb, turnipports *tp, const char *relay_if, + size_t relays_number, char **relay_addrs, int default_relays, int verbose #if !defined(TURN_NO_HIREDIS) - ,redis_stats_db_t* redis_stats_db + , + redis_stats_db_t *redis_stats_db #endif - ); +); void ioa_engine_set_rtcp_map(ioa_engine_handle e, rtcp_map *rtcpmap); -ioa_socket_handle create_ioa_socket_from_fd(ioa_engine_handle e, ioa_socket_raw fd, ioa_socket_handle parent_s, SOCKET_TYPE st, SOCKET_APP_TYPE sat, const ioa_addr *remote_addr, const ioa_addr *local_addr); -ioa_socket_handle create_ioa_socket_from_ssl(ioa_engine_handle e, ioa_socket_handle parent_s, SSL* ssl, SOCKET_TYPE st, SOCKET_APP_TYPE sat, const ioa_addr *remote_addr, const ioa_addr *local_addr); +ioa_socket_handle create_ioa_socket_from_fd(ioa_engine_handle e, ioa_socket_raw fd, ioa_socket_handle parent_s, + SOCKET_TYPE st, SOCKET_APP_TYPE sat, const ioa_addr *remote_addr, + const ioa_addr *local_addr); +ioa_socket_handle create_ioa_socket_from_ssl(ioa_engine_handle e, ioa_socket_handle parent_s, SSL *ssl, SOCKET_TYPE st, + SOCKET_APP_TYPE sat, const ioa_addr *remote_addr, + const ioa_addr *local_addr); int get_a_local_relay(int family, ioa_addr *relay_addr); @@ -262,9 +261,10 @@ void delete_socket_from_map(ioa_socket_handle s); int is_connreset(void); int would_block(void); -int udp_send(ioa_socket_handle s, const ioa_addr* dest_addr, const char* buffer, int len); -int udp_recvfrom(evutil_socket_t fd, ioa_addr* orig_addr, const ioa_addr *like_addr, char* buffer, int buf_size, int *ttl, int *tos, char *ecmsg, int flags, uint32_t *errcode); -int ssl_read(evutil_socket_t fd, SSL* ssl, ioa_network_buffer_handle nbh, int verbose); +int udp_send(ioa_socket_handle s, const ioa_addr *dest_addr, const char *buffer, int len); +int udp_recvfrom(evutil_socket_t fd, ioa_addr *orig_addr, const ioa_addr *like_addr, char *buffer, int buf_size, + int *ttl, int *tos, char *ecmsg, int flags, uint32_t *errcode); +int ssl_read(evutil_socket_t fd, SSL *ssl, ioa_network_buffer_handle nbh, int verbose); int set_raw_socket_ttl_options(evutil_socket_t fd, int family); int set_raw_socket_tos_options(evutil_socket_t fd, int family); @@ -282,8 +282,9 @@ int ioa_socket_check_bandwidth(ioa_socket_handle s, ioa_network_buffer_handle nb ///////////////////////// SUPER MEMORY //////// -#define allocate_super_memory_engine(e,size) allocate_super_memory_engine_func(e, size, __FILE__, __FUNCTION__, __LINE__) -void* allocate_super_memory_engine_func(ioa_engine_handle e, size_t size, const char* file, const char* func, int line); +#define allocate_super_memory_engine(e, size) \ + allocate_super_memory_engine_func(e, size, __FILE__, __FUNCTION__, __LINE__) +void *allocate_super_memory_engine_func(ioa_engine_handle e, size_t size, const char *file, const char *func, int line); ///////////////////////////////////////////////// diff --git a/src/apps/relay/ns_sm.h b/src/apps/relay/ns_sm.h index dfa366e..1539813 100644 --- a/src/apps/relay/ns_sm.h +++ b/src/apps/relay/ns_sm.h @@ -52,10 +52,12 @@ typedef struct _super_memory super_memory_t; void init_super_memory(void); -super_memory_t* new_super_memory_region(void); +super_memory_t *new_super_memory_region(void); -#define allocate_super_memory_region(region,size) allocate_super_memory_region_func(region, size, __FILE__, __FUNCTION__, __LINE__) -void* allocate_super_memory_region_func(super_memory_t *region, size_t size, const char* file, const char* func, int line); +#define allocate_super_memory_region(region, size) \ + allocate_super_memory_region_func(region, size, __FILE__, __FUNCTION__, __LINE__) +void *allocate_super_memory_region_func(super_memory_t *region, size_t size, const char *file, const char *func, + int line); ///////////////////////////////////////////////// diff --git a/src/apps/relay/prom_server.c b/src/apps/relay/prom_server.c index 55b88c1..a245f08 100644 --- a/src/apps/relay/prom_server.c +++ b/src/apps/relay/prom_server.c @@ -1,10 +1,9 @@ -#include "mainrelay.h" #include "prom_server.h" +#include "mainrelay.h" #include "ns_turn_utils.h" #if !defined(TURN_NO_PROMETHEUS) - prom_counter_t *turn_traffic_rcvp; prom_counter_t *turn_traffic_rcvb; prom_counter_t *turn_traffic_sentp; @@ -27,9 +26,8 @@ prom_counter_t *turn_total_traffic_peer_sentb; prom_gauge_t *turn_total_allocations; - -void start_prometheus_server(void){ - if (turn_params.prometheus == 0){ +void start_prometheus_server(void) { + if (turn_params.prometheus == 0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "prometheus collector disabled, not started\n"); return; } @@ -44,45 +42,62 @@ void start_prometheus_server(void){ } // Create traffic counter metrics - turn_traffic_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_rcvp", "Represents finished sessions received packets", nlabels, label)); - turn_traffic_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_rcvb", "Represents finished sessions received bytes", nlabels, label)); - turn_traffic_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_sentp", "Represents finished sessions sent packets", nlabels, label)); - turn_traffic_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_sentb", "Represents finished sessions sent bytes", nlabels, label)); + turn_traffic_rcvp = prom_collector_registry_must_register_metric( + prom_counter_new("turn_traffic_rcvp", "Represents finished sessions received packets", nlabels, label)); + turn_traffic_rcvb = prom_collector_registry_must_register_metric( + prom_counter_new("turn_traffic_rcvb", "Represents finished sessions received bytes", nlabels, label)); + turn_traffic_sentp = prom_collector_registry_must_register_metric( + prom_counter_new("turn_traffic_sentp", "Represents finished sessions sent packets", nlabels, label)); + turn_traffic_sentb = prom_collector_registry_must_register_metric( + prom_counter_new("turn_traffic_sentb", "Represents finished sessions sent bytes", nlabels, label)); // Create finished sessions traffic for peers counter metrics - turn_traffic_peer_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_rcvp", "Represents finished sessions peer received packets", nlabels, label)); - turn_traffic_peer_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_rcvb", "Represents finished sessions peer received bytes", nlabels, label)); - turn_traffic_peer_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_sentp", "Represents finished sessions peer sent packets", nlabels, label)); - turn_traffic_peer_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_sentb", "Represents finished sessions peer sent bytes", nlabels, label)); + turn_traffic_peer_rcvp = prom_collector_registry_must_register_metric( + prom_counter_new("turn_traffic_peer_rcvp", "Represents finished sessions peer received packets", nlabels, label)); + turn_traffic_peer_rcvb = prom_collector_registry_must_register_metric( + prom_counter_new("turn_traffic_peer_rcvb", "Represents finished sessions peer received bytes", nlabels, label)); + turn_traffic_peer_sentp = prom_collector_registry_must_register_metric( + prom_counter_new("turn_traffic_peer_sentp", "Represents finished sessions peer sent packets", nlabels, label)); + turn_traffic_peer_sentb = prom_collector_registry_must_register_metric( + prom_counter_new("turn_traffic_peer_sentb", "Represents finished sessions peer sent bytes", nlabels, label)); // Create total finished traffic counter metrics - turn_total_traffic_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_rcvp", "Represents total finished sessions received packets", 0, NULL)); - turn_total_traffic_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_rcvb", "Represents total finished sessions received bytes", 0, NULL)); - turn_total_traffic_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_sentp", "Represents total finished sessions sent packets", 0, NULL)); - turn_total_traffic_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_sentb", "Represents total finished sessions sent bytes", 0, NULL)); + turn_total_traffic_rcvp = prom_collector_registry_must_register_metric( + prom_counter_new("turn_total_traffic_rcvp", "Represents total finished sessions received packets", 0, NULL)); + turn_total_traffic_rcvb = prom_collector_registry_must_register_metric( + prom_counter_new("turn_total_traffic_rcvb", "Represents total finished sessions received bytes", 0, NULL)); + turn_total_traffic_sentp = prom_collector_registry_must_register_metric( + prom_counter_new("turn_total_traffic_sentp", "Represents total finished sessions sent packets", 0, NULL)); + turn_total_traffic_sentb = prom_collector_registry_must_register_metric( + prom_counter_new("turn_total_traffic_sentb", "Represents total finished sessions sent bytes", 0, NULL)); // Create total finished sessions traffic for peers counter metrics - turn_total_traffic_peer_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_peer_rcvp", "Represents total finished sessions peer received packets", 0, NULL)); - turn_total_traffic_peer_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_peer_rcvb", "Represents total finished sessions peer received bytes", 0, NULL)); - turn_total_traffic_peer_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_peer_sentp", "Represents total finished sessions peer sent packets", 0, NULL)); - turn_total_traffic_peer_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_peer_sentb", "Represents total finished sessions peer sent bytes", 0, NULL)); + turn_total_traffic_peer_rcvp = prom_collector_registry_must_register_metric(prom_counter_new( + "turn_total_traffic_peer_rcvp", "Represents total finished sessions peer received packets", 0, NULL)); + turn_total_traffic_peer_rcvb = prom_collector_registry_must_register_metric(prom_counter_new( + "turn_total_traffic_peer_rcvb", "Represents total finished sessions peer received bytes", 0, NULL)); + turn_total_traffic_peer_sentp = prom_collector_registry_must_register_metric(prom_counter_new( + "turn_total_traffic_peer_sentp", "Represents total finished sessions peer sent packets", 0, NULL)); + turn_total_traffic_peer_sentb = prom_collector_registry_must_register_metric( + prom_counter_new("turn_total_traffic_peer_sentb", "Represents total finished sessions peer sent bytes", 0, NULL)); // Create total allocations number gauge metric - turn_total_allocations = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_allocations", "Represents current allocations number", 1, (const char*[]) {"type"})); + turn_total_allocations = prom_collector_registry_must_register_metric( + prom_gauge_new("turn_total_allocations", "Represents current allocations number", 1, (const char *[]){"type"})); promhttp_set_active_collector_registry(NULL); - unsigned int flags = MHD_USE_DUAL_STACK + unsigned int flags = MHD_USE_DUAL_STACK #if MHD_USE_ERROR_LOG - | MHD_USE_ERROR_LOG + | MHD_USE_ERROR_LOG #endif - ; + ; if (MHD_is_feature_supported(MHD_FEATURE_EPOLL)) { - #if MHD_USE_EPOLL_INTERNAL_THREAD +#if MHD_USE_EPOLL_INTERNAL_THREAD flags |= MHD_USE_EPOLL_INTERNAL_THREAD; - #else - flags |= MHD_USE_SELECT_INTERNALLY; //ubuntu 16.04 - #endif +#else + flags |= MHD_USE_SELECT_INTERNALLY; // ubuntu 16.04 +#endif } else { flags |= MHD_USE_SELECT_INTERNALLY; } @@ -97,15 +112,16 @@ void start_prometheus_server(void){ return; } -void prom_set_finished_traffic(const char* realm, const char* user, unsigned long rsvp, unsigned long rsvb, unsigned long sentp, unsigned long sentb, bool peer){ - if (turn_params.prometheus == 1){ +void prom_set_finished_traffic(const char *realm, const char *user, unsigned long rsvp, unsigned long rsvb, + unsigned long sentp, unsigned long sentb, bool peer) { + if (turn_params.prometheus == 1) { const char *label[] = {realm, NULL}; - if (turn_params.prometheus_username_labels){ + if (turn_params.prometheus_username_labels) { label[1] = user; } - if (peer){ + if (peer) { prom_counter_add(turn_traffic_peer_rcvp, rsvp, label); prom_counter_add(turn_traffic_peer_rcvb, rsvb, label); prom_counter_add(turn_traffic_peer_sentp, sentp, label); @@ -130,22 +146,22 @@ void prom_set_finished_traffic(const char* realm, const char* user, unsigned lon } void prom_inc_allocation(SOCKET_TYPE type) { - if (turn_params.prometheus == 1){ - prom_gauge_inc(turn_total_allocations, (const char*[]) {socket_type_name(type)}); + if (turn_params.prometheus == 1) { + prom_gauge_inc(turn_total_allocations, (const char *[]){socket_type_name(type)}); } } void prom_dec_allocation(SOCKET_TYPE type) { - if (turn_params.prometheus == 1){ - prom_gauge_dec(turn_total_allocations, (const char*[]) {socket_type_name(type)}); + if (turn_params.prometheus == 1) { + prom_gauge_dec(turn_total_allocations, (const char *[]){socket_type_name(type)}); } } #else -void start_prometheus_server(void){ - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "turnserver compiled without prometheus support\n"); - return; +void start_prometheus_server(void) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "turnserver compiled without prometheus support\n"); + return; } #endif /* TURN_NO_PROMETHEUS */ diff --git a/src/apps/relay/prom_server.h b/src/apps/relay/prom_server.h index ae93b84..c16fa10 100644 --- a/src/apps/relay/prom_server.h +++ b/src/apps/relay/prom_server.h @@ -7,10 +7,12 @@ #if !defined(TURN_NO_PROMETHEUS) #include +#include #include #include #include -#include + +#include "ns_turn_ioalib.h" #ifdef __cplusplus extern "C" { @@ -54,10 +56,10 @@ extern prom_gauge_t *turn_total_allocations_number; extern "C" { #endif - void start_prometheus_server(void); -void prom_set_finished_traffic(const char* realm, const char* user, unsigned long rsvp, unsigned long rsvb, unsigned long sentp, unsigned long sentb, bool peer); +void prom_set_finished_traffic(const char *realm, const char *user, unsigned long rsvp, unsigned long rsvb, + unsigned long sentp, unsigned long sentb, bool peer); void prom_inc_allocation(SOCKET_TYPE type); void prom_dec_allocation(SOCKET_TYPE type); @@ -71,4 +73,4 @@ void start_prometheus_server(void); } #endif /* __clplusplus */ -#endif /* __PROM_SERVER_H__ */ \ No newline at end of file +#endif /* __PROM_SERVER_H__ */ diff --git a/src/apps/relay/tls_listener.c b/src/apps/relay/tls_listener.c index e784cbb..8af89d3 100644 --- a/src/apps/relay/tls_listener.c +++ b/src/apps/relay/tls_listener.c @@ -33,277 +33,257 @@ #include "ns_turn_utils.h" -#include "tls_listener.h" #include "ns_ioalib_impl.h" +#include "tls_listener.h" #include /////////////////////////////////////////////////// -#define FUNCSTART if(server && eve(server->verbose)) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s:%d:start\n",__FUNCTION__,__LINE__) -#define FUNCEND if(server && eve(server->verbose)) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s:%d:end\n",__FUNCTION__,__LINE__) +#define FUNCSTART \ + if (server && eve(server->verbose)) \ + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s:%d:start\n", __FUNCTION__, __LINE__) +#define FUNCEND \ + if (server && eve(server->verbose)) \ + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s:%d:end\n", __FUNCTION__, __LINE__) -struct tls_listener_relay_server_info -{ - char ifname[1025]; - ioa_addr addr; - ioa_engine_handle e; - int verbose; - struct evconnlistener *l; - struct evconnlistener *sctp_l; - struct message_to_relay sm; - ioa_engine_new_connection_event_handler connect_cb; - struct relay_server *relay_server; +struct tls_listener_relay_server_info { + char ifname[1025]; + ioa_addr addr; + ioa_engine_handle e; + int verbose; + struct evconnlistener *l; + struct evconnlistener *sctp_l; + struct message_to_relay sm; + ioa_engine_new_connection_event_handler connect_cb; + struct relay_server *relay_server; }; /////////////// io handlers /////////////////// -static void server_input_handler(struct evconnlistener *l, evutil_socket_t fd, - struct sockaddr *sa, int socklen, void *arg) -{ +static void server_input_handler(struct evconnlistener *l, evutil_socket_t fd, struct sockaddr *sa, int socklen, + void *arg) { - UNUSED_ARG(l); + UNUSED_ARG(l); - tls_listener_relay_server_type * server = (tls_listener_relay_server_type*) arg; + tls_listener_relay_server_type *server = (tls_listener_relay_server_type *)arg; - if (!server) - { - return; - } + if (!server) { + return; + } - if(!(server->connect_cb)) { - socket_closesocket(fd); - return; - } + if (!(server->connect_cb)) { + socket_closesocket(fd); + return; + } - FUNCSTART; + FUNCSTART; - memcpy(&(server->sm.m.sm.nd.src_addr),sa,socklen); + memcpy(&(server->sm.m.sm.nd.src_addr), sa, socklen); - addr_debug_print(server->verbose, &(server->sm.m.sm.nd.src_addr),"tcp or tls connected to"); + addr_debug_print(server->verbose, &(server->sm.m.sm.nd.src_addr), "tcp or tls connected to"); - SOCKET_TYPE st = TENTATIVE_TCP_SOCKET; + SOCKET_TYPE st = TENTATIVE_TCP_SOCKET; - if(turn_params.tcp_use_proxy) - st = TCP_SOCKET_PROXY; - else if(turn_params.no_tls) - st = TCP_SOCKET; - else if(turn_params.no_tcp) - st = TLS_SOCKET; + if (turn_params.tcp_use_proxy) + st = TCP_SOCKET_PROXY; + else if (turn_params.no_tls) + st = TCP_SOCKET; + else if (turn_params.no_tcp) + st = TLS_SOCKET; - ioa_socket_handle ioas = - create_ioa_socket_from_fd( - server->e, - fd, - NULL, - st, - CLIENT_SOCKET, - &(server->sm.m.sm.nd.src_addr), - &(server->addr)); + ioa_socket_handle ioas = create_ioa_socket_from_fd(server->e, fd, NULL, st, CLIENT_SOCKET, + &(server->sm.m.sm.nd.src_addr), &(server->addr)); - if (ioas) { + if (ioas) { - server->sm.m.sm.nd.recv_ttl = TTL_IGNORE; - server->sm.m.sm.nd.recv_tos = TOS_IGNORE; - server->sm.m.sm.nd.nbh = NULL; - server->sm.m.sm.s = ioas; - server->sm.m.sm.can_resume = 1; - server->sm.relay_server = server->relay_server; + server->sm.m.sm.nd.recv_ttl = TTL_IGNORE; + server->sm.m.sm.nd.recv_tos = TOS_IGNORE; + server->sm.m.sm.nd.nbh = NULL; + server->sm.m.sm.s = ioas; + server->sm.m.sm.can_resume = 1; + server->sm.relay_server = server->relay_server; - int rc = server->connect_cb(server->e, &(server->sm)); + int rc = server->connect_cb(server->e, &(server->sm)); - if (rc < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Cannot create tcp or tls session\n"); - } - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Cannot create ioa_socket from FD\n"); - socket_closesocket(fd); - } + if (rc < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot create tcp or tls session\n"); + } + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot create ioa_socket from FD\n"); + socket_closesocket(fd); + } - FUNCEND ; + FUNCEND; } #if !defined(TURN_NO_SCTP) -static void sctp_server_input_handler(struct evconnlistener *l, evutil_socket_t fd, - struct sockaddr *sa, int socklen, void *arg) -{ +static void sctp_server_input_handler(struct evconnlistener *l, evutil_socket_t fd, struct sockaddr *sa, int socklen, + void *arg) { - UNUSED_ARG(l); + UNUSED_ARG(l); - tls_listener_relay_server_type * server = (tls_listener_relay_server_type*) arg; + tls_listener_relay_server_type *server = (tls_listener_relay_server_type *)arg; - if (!server) - { - return; - } + if (!server) { + return; + } - if(!(server->connect_cb)) { - socket_closesocket(fd); - return; - } + if (!(server->connect_cb)) { + socket_closesocket(fd); + return; + } - FUNCSTART; + FUNCSTART; - memcpy(&(server->sm.m.sm.nd.src_addr),sa,socklen); + memcpy(&(server->sm.m.sm.nd.src_addr), sa, socklen); - addr_debug_print(server->verbose, &(server->sm.m.sm.nd.src_addr),"sctp or tls/sctp connected to"); + addr_debug_print(server->verbose, &(server->sm.m.sm.nd.src_addr), "sctp or tls/sctp connected to"); - SOCKET_TYPE st = TENTATIVE_SCTP_SOCKET; + SOCKET_TYPE st = TENTATIVE_SCTP_SOCKET; - if(turn_params.no_tls) - st = SCTP_SOCKET; - else if(turn_params.no_tcp) - st = TLS_SCTP_SOCKET; + if (turn_params.no_tls) + st = SCTP_SOCKET; + else if (turn_params.no_tcp) + st = TLS_SCTP_SOCKET; - ioa_socket_handle ioas = - create_ioa_socket_from_fd( - server->e, - fd, - NULL, - st, - CLIENT_SOCKET, - &(server->sm.m.sm.nd.src_addr), - &(server->addr)); + ioa_socket_handle ioas = create_ioa_socket_from_fd(server->e, fd, NULL, st, CLIENT_SOCKET, + &(server->sm.m.sm.nd.src_addr), &(server->addr)); - if (ioas) { + if (ioas) { - server->sm.m.sm.nd.recv_ttl = TTL_IGNORE; - server->sm.m.sm.nd.recv_tos = TOS_IGNORE; - server->sm.m.sm.nd.nbh = NULL; - server->sm.m.sm.s = ioas; - server->sm.m.sm.can_resume = 1; - server->sm.relay_server = server->relay_server; + server->sm.m.sm.nd.recv_ttl = TTL_IGNORE; + server->sm.m.sm.nd.recv_tos = TOS_IGNORE; + server->sm.m.sm.nd.nbh = NULL; + server->sm.m.sm.s = ioas; + server->sm.m.sm.can_resume = 1; + server->sm.relay_server = server->relay_server; - int rc = server->connect_cb(server->e, &(server->sm)); + int rc = server->connect_cb(server->e, &(server->sm)); - if (rc < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Cannot create sctp or tls/sctp session\n"); - } - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Cannot create ioa_socket from FD\n"); - socket_closesocket(fd); - } + if (rc < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot create sctp or tls/sctp session\n"); + } + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot create ioa_socket from FD\n"); + socket_closesocket(fd); + } - FUNCEND ; + FUNCEND; } #endif ///////////////////// operations ////////////////////////// -static int create_server_listener(tls_listener_relay_server_type* server) { +static int create_server_listener(tls_listener_relay_server_type *server) { FUNCSTART; - if(!server) return -1; + if (!server) + return -1; evutil_socket_t tls_listen_fd = -1; tls_listen_fd = socket(server->addr.ss.sa_family, CLIENT_STREAM_SOCKET_TYPE, CLIENT_STREAM_SOCKET_PROTOCOL); if (tls_listen_fd < 0) { - perror("socket"); - return -1; + perror("socket"); + return -1; } - if(sock_bind_to_device(tls_listen_fd, (unsigned char*)server->ifname)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind listener socket to device %s\n",server->ifname); + if (sock_bind_to_device(tls_listen_fd, (unsigned char *)server->ifname) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Cannot bind listener socket to device %s\n", server->ifname); } { - const int max_binding_time = 60; - int addr_bind_cycle = 0; - retry_addr_bind: + const int max_binding_time = 60; + int addr_bind_cycle = 0; + retry_addr_bind: - if(addr_bind(tls_listen_fd,&server->addr,1,1,TCP_SOCKET)<0) { - perror("Cannot bind local socket to addr"); - char saddr[129]; - addr_to_string(&server->addr,(uint8_t*)saddr); - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"Cannot bind TLS/TCP listener socket to addr %s\n",saddr); - if(addr_bind_cycle++addr, 1, 1, TCP_SOCKET) < 0) { + perror("Cannot bind local socket to addr"); + char saddr[129]; + addr_to_string(&server->addr, (uint8_t *)saddr); + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Cannot bind TLS/TCP listener socket to addr %s\n", saddr); + if (addr_bind_cycle++ < max_binding_time) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Trying to bind TLS/TCP listener socket to addr %s, again...\n", saddr); + sleep(1); + goto retry_addr_bind; + } + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Fatal final failure: cannot bind TLS/TCP listener socket to addr %s\n", + saddr); + exit(-1); + } + } - socket_tcp_set_keepalive(tls_listen_fd,TCP_SOCKET); + socket_tcp_set_keepalive(tls_listen_fd, TCP_SOCKET); socket_set_nonblocking(tls_listen_fd); - server->l = evconnlistener_new(server->e->event_base, - server_input_handler, server, - LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, - 1024, tls_listen_fd); + server->l = evconnlistener_new(server->e->event_base, server_input_handler, server, + LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, 1024, tls_listen_fd); - if(!(server->l)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot create TLS listener\n"); - socket_closesocket(tls_listen_fd); - return -1; + if (!(server->l)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Cannot create TLS listener\n"); + socket_closesocket(tls_listen_fd); + return -1; } - if(!turn_params.no_tcp && !turn_params.no_tls) - addr_debug_print(server->verbose, &server->addr,"TLS/TCP listener opened on "); - else if(!turn_params.no_tls) - addr_debug_print(server->verbose, &server->addr,"TLS listener opened on "); - else if(!turn_params.no_tcp) - addr_debug_print(server->verbose, &server->addr,"TCP listener opened on "); + if (!turn_params.no_tcp && !turn_params.no_tls) + addr_debug_print(server->verbose, &server->addr, "TLS/TCP listener opened on "); + else if (!turn_params.no_tls) + addr_debug_print(server->verbose, &server->addr, "TLS listener opened on "); + else if (!turn_params.no_tcp) + addr_debug_print(server->verbose, &server->addr, "TCP listener opened on "); FUNCEND; - + return 0; } #if !defined(TURN_NO_SCTP) -static int sctp_create_server_listener(tls_listener_relay_server_type* server) { +static int sctp_create_server_listener(tls_listener_relay_server_type *server) { FUNCSTART; - if(!server) return -1; + if (!server) + return -1; evutil_socket_t tls_listen_fd = -1; tls_listen_fd = socket(server->addr.ss.sa_family, SCTP_CLIENT_STREAM_SOCKET_TYPE, SCTP_CLIENT_STREAM_SOCKET_PROTOCOL); if (tls_listen_fd < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot create SCTP socket listener\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot create SCTP socket listener\n"); return -1; } - if(sock_bind_to_device(tls_listen_fd, (unsigned char*)server->ifname)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind listener socket to device %s\n",server->ifname); + if (sock_bind_to_device(tls_listen_fd, (unsigned char *)server->ifname) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Cannot bind listener socket to device %s\n", server->ifname); } - if(addr_bind(tls_listen_fd,&server->addr,1,0,SCTP_SOCKET)<0) { - close(tls_listen_fd); - return -1; + if (addr_bind(tls_listen_fd, &server->addr, 1, 0, SCTP_SOCKET) < 0) { + close(tls_listen_fd); + return -1; } - socket_tcp_set_keepalive(tls_listen_fd,SCTP_SOCKET); + socket_tcp_set_keepalive(tls_listen_fd, SCTP_SOCKET); socket_set_nonblocking(tls_listen_fd); - server->sctp_l = evconnlistener_new(server->e->event_base, - sctp_server_input_handler, server, - LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, - 1024, tls_listen_fd); + server->sctp_l = evconnlistener_new(server->e->event_base, sctp_server_input_handler, server, + LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, 1024, tls_listen_fd); - if(!(server->sctp_l)) { - socket_closesocket(tls_listen_fd); - return -1; + if (!(server->sctp_l)) { + socket_closesocket(tls_listen_fd); + return -1; } if (!turn_params.no_tls) - addr_debug_print(server->verbose, &server->addr, "TLS/SCTP listener opened on "); + addr_debug_print(server->verbose, &server->addr, "TLS/SCTP listener opened on "); else - addr_debug_print(server->verbose, &server->addr, "SCTP listener opened on "); + addr_debug_print(server->verbose, &server->addr, "SCTP listener opened on "); FUNCEND; @@ -312,29 +292,26 @@ static int sctp_create_server_listener(tls_listener_relay_server_type* server) { #endif -static int init_server(tls_listener_relay_server_type* server, - const char* ifname, - const char *local_address, - int port, - int verbose, - ioa_engine_handle e, - ioa_engine_new_connection_event_handler send_socket, - struct relay_server *relay_server) { +static int init_server(tls_listener_relay_server_type *server, const char *ifname, const char *local_address, int port, + int verbose, ioa_engine_handle e, ioa_engine_new_connection_event_handler send_socket, + struct relay_server *relay_server) { - if(!server) return -1; + if (!server) + return -1; server->connect_cb = send_socket; server->relay_server = relay_server; - if(ifname) STRCPY(server->ifname,ifname); + if (ifname) + STRCPY(server->ifname, ifname); - if(make_ioa_addr((const uint8_t*)local_address, port, &server->addr)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot create a TCP/TLS listener for address: %s\n",local_address); - return -1; + if (make_ioa_addr((const uint8_t *)local_address, port, &server->addr) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot create a TCP/TLS listener for address: %s\n", local_address); + return -1; } - server->verbose=verbose; - + server->verbose = verbose; + server->e = e; #if !defined(TURN_NO_SCTP) @@ -346,23 +323,19 @@ static int init_server(tls_listener_relay_server_type* server, /////////////////////////////////////////////////////////// +tls_listener_relay_server_type *create_tls_listener_server(const char *ifname, const char *local_address, int port, + int verbose, ioa_engine_handle e, + ioa_engine_new_connection_event_handler send_socket, + struct relay_server *relay_server) { -tls_listener_relay_server_type* create_tls_listener_server(const char* ifname, - const char *local_address, int port, int verbose, - ioa_engine_handle e, - ioa_engine_new_connection_event_handler send_socket, - struct relay_server *relay_server) -{ + tls_listener_relay_server_type *server = + (tls_listener_relay_server_type *)allocate_super_memory_engine(e, sizeof(tls_listener_relay_server_type)); - tls_listener_relay_server_type* server = - (tls_listener_relay_server_type*) allocate_super_memory_engine(e,sizeof(tls_listener_relay_server_type)); - - if (init_server(server, ifname, local_address, port, verbose, e, - send_socket, relay_server) < 0) { - return NULL ; - } else { - return server; - } + if (init_server(server, ifname, local_address, port, verbose, e, send_socket, relay_server) < 0) { + return NULL; + } else { + return server; + } } ////////////////////////////////////////////////////////////////// diff --git a/src/apps/relay/tls_listener.h b/src/apps/relay/tls_listener.h index fda420a..7556d0a 100644 --- a/src/apps/relay/tls_listener.h +++ b/src/apps/relay/tls_listener.h @@ -48,11 +48,10 @@ typedef struct tls_listener_relay_server_info tls_listener_relay_server_type; /////////////////////////////////////////// -tls_listener_relay_server_type* create_tls_listener_server(const char* ifname, - const char *local_address, int port, int verbose, - ioa_engine_handle e, - ioa_engine_new_connection_event_handler send_socket, - struct relay_server *relay_server); +tls_listener_relay_server_type *create_tls_listener_server(const char *ifname, const char *local_address, int port, + int verbose, ioa_engine_handle e, + ioa_engine_new_connection_event_handler send_socket, + struct relay_server *relay_server); /////////////////////////////////////////// diff --git a/src/apps/relay/turn_admin_server.c b/src/apps/relay/turn_admin_server.c index bda9c45..403356b 100644 --- a/src/apps/relay/turn_admin_server.c +++ b/src/apps/relay/turn_admin_server.c @@ -28,8 +28,8 @@ * SUCH DAMAGE. */ -#include #include +#include #include #include @@ -55,21 +55,21 @@ #include "libtelnet.h" -#include #include +#include -#include #include -#include +#include #include +#include -#include "userdb.h" #include "mainrelay.h" +#include "userdb.h" #include "ns_turn_utils.h" -#include "ns_turn_server.h" #include "ns_turn_maps.h" +#include "ns_turn_server.h" #include "apputils.h" @@ -96,7 +96,6 @@ char cli_password[CLI_PASSWORD_LENGTH] = ""; int cli_max_output_sessions = DEFAULT_CLI_MAX_OUTPUT_SESSIONS; - int use_web_admin = 0; ioa_addr web_admin_addr; @@ -107,1401 +106,1358 @@ int web_admin_port = WEB_ADMIN_DEFAULT_PORT; /////////////////////////////// struct cli_session { - evutil_socket_t fd; - int auth_completed; - size_t cmds; - struct bufferevent *bev; - ioa_addr addr; - telnet_t *ts; - FILE* f; - char realm[STUN_MAX_REALM_SIZE+1]; - char origin[STUN_MAX_ORIGIN_SIZE+1]; - realm_params_t *rp; + evutil_socket_t fd; + int auth_completed; + size_t cmds; + struct bufferevent *bev; + ioa_addr addr; + telnet_t *ts; + FILE *f; + char realm[STUN_MAX_REALM_SIZE + 1]; + char origin[STUN_MAX_ORIGIN_SIZE + 1]; + realm_params_t *rp; }; /////////////////////////////// #define CLI_PASSWORD_TRY_NUMBER (5) -static const char *CLI_HELP_STR[] = - {"", - " ?, h, help - print this text", - "", - " quit, q, exit, bye - end CLI session", - "", - " stop, shutdown, halt - shutdown TURN Server", - "", - " pc - print configuration", - "", - " sr - set CLI session realm", - "", - " ur - unset CLI session realm", - "", - " so - set CLI session origin", - "", - " uo - unset CLI session origin", - "", - " tc - toggle a configuration parameter", - " (see pc command output for togglable param names)", - "", - " cc - change a configuration parameter", - " (see pc command output for changeable param names)", - "", - " ps [username] - print sessions, with optional exact user match", - "", - " psp - print sessions, with partial user string match", - "", - " psd - dump ps command output into file on the TURN server system", - "", - " pu [udp|tcp|dtls|tls]- print current users", - "", - " lr - log reset", - "", - " aas ip[:port} - add an alternate server reference", - " das ip[:port] - delete an alternate server reference", - " atas ip[:port] - add a TLS alternate server reference", - " dtas ip[:port] - delete a TLS alternate server reference", - "", - " cs - cancel session, forcefully", - "", - NULL}; +static const char *CLI_HELP_STR[] = {"", + " ?, h, help - print this text", + "", + " quit, q, exit, bye - end CLI session", + "", + " stop, shutdown, halt - shutdown TURN Server", + "", + " pc - print configuration", + "", + " sr - set CLI session realm", + "", + " ur - unset CLI session realm", + "", + " so - set CLI session origin", + "", + " uo - unset CLI session origin", + "", + " tc - toggle a configuration parameter", + " (see pc command output for togglable param names)", + "", + " cc - change a configuration parameter", + " (see pc command output for changeable param names)", + "", + " ps [username] - print sessions, with optional exact user match", + "", + " psp - print sessions, with partial user string match", + "", + " psd - dump ps command output into file on the TURN server system", + "", + " pu [udp|tcp|dtls|tls]- print current users", + "", + " lr - log reset", + "", + " aas ip[:port} - add an alternate server reference", + " das ip[:port] - delete an alternate server reference", + " atas ip[:port] - add a TLS alternate server reference", + " dtas ip[:port] - delete a TLS alternate server reference", + "", + " cs - cancel session, forcefully", + "", + NULL}; -static const char *CLI_GREETING_STR[] = { - "TURN Server", - TURN_SOFTWARE, - NULL}; +static const char *CLI_GREETING_STR[] = {"TURN Server", TURN_SOFTWARE, NULL}; static char CLI_CURSOR[] = "> "; static const telnet_telopt_t cli_telopts[] = { - { TELNET_TELOPT_ECHO, TELNET_WONT, TELNET_DONT }, - { TELNET_TELOPT_TTYPE, TELNET_WONT, TELNET_DONT }, - { TELNET_TELOPT_COMPRESS2, TELNET_WONT, TELNET_DONT }, - { TELNET_TELOPT_ZMP, TELNET_WONT, TELNET_DONT }, - { TELNET_TELOPT_MSSP, TELNET_WONT, TELNET_DONT }, - { TELNET_TELOPT_BINARY, TELNET_WONT, TELNET_DONT }, - { TELNET_TELOPT_NAWS, TELNET_WONT, TELNET_DONT }, - { -1, 0, 0 } - }; + {TELNET_TELOPT_ECHO, TELNET_WONT, TELNET_DONT}, {TELNET_TELOPT_TTYPE, TELNET_WONT, TELNET_DONT}, + {TELNET_TELOPT_COMPRESS2, TELNET_WONT, TELNET_DONT}, {TELNET_TELOPT_ZMP, TELNET_WONT, TELNET_DONT}, + {TELNET_TELOPT_MSSP, TELNET_WONT, TELNET_DONT}, {TELNET_TELOPT_BINARY, TELNET_WONT, TELNET_DONT}, + {TELNET_TELOPT_NAWS, TELNET_WONT, TELNET_DONT}, {-1, 0, 0}}; struct toggleable_command { - const char *cmd; - vintp data; + const char *cmd; + vintp data; }; -struct toggleable_command tcmds[] = { - {"stale-nonce",&turn_params.stale_nonce}, - {"stun-only",&turn_params.stun_only}, - {"no-stun",&turn_params.no_stun}, - {"secure-stun",&turn_params.secure_stun}, - {"no-udp-relay",&turn_params.no_udp_relay}, - {"no-tcp-relay",&turn_params.no_tcp_relay}, - {"no-multicast-peers",&turn_params.no_multicast_peers}, - {"allow-loopback-peers",&turn_params.allow_loopback_peers}, - {"mobility",&turn_params.mobility}, - {NULL,NULL} -}; +struct toggleable_command tcmds[] = {{"stale-nonce", &turn_params.stale_nonce}, + {"stun-only", &turn_params.stun_only}, + {"no-stun", &turn_params.no_stun}, + {"secure-stun", &turn_params.secure_stun}, + {"no-udp-relay", &turn_params.no_udp_relay}, + {"no-tcp-relay", &turn_params.no_tcp_relay}, + {"no-multicast-peers", &turn_params.no_multicast_peers}, + {"allow-loopback-peers", &turn_params.allow_loopback_peers}, + {"mobility", &turn_params.mobility}, + {NULL, NULL}}; /////////////////////////////// -static void myprintf(struct cli_session *cs, const char *format, ...) -{ - if(cs && format) { - va_list args; - va_start (args, format); - if(cs->f) { - vfprintf(cs->f, format, args); - } else { - telnet_vprintf(cs->ts, format, args); - } - va_end (args); - } +static void myprintf(struct cli_session *cs, const char *format, ...) { + if (cs && format) { + va_list args; + va_start(args, format); + if (cs->f) { + vfprintf(cs->f, format, args); + } else { + telnet_vprintf(cs->ts, format, args); + } + va_end(args); + } } -static void log_reset(struct cli_session* cs) -{ - if(cs) { - reset_rtpprintf(); - myprintf(cs," log reset done\n"); - } +static void log_reset(struct cli_session *cs) { + if (cs) { + reset_rtpprintf(); + myprintf(cs, " log reset done\n"); + } } -static void print_str_array(struct cli_session* cs, const char** sa) -{ - if(cs && sa) { - int i=0; - while(sa[i]) { - myprintf(cs,"%s\n",sa[i]); +static void print_str_array(struct cli_session *cs, const char **sa) { + if (cs && sa) { + int i = 0; + while (sa[i]) { + myprintf(cs, "%s\n", sa[i]); i++; } } } -static const char* get_flag(int val) -{ - if(val) - return "ON"; - return "OFF"; +static const char *get_flag(int val) { + if (val) + return "ON"; + return "OFF"; } -static void cli_print_flag(struct cli_session* cs, int flag, const char* name, int changeable) -{ - if(cs && cs->ts && name) { - const char *sc=""; - if(changeable) - sc=" (*)"; - myprintf(cs," %s: %s%s\n",name,get_flag(flag),sc); - } +static void cli_print_flag(struct cli_session *cs, int flag, const char *name, int changeable) { + if (cs && cs->ts && name) { + const char *sc = ""; + if (changeable) + sc = " (*)"; + myprintf(cs, " %s: %s%s\n", name, get_flag(flag), sc); + } } -static void cli_print_uint(struct cli_session* cs, unsigned long value, const char* name, int changeable) -{ - if(cs && cs->ts && name) { - const char *sc=""; - if(changeable==1) - sc=" (*)"; - else if(changeable==2) - sc=" (**)"; - myprintf(cs," %s: %lu%s\n",name,value,sc); - } +static void cli_print_uint(struct cli_session *cs, unsigned long value, const char *name, int changeable) { + if (cs && cs->ts && name) { + const char *sc = ""; + if (changeable == 1) + sc = " (*)"; + else if (changeable == 2) + sc = " (**)"; + myprintf(cs, " %s: %lu%s\n", name, value, sc); + } } -static void cli_print_str(struct cli_session* cs, const char *value, const char* name, int changeable) -{ - if(cs && cs->ts && name && value) { - if(value[0] == 0) - value="empty"; - const char *sc=""; - if(changeable==1) - sc=" (*)"; - else if(changeable==2) - sc=" (**)"; - myprintf(cs," %s: %s%s\n",name,value,sc); - } +static void cli_print_str(struct cli_session *cs, const char *value, const char *name, int changeable) { + if (cs && cs->ts && name && value) { + if (value[0] == 0) + value = "empty"; + const char *sc = ""; + if (changeable == 1) + sc = " (*)"; + else if (changeable == 2) + sc = " (**)"; + myprintf(cs, " %s: %s%s\n", name, value, sc); + } } -static void cli_print_addr(struct cli_session* cs, ioa_addr *value, int use_port, const char* name, int changeable) -{ - if(cs && cs->ts && name && value) { - const char *sc=""; - if(changeable==1) - sc=" (*)"; - else if(changeable==2) - sc=" (**)"; - char s[256]; - if(!use_port) - addr_to_string_no_port(value,(uint8_t*)s); - else - addr_to_string(value,(uint8_t*)s); - myprintf(cs," %s: %s%s\n",name,s,sc); - } +static void cli_print_addr(struct cli_session *cs, ioa_addr *value, int use_port, const char *name, int changeable) { + if (cs && cs->ts && name && value) { + const char *sc = ""; + if (changeable == 1) + sc = " (*)"; + else if (changeable == 2) + sc = " (**)"; + char s[256]; + if (!use_port) + addr_to_string_no_port(value, (uint8_t *)s); + else + addr_to_string(value, (uint8_t *)s); + myprintf(cs, " %s: %s%s\n", name, s, sc); + } } -static void cli_print_addr_list(struct cli_session* cs, turn_server_addrs_list_t *value, int use_port, const char* name, int changeable) -{ - if(cs && cs->ts && name && value && value->size && value->addrs) { - const char *sc=""; - if(changeable==1) - sc=" (*)"; - else if(changeable==2) - sc=" (**)"; - char s[256]; - size_t i; - for(i=0;isize;i++) { - if(!use_port) - addr_to_string_no_port(&(value->addrs[i]),(uint8_t*)s); - else - addr_to_string(&(value->addrs[i]),(uint8_t*)s); - myprintf(cs," %s: %s%s\n",name,s,sc); - } - } +static void cli_print_addr_list(struct cli_session *cs, turn_server_addrs_list_t *value, int use_port, const char *name, + int changeable) { + if (cs && cs->ts && name && value && value->size && value->addrs) { + const char *sc = ""; + if (changeable == 1) + sc = " (*)"; + else if (changeable == 2) + sc = " (**)"; + char s[256]; + size_t i; + for (i = 0; i < value->size; i++) { + if (!use_port) + addr_to_string_no_port(&(value->addrs[i]), (uint8_t *)s); + else + addr_to_string(&(value->addrs[i]), (uint8_t *)s); + myprintf(cs, " %s: %s%s\n", name, s, sc); + } + } } -static void cli_print_str_array(struct cli_session* cs, char **value, size_t sz, const char* name, int changeable) -{ - if(cs && cs->ts && name && value && sz) { - const char *sc=""; - if(changeable==1) - sc=" (*)"; - else if(changeable==2) - sc=" (**)"; - size_t i; - for(i=0;its && name && value && sz) { + const char *sc = ""; + if (changeable == 1) + sc = " (*)"; + else if (changeable == 2) + sc = " (**)"; + size_t i; + for (i = 0; i < sz; i++) { + if (value[i]) + myprintf(cs, " %s: %s%s\n", name, value[i], sc); + } + } } -static void cli_print_ip_range_list(struct cli_session* cs, ip_range_list_t *value, const char* name, int changeable) -{ - if(cs && cs->ts && name && value && value->ranges_number && value->rs) { - const char *sc=""; - if(changeable==1) - sc=" (*)"; - else if(changeable==2) - sc=" (**)"; - size_t i; - for(i=0;iranges_number;++i) { - if(value->rs[i].realm[0]) { - if(cs->realm[0] && strcmp(cs->realm,value->rs[i].realm)) { - continue; - } else { - myprintf(cs," %s: %s (%s)%s\n",name,value->rs[i].str,value->rs[i].realm,sc); - } - } else { - myprintf(cs," %s: %s%s\n",name,value->rs[i].str,sc); - } - } - } +static void cli_print_ip_range_list(struct cli_session *cs, ip_range_list_t *value, const char *name, int changeable) { + if (cs && cs->ts && name && value && value->ranges_number && value->rs) { + const char *sc = ""; + if (changeable == 1) + sc = " (*)"; + else if (changeable == 2) + sc = " (**)"; + size_t i; + for (i = 0; i < value->ranges_number; ++i) { + if (value->rs[i].realm[0]) { + if (cs->realm[0] && strcmp(cs->realm, value->rs[i].realm)) { + continue; + } else { + myprintf(cs, " %s: %s (%s)%s\n", name, value->rs[i].str, value->rs[i].realm, sc); + } + } else { + myprintf(cs, " %s: %s%s\n", name, value->rs[i].str, sc); + } + } + } } -static void toggle_cli_param(struct cli_session* cs, const char* pn) -{ - if(cs && cs->ts && pn) { +static void toggle_cli_param(struct cli_session *cs, const char *pn) { + if (cs && cs->ts && pn) { - int i=0; + int i = 0; - while(tcmds[i].cmd && tcmds[i].data) { - if(strcmp(tcmds[i].cmd,pn) == 0) { - *(tcmds[i].data) = !(*(tcmds[i].data)); - cli_print_flag(cs,*(tcmds[i].data),tcmds[i].cmd,0); - return; - } - ++i; - } + while (tcmds[i].cmd && tcmds[i].data) { + if (strcmp(tcmds[i].cmd, pn) == 0) { + *(tcmds[i].data) = !(*(tcmds[i].data)); + cli_print_flag(cs, *(tcmds[i].data), tcmds[i].cmd, 0); + return; + } + ++i; + } - myprintf(cs, "\n"); - myprintf(cs, " Error: unknown or constant parameter: %s.\n",pn); - myprintf(cs, " You can toggle only the following parameters:\n"); - myprintf(cs, "\n"); + myprintf(cs, "\n"); + myprintf(cs, " Error: unknown or constant parameter: %s.\n", pn); + myprintf(cs, " You can toggle only the following parameters:\n"); + myprintf(cs, "\n"); - i=0; + i = 0; - while(tcmds[i].cmd && tcmds[i].data) { - cli_print_flag(cs,*(tcmds[i].data),tcmds[i].cmd,0); - ++i; - } + while (tcmds[i].cmd && tcmds[i].data) { + cli_print_flag(cs, *(tcmds[i].data), tcmds[i].cmd, 0); + ++i; + } - myprintf(cs,"\n"); - } + myprintf(cs, "\n"); + } } -static void change_cli_param(struct cli_session* cs, const char* pn) -{ - if(cs && cs->ts && pn) { +static void change_cli_param(struct cli_session *cs, const char *pn) { + if (cs && cs->ts && pn) { - if(strstr(pn,"total-quota")==pn) { - turn_params.total_quota = atoi(pn+strlen("total-quota")); - cli_print_uint(cs,(unsigned long)turn_params.total_quota,"total-quota",2); - return; - } else if(strstr(pn,"user-quota")==pn) { - turn_params.user_quota = atoi(pn+strlen("user-quota")); - cli_print_uint(cs,(unsigned long)turn_params.user_quota,"user-quota",2); - return; - } else if(strstr(pn,"max-bps")==pn) { - set_max_bps((band_limit_t)strtoul(pn+strlen("max-bps"),NULL,10)); - cli_print_uint(cs,(unsigned long)get_max_bps(),"max-bps",2); - return; - } else if(strstr(pn,"bps-capacity")==pn) { - set_bps_capacity((band_limit_t)strtoul(pn+strlen("bps-capacity"),NULL,10)); - cli_print_uint(cs,(unsigned long)get_bps_capacity(),"bps-capacity",2); - return; - } else if(strstr(pn,"cli-max-output-sessions")==pn) { - cli_max_output_sessions = atoi(pn+strlen("cli-max-output-sessions")); - cli_print_uint(cs,(unsigned long)cli_max_output_sessions,"cli-max-output-sessions",2); - return; - } + if (strstr(pn, "total-quota") == pn) { + turn_params.total_quota = atoi(pn + strlen("total-quota")); + cli_print_uint(cs, (unsigned long)turn_params.total_quota, "total-quota", 2); + return; + } else if (strstr(pn, "user-quota") == pn) { + turn_params.user_quota = atoi(pn + strlen("user-quota")); + cli_print_uint(cs, (unsigned long)turn_params.user_quota, "user-quota", 2); + return; + } else if (strstr(pn, "max-bps") == pn) { + set_max_bps((band_limit_t)strtoul(pn + strlen("max-bps"), NULL, 10)); + cli_print_uint(cs, (unsigned long)get_max_bps(), "max-bps", 2); + return; + } else if (strstr(pn, "bps-capacity") == pn) { + set_bps_capacity((band_limit_t)strtoul(pn + strlen("bps-capacity"), NULL, 10)); + cli_print_uint(cs, (unsigned long)get_bps_capacity(), "bps-capacity", 2); + return; + } else if (strstr(pn, "cli-max-output-sessions") == pn) { + cli_max_output_sessions = atoi(pn + strlen("cli-max-output-sessions")); + cli_print_uint(cs, (unsigned long)cli_max_output_sessions, "cli-max-output-sessions", 2); + return; + } - myprintf(cs, "\n"); - myprintf(cs, " Error: unknown or constant parameter: %s.\n",pn); - myprintf(cs, "\n"); - } + myprintf(cs, "\n"); + myprintf(cs, " Error: unknown or constant parameter: %s.\n", pn); + myprintf(cs, "\n"); + } } struct ps_arg { - struct cli_session* cs; - size_t counter; - turn_time_t ct; - const char *username; - const char *pname; - int exact_match; - ur_string_map* users; - size_t *user_counters; - char **user_names; - size_t users_number; + struct cli_session *cs; + size_t counter; + turn_time_t ct; + const char *username; + const char *pname; + int exact_match; + ur_string_map *users; + size_t *user_counters; + char **user_names; + size_t users_number; }; -static int print_session(ur_map_key_type key, ur_map_value_type value, void *arg) -{ - if(key && value && arg) { - struct ps_arg *csarg = (struct ps_arg*)arg; - struct cli_session* cs = csarg->cs; - struct turn_session_info *tsi = (struct turn_session_info *)value; +static int print_session(ur_map_key_type key, ur_map_value_type value, void *arg) { + if (key && value && arg) { + struct ps_arg *csarg = (struct ps_arg *)arg; + struct cli_session *cs = csarg->cs; + struct turn_session_info *tsi = (struct turn_session_info *)value; - if(cs->realm[0] && strcmp(cs->realm,tsi->realm)) - return 0; + if (cs->realm[0] && strcmp(cs->realm, tsi->realm)) + return 0; - if(cs->origin[0] && strcmp(cs->origin,tsi->origin)) - return 0; + if (cs->origin[0] && strcmp(cs->origin, tsi->origin)) + return 0; - if(csarg->users) { + if (csarg->users) { - const char *pn=csarg->pname; - if(pn[0]) { - if(!strcmp(pn,"TLS") || !strcmp(pn,"tls") || !strcmp(pn,"Tls")) { - if((tsi->client_protocol != TLS_SOCKET)&&(tsi->client_protocol != TLS_SCTP_SOCKET)) - return 0; - } else if(!strcmp(pn,"DTLS") || !strcmp(pn,"dtls") || !strcmp(pn,"Dtls")) { - if(tsi->client_protocol != DTLS_SOCKET) - return 0; - } else if(!strcmp(pn,"TCP") || !strcmp(pn,"tcp") || !strcmp(pn,"Tcp")) { - if((tsi->client_protocol != TCP_SOCKET)&&(tsi->client_protocol != SCTP_SOCKET)) - return 0; - } else if(!strcmp(pn,"UDP") || !strcmp(pn,"udp") || !strcmp(pn,"Udp")) { - if(tsi->client_protocol != UDP_SOCKET) - return 0; - } else { - return 0; - } - } + const char *pn = csarg->pname; + if (pn[0]) { + if (!strcmp(pn, "TLS") || !strcmp(pn, "tls") || !strcmp(pn, "Tls")) { + if ((tsi->client_protocol != TLS_SOCKET) && (tsi->client_protocol != TLS_SCTP_SOCKET)) + return 0; + } else if (!strcmp(pn, "DTLS") || !strcmp(pn, "dtls") || !strcmp(pn, "Dtls")) { + if (tsi->client_protocol != DTLS_SOCKET) + return 0; + } else if (!strcmp(pn, "TCP") || !strcmp(pn, "tcp") || !strcmp(pn, "Tcp")) { + if ((tsi->client_protocol != TCP_SOCKET) && (tsi->client_protocol != SCTP_SOCKET)) + return 0; + } else if (!strcmp(pn, "UDP") || !strcmp(pn, "udp") || !strcmp(pn, "Udp")) { + if (tsi->client_protocol != UDP_SOCKET) + return 0; + } else { + return 0; + } + } - ur_string_map_value_type value; - if(!ur_string_map_get(csarg->users, (ur_string_map_key_type)(char*)tsi->username, &value)) { - value = (ur_string_map_value_type)csarg->users_number; - csarg->users_number += 1; - csarg->user_counters = (size_t*)realloc(csarg->user_counters, - csarg->users_number * sizeof(size_t)); - csarg->user_names = (char**)realloc(csarg->user_names, - csarg->users_number * sizeof(char*)); - csarg->user_names[(size_t)value] = strdup((char*)tsi->username); - csarg->user_counters[(size_t)value] = 0; - ur_string_map_put(csarg->users, (ur_string_map_key_type)(char*)tsi->username, value); - } - csarg->user_counters[(size_t)value] += 1; - } else { - if(csarg->username[0]) { - if(csarg->exact_match) { - if(strcmp((char*)tsi->username, csarg->username)) - return 0; - } else { - if(!strstr((char*)tsi->username, csarg->username)) - return 0; - } - } - if(cs->f || (unsigned long)csarg->counter<(unsigned long)cli_max_output_sessions) { - myprintf(cs, "\n"); - myprintf(cs," %lu) id=%018llu, user <%s>:\n", - (unsigned long)(csarg->counter+1), - (unsigned long long)tsi->id, - tsi->username); - if(tsi->realm[0]) - myprintf(cs," realm: %s\n",tsi->realm); - if(tsi->origin[0]) - myprintf(cs," origin: %s\n",tsi->origin); - if(turn_time_before(csarg->ct, tsi->start_time)) { - myprintf(cs," started: undefined time\n"); - } else { - myprintf(cs," started %lu secs ago\n",(unsigned long)(csarg->ct - tsi->start_time)); - } - if(turn_time_before(tsi->expiration_time,csarg->ct)) { - myprintf(cs," expired\n"); - } else { - myprintf(cs," expiring in %lu secs\n",(unsigned long)(tsi->expiration_time - csarg->ct)); - } - myprintf(cs," client protocol %s, relay protocol %s\n",socket_type_name(tsi->client_protocol),socket_type_name(tsi->peer_protocol)); - { - if(!tsi->local_addr_data.saddr[0]) - addr_to_string(&(tsi->local_addr_data.addr),(uint8_t*)tsi->local_addr_data.saddr); - if(!tsi->remote_addr_data.saddr[0]) - addr_to_string(&(tsi->remote_addr_data.addr),(uint8_t*)tsi->remote_addr_data.saddr); - if(!tsi->relay_addr_data_ipv4.saddr[0]) - addr_to_string(&(tsi->relay_addr_data_ipv4.addr),(uint8_t*)tsi->relay_addr_data_ipv4.saddr); - if(!tsi->relay_addr_data_ipv6.saddr[0]) - addr_to_string(&(tsi->relay_addr_data_ipv6.addr),(uint8_t*)tsi->relay_addr_data_ipv6.saddr); - myprintf(cs," client addr %s, server addr %s\n", - tsi->remote_addr_data.saddr, - tsi->local_addr_data.saddr); - if(tsi->relay_addr_data_ipv4.saddr[0]) { - myprintf(cs," relay addr %s\n", tsi->relay_addr_data_ipv4.saddr); - } - if(tsi->relay_addr_data_ipv6.saddr[0]) { - myprintf(cs," relay addr %s\n", tsi->relay_addr_data_ipv6.saddr); - } - } - myprintf(cs," fingerprints enforced: %s\n",get_flag(tsi->enforce_fingerprints)); - myprintf(cs," mobile: %s\n",get_flag(tsi->is_mobile)); - if(tsi->tls_method[0]) { - myprintf(cs," TLS method: %s\n",tsi->tls_method); - myprintf(cs," TLS cipher: %s\n",tsi->tls_cipher); - } - if(tsi->bps) - myprintf(cs," Max throughput: %lu bytes per second\n",(unsigned long)tsi->bps); - myprintf(cs," usage: rp=%lu, rb=%lu, sp=%lu, sb=%lu\n",(unsigned long)(tsi->received_packets), (unsigned long)(tsi->received_bytes),(unsigned long)(tsi->sent_packets),(unsigned long)(tsi->sent_bytes)); - myprintf(cs," rate: r=%lu, s=%lu, total=%lu (bytes per sec)\n",(unsigned long)(tsi->received_rate), (unsigned long)(tsi->sent_rate),(unsigned long)(tsi->total_rate)); - if(tsi->main_peers_size) { - myprintf(cs," peers:\n"); - size_t i; - for(i=0;imain_peers_size;++i) { - if(!(tsi->main_peers_data[i].saddr[0])) - addr_to_string(&(tsi->main_peers_data[i].addr),(uint8_t*)tsi->main_peers_data[i].saddr); - myprintf(cs," %s\n",tsi->main_peers_data[i].saddr); - } - if(tsi->extra_peers_size && tsi->extra_peers_data) { - for(i=0;iextra_peers_size;++i) { - if(!(tsi->extra_peers_data[i].saddr[0])) - addr_to_string(&(tsi->extra_peers_data[i].addr),(uint8_t*)tsi->extra_peers_data[i].saddr); - myprintf(cs," %s\n",tsi->extra_peers_data[i].saddr); - } - } - } - } - } + ur_string_map_value_type value; + if (!ur_string_map_get(csarg->users, (ur_string_map_key_type)(char *)tsi->username, &value)) { + value = (ur_string_map_value_type)csarg->users_number; + csarg->users_number += 1; + csarg->user_counters = (size_t *)realloc(csarg->user_counters, csarg->users_number * sizeof(size_t)); + csarg->user_names = (char **)realloc(csarg->user_names, csarg->users_number * sizeof(char *)); + csarg->user_names[(size_t)value] = strdup((char *)tsi->username); + csarg->user_counters[(size_t)value] = 0; + ur_string_map_put(csarg->users, (ur_string_map_key_type)(char *)tsi->username, value); + } + csarg->user_counters[(size_t)value] += 1; + } else { + if (csarg->username[0]) { + if (csarg->exact_match) { + if (strcmp((char *)tsi->username, csarg->username)) + return 0; + } else { + if (!strstr((char *)tsi->username, csarg->username)) + return 0; + } + } + if (cs->f || (unsigned long)csarg->counter < (unsigned long)cli_max_output_sessions) { + myprintf(cs, "\n"); + myprintf(cs, " %lu) id=%018llu, user <%s>:\n", (unsigned long)(csarg->counter + 1), + (unsigned long long)tsi->id, tsi->username); + if (tsi->realm[0]) + myprintf(cs, " realm: %s\n", tsi->realm); + if (tsi->origin[0]) + myprintf(cs, " origin: %s\n", tsi->origin); + if (turn_time_before(csarg->ct, tsi->start_time)) { + myprintf(cs, " started: undefined time\n"); + } else { + myprintf(cs, " started %lu secs ago\n", (unsigned long)(csarg->ct - tsi->start_time)); + } + if (turn_time_before(tsi->expiration_time, csarg->ct)) { + myprintf(cs, " expired\n"); + } else { + myprintf(cs, " expiring in %lu secs\n", (unsigned long)(tsi->expiration_time - csarg->ct)); + } + myprintf(cs, " client protocol %s, relay protocol %s\n", socket_type_name(tsi->client_protocol), + socket_type_name(tsi->peer_protocol)); + { + if (!tsi->local_addr_data.saddr[0]) + addr_to_string(&(tsi->local_addr_data.addr), (uint8_t *)tsi->local_addr_data.saddr); + if (!tsi->remote_addr_data.saddr[0]) + addr_to_string(&(tsi->remote_addr_data.addr), (uint8_t *)tsi->remote_addr_data.saddr); + if (!tsi->relay_addr_data_ipv4.saddr[0]) + addr_to_string(&(tsi->relay_addr_data_ipv4.addr), (uint8_t *)tsi->relay_addr_data_ipv4.saddr); + if (!tsi->relay_addr_data_ipv6.saddr[0]) + addr_to_string(&(tsi->relay_addr_data_ipv6.addr), (uint8_t *)tsi->relay_addr_data_ipv6.saddr); + myprintf(cs, " client addr %s, server addr %s\n", tsi->remote_addr_data.saddr, + tsi->local_addr_data.saddr); + if (tsi->relay_addr_data_ipv4.saddr[0]) { + myprintf(cs, " relay addr %s\n", tsi->relay_addr_data_ipv4.saddr); + } + if (tsi->relay_addr_data_ipv6.saddr[0]) { + myprintf(cs, " relay addr %s\n", tsi->relay_addr_data_ipv6.saddr); + } + } + myprintf(cs, " fingerprints enforced: %s\n", get_flag(tsi->enforce_fingerprints)); + myprintf(cs, " mobile: %s\n", get_flag(tsi->is_mobile)); + if (tsi->tls_method[0]) { + myprintf(cs, " TLS method: %s\n", tsi->tls_method); + myprintf(cs, " TLS cipher: %s\n", tsi->tls_cipher); + } + if (tsi->bps) + myprintf(cs, " Max throughput: %lu bytes per second\n", (unsigned long)tsi->bps); + myprintf(cs, " usage: rp=%lu, rb=%lu, sp=%lu, sb=%lu\n", (unsigned long)(tsi->received_packets), + (unsigned long)(tsi->received_bytes), (unsigned long)(tsi->sent_packets), + (unsigned long)(tsi->sent_bytes)); + myprintf(cs, " rate: r=%lu, s=%lu, total=%lu (bytes per sec)\n", (unsigned long)(tsi->received_rate), + (unsigned long)(tsi->sent_rate), (unsigned long)(tsi->total_rate)); + if (tsi->main_peers_size) { + myprintf(cs, " peers:\n"); + size_t i; + for (i = 0; i < tsi->main_peers_size; ++i) { + if (!(tsi->main_peers_data[i].saddr[0])) + addr_to_string(&(tsi->main_peers_data[i].addr), (uint8_t *)tsi->main_peers_data[i].saddr); + myprintf(cs, " %s\n", tsi->main_peers_data[i].saddr); + } + if (tsi->extra_peers_size && tsi->extra_peers_data) { + for (i = 0; i < tsi->extra_peers_size; ++i) { + if (!(tsi->extra_peers_data[i].saddr[0])) + addr_to_string(&(tsi->extra_peers_data[i].addr), (uint8_t *)tsi->extra_peers_data[i].saddr); + myprintf(cs, " %s\n", tsi->extra_peers_data[i].saddr); + } + } + } + } + } - csarg->counter += 1; - } - return 0; + csarg->counter += 1; + } + return 0; } -static void cancel_session(struct cli_session* cs, const char* ssid) -{ - if(cs && cs->ts && ssid && *ssid) { - turnsession_id sid = strtoull(ssid,NULL,10); - send_session_cancellation_to_relay(sid); - } +static void cancel_session(struct cli_session *cs, const char *ssid) { + if (cs && cs->ts && ssid && *ssid) { + turnsession_id sid = strtoull(ssid, NULL, 10); + send_session_cancellation_to_relay(sid); + } } -static void print_sessions(struct cli_session* cs, const char* pn, int exact_match, int print_users) -{ - if(cs && cs->ts && pn) { +static void print_sessions(struct cli_session *cs, const char *pn, int exact_match, int print_users) { + if (cs && cs->ts && pn) { - while(pn[0] == ' ') ++pn; - if(pn[0] == '*') ++pn; + while (pn[0] == ' ') + ++pn; + if (pn[0] == '*') + ++pn; - const char *uname=""; - if(!print_users) { - uname = pn; - pn = ""; - } + const char *uname = ""; + if (!print_users) { + uname = pn; + pn = ""; + } - struct ps_arg arg = {cs,0,0,uname,pn,exact_match,NULL,NULL,NULL,0}; + struct ps_arg arg = {cs, 0, 0, uname, pn, exact_match, NULL, NULL, NULL, 0}; - arg.ct = turn_time(); + arg.ct = turn_time(); - if(print_users) { - arg.users = ur_string_map_create(NULL); - } + if (print_users) { + arg.users = ur_string_map_create(NULL); + } - ur_map_foreach_arg(adminserver.sessions, (foreachcb_arg_type)print_session, &arg); + ur_map_foreach_arg(adminserver.sessions, (foreachcb_arg_type)print_session, &arg); - myprintf(cs,"\n"); + myprintf(cs, "\n"); - if(!print_users && !(cs->f)) { - if((unsigned long)arg.counter > (unsigned long)cli_max_output_sessions) { - myprintf(cs,"...\n"); - myprintf(cs,"\n"); - } - } else if(arg.user_counters && arg.user_names) { - size_t i; - for(i=0;i, %lu sessions\n", - arg.user_names[i], - (unsigned long)arg.user_counters[i]); - } - } - myprintf(cs,"\n"); - } + if (!print_users && !(cs->f)) { + if ((unsigned long)arg.counter > (unsigned long)cli_max_output_sessions) { + myprintf(cs, "...\n"); + myprintf(cs, "\n"); + } + } else if (arg.user_counters && arg.user_names) { + size_t i; + for (i = 0; i < arg.users_number; ++i) { + if (arg.user_names[i]) { + myprintf(cs, " user: <%s>, %lu sessions\n", arg.user_names[i], (unsigned long)arg.user_counters[i]); + } + } + myprintf(cs, "\n"); + } - { - char ts[1025]; - snprintf(ts,sizeof(ts)," Total sessions"); - if(cs->realm[0]) { - snprintf(ts+strlen(ts),sizeof(ts)-strlen(ts)," for realm %s",cs->realm); - if(cs->origin[0]) - snprintf(ts+strlen(ts),sizeof(ts)-strlen(ts)," and for origin %s",cs->origin); - } else { - if(cs->origin[0]) - snprintf(ts+strlen(ts),sizeof(ts)-strlen(ts)," for origin %s",cs->origin); - } - snprintf(ts+strlen(ts),sizeof(ts)-strlen(ts),": %lu", (unsigned long)arg.counter); - myprintf(cs,"%s\n", ts); - myprintf(cs,"\n"); - } + { + char ts[1025]; + snprintf(ts, sizeof(ts), " Total sessions"); + if (cs->realm[0]) { + snprintf(ts + strlen(ts), sizeof(ts) - strlen(ts), " for realm %s", cs->realm); + if (cs->origin[0]) + snprintf(ts + strlen(ts), sizeof(ts) - strlen(ts), " and for origin %s", cs->origin); + } else { + if (cs->origin[0]) + snprintf(ts + strlen(ts), sizeof(ts) - strlen(ts), " for origin %s", cs->origin); + } + snprintf(ts + strlen(ts), sizeof(ts) - strlen(ts), ": %lu", (unsigned long)arg.counter); + myprintf(cs, "%s\n", ts); + myprintf(cs, "\n"); + } - if(!print_users && !(cs->f)) { - if((unsigned long)arg.counter > (unsigned long)cli_max_output_sessions) { - myprintf(cs," Warning: too many output sessions, more than the\n"); - myprintf(cs," current value of cli-max-output-sessions CLI parameter.\n"); - myprintf(cs," Refine your request or increase cli-max-output-sessions value.\n"); - myprintf(cs,"\n"); - } - } + if (!print_users && !(cs->f)) { + if ((unsigned long)arg.counter > (unsigned long)cli_max_output_sessions) { + myprintf(cs, " Warning: too many output sessions, more than the\n"); + myprintf(cs, " current value of cli-max-output-sessions CLI parameter.\n"); + myprintf(cs, " Refine your request or increase cli-max-output-sessions value.\n"); + myprintf(cs, "\n"); + } + } - if(arg.user_counters) - free(arg.user_counters); - if(arg.user_names) { - size_t i; - for(i=0;ioptions.name; + if (rn[0]) + cli_print_str(cs, rn, "Default realm", 0); + } + if (cs->realm[0]) + cli_print_str(cs, cs->realm, "CLI session realm", 0); + else + cli_print_str(cs, get_realm(NULL)->options.name, "CLI session realm", 0); + if (cs->origin[0]) + cli_print_str(cs, cs->origin, "CLI session origin", 0); + if (turn_params.ct == TURN_CREDENTIALS_LONG_TERM) + cli_print_flag(cs, 1, "Long-term authorization mechanism", 0); + else + cli_print_flag(cs, 1, "Anonymous credentials", 0); + cli_print_flag(cs, turn_params.use_auth_secret_with_timestamp, "TURN REST API support", 0); + if (turn_params.use_auth_secret_with_timestamp && turn_params.rest_api_separator) + cli_print_uint(cs, turn_params.rest_api_separator, "TURN REST API separator ASCII number", 0); - { - char * rn = get_realm(NULL)->options.name; - if(rn[0]) - cli_print_str(cs,rn,"Default realm",0); - } - if(cs->realm[0]) - cli_print_str(cs,cs->realm,"CLI session realm",0); - else - cli_print_str(cs,get_realm(NULL)->options.name,"CLI session realm",0); - if(cs->origin[0]) - cli_print_str(cs,cs->origin,"CLI session origin",0); - if(turn_params.ct == TURN_CREDENTIALS_LONG_TERM) - cli_print_flag(cs,1,"Long-term authorization mechanism",0); - else - cli_print_flag(cs,1,"Anonymous credentials",0); - cli_print_flag(cs,turn_params.use_auth_secret_with_timestamp,"TURN REST API support",0); - if(turn_params.use_auth_secret_with_timestamp && turn_params.rest_api_separator) - cli_print_uint(cs,turn_params.rest_api_separator,"TURN REST API separator ASCII number",0); + myprintf(cs, "\n"); - myprintf(cs,"\n"); + cli_print_uint(cs, (unsigned long)cs->rp->status.total_current_allocs, "total-current-allocs", 0); - cli_print_uint(cs,(unsigned long)cs->rp->status.total_current_allocs,"total-current-allocs",0); + myprintf(cs, "\n"); - myprintf(cs,"\n"); + cli_print_uint(cs, (unsigned long)turn_params.total_quota, "Default total-quota", 2); + cli_print_uint(cs, (unsigned long)turn_params.user_quota, "Default user-quota", 2); + cli_print_uint(cs, (unsigned long)get_bps_capacity(), "Total server bps-capacity", 2); + cli_print_uint(cs, (unsigned long)get_bps_capacity_allocated(), "Allocated bps-capacity", 0); + cli_print_uint(cs, (unsigned long)get_max_bps(), "Default max-bps", 2); - cli_print_uint(cs,(unsigned long)turn_params.total_quota,"Default total-quota",2); - cli_print_uint(cs,(unsigned long)turn_params.user_quota,"Default user-quota",2); - cli_print_uint(cs,(unsigned long)get_bps_capacity(),"Total server bps-capacity",2); - cli_print_uint(cs,(unsigned long)get_bps_capacity_allocated(),"Allocated bps-capacity",0); - cli_print_uint(cs,(unsigned long)get_max_bps(),"Default max-bps",2); + myprintf(cs, "\n"); - myprintf(cs,"\n"); + cli_print_uint(cs, (unsigned long)cs->rp->options.perf_options.total_quota, "current realm total-quota", 0); + cli_print_uint(cs, (unsigned long)cs->rp->options.perf_options.user_quota, "current realm user-quota", 0); + cli_print_uint(cs, (unsigned long)cs->rp->options.perf_options.max_bps, "current realm max-bps", 0); - cli_print_uint(cs,(unsigned long)cs->rp->options.perf_options.total_quota,"current realm total-quota",0); - cli_print_uint(cs,(unsigned long)cs->rp->options.perf_options.user_quota,"current realm user-quota",0); - cli_print_uint(cs,(unsigned long)cs->rp->options.perf_options.max_bps,"current realm max-bps",0); + myprintf(cs, "\n"); - myprintf(cs,"\n"); + cli_print_uint(cs, (unsigned long)cli_max_output_sessions, "cli-max-output-sessions", 2); - cli_print_uint(cs,(unsigned long)cli_max_output_sessions,"cli-max-output-sessions",2); - - { - myprintf(cs,"\n"); - const char *str=" (Note 1: parameters with (*) are toggleable)"; - myprintf(cs,"%s\n",str); - myprintf(cs,"\n"); - str=" (Note 2: parameters with (**) are changeable)"; - myprintf(cs,"%s\n",str); - myprintf(cs,"\n"); - } - } + { + myprintf(cs, "\n"); + const char *str = " (Note 1: parameters with (*) are toggleable)"; + myprintf(cs, "%s\n", str); + myprintf(cs, "\n"); + str = " (Note 2: parameters with (**) are changeable)"; + myprintf(cs, "%s\n", str); + myprintf(cs, "\n"); + } + } } -static void close_cli_session(struct cli_session* cs); +static void close_cli_session(struct cli_session *cs); -static int run_cli_output(struct cli_session* cs, const char *buf, unsigned int len) -{ - if(cs && buf && len) { - if(bufferevent_write(cs->bev, buf, len)< 0) { - return -1; - } - return 0; - } - return -1; +static int run_cli_output(struct cli_session *cs, const char *buf, unsigned int len) { + if (cs && buf && len) { + if (bufferevent_write(cs->bev, buf, len) < 0) { + return -1; + } + return 0; + } + return -1; } -static void close_cli_session(struct cli_session* cs) -{ - if(cs) { +static void close_cli_session(struct cli_session *cs) { + if (cs) { - addr_debug_print(adminserver.verbose, &(cs->addr),"CLI session disconnected from"); + addr_debug_print(adminserver.verbose, &(cs->addr), "CLI session disconnected from"); - if(cs->ts) { - telnet_free(cs->ts); - cs->ts = NULL; - } + if (cs->ts) { + telnet_free(cs->ts); + cs->ts = NULL; + } - BUFFEREVENT_FREE(cs->bev); + BUFFEREVENT_FREE(cs->bev); - if(cs->fd>=0) { - close(cs->fd); - cs->fd = -1; - } + if (cs->fd >= 0) { + close(cs->fd); + cs->fd = -1; + } - free(cs); - } + free(cs); + } } -static void type_cli_cursor(struct cli_session* cs) -{ - if(cs && (cs->bev)) { - myprintf(cs, "%s", CLI_CURSOR); - } +static void type_cli_cursor(struct cli_session *cs) { + if (cs && (cs->bev)) { + myprintf(cs, "%s", CLI_CURSOR); + } } -static void cli_add_alternate_server(struct cli_session* cs, const char* pn) -{ - if(cs && cs->ts && pn && *pn) { - add_alternate_server(pn); - } +static void cli_add_alternate_server(struct cli_session *cs, const char *pn) { + if (cs && cs->ts && pn && *pn) { + add_alternate_server(pn); + } } -static void cli_add_tls_alternate_server(struct cli_session* cs, const char* pn) -{ - if(cs && cs->ts && pn && *pn) { - add_tls_alternate_server(pn); - } +static void cli_add_tls_alternate_server(struct cli_session *cs, const char *pn) { + if (cs && cs->ts && pn && *pn) { + add_tls_alternate_server(pn); + } } -static void cli_del_alternate_server(struct cli_session* cs, const char* pn) -{ - if(cs && cs->ts && pn && *pn) { - del_alternate_server(pn); - } +static void cli_del_alternate_server(struct cli_session *cs, const char *pn) { + if (cs && cs->ts && pn && *pn) { + del_alternate_server(pn); + } } -static void cli_del_tls_alternate_server(struct cli_session* cs, const char* pn) -{ - if(cs && cs->ts && pn && *pn) { - del_tls_alternate_server(pn); - } +static void cli_del_tls_alternate_server(struct cli_session *cs, const char *pn) { + if (cs && cs->ts && pn && *pn) { + del_tls_alternate_server(pn); + } } -static int run_cli_input(struct cli_session* cs, const char *buf0, unsigned int len) -{ - int ret = 0; +static int run_cli_input(struct cli_session *cs, const char *buf0, unsigned int len) { + int ret = 0; - if(cs && buf0 && cs->ts && cs->bev) { + if (cs && buf0 && cs->ts && cs->bev) { - char *buf = (char*)malloc(len+1); - memcpy(buf,buf0,len); - buf[len]=0; + char *buf = (char *)malloc(len + 1); + memcpy(buf, buf0, len); + buf[len] = 0; - char *cmd = buf; + char *cmd = buf; - while((cmd[0]==' ') || (cmd[0]=='\t')) ++cmd; + while ((cmd[0] == ' ') || (cmd[0] == '\t')) + ++cmd; - size_t sl = strlen(cmd); + size_t sl = strlen(cmd); - while(sl) { - char c = cmd[sl-1]; - if((c==10)||(c==13)) { - cmd[sl-1]=0; - --sl; - } else { - break; - } - } + while (sl) { + char c = cmd[sl - 1]; + if ((c == 10) || (c == 13)) { + cmd[sl - 1] = 0; + --sl; + } else { + break; + } + } - if(sl) { - cs->cmds += 1; - if(cli_password[0] && !(cs->auth_completed)) { - if(check_password(cmd,cli_password)) { - if(cs->cmds>=CLI_PASSWORD_TRY_NUMBER) { - addr_debug_print(1, &(cs->addr),"CLI authentication error"); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"CLI authentication error\n"); - close_cli_session(cs); - } else { - const char* ipwd="Enter password: "; - myprintf(cs,"%s\n",ipwd); - } - } else { - cs->auth_completed = 1; - addr_debug_print(1, &(cs->addr),"CLI authentication success"); - type_cli_cursor(cs); - } - } else if((strcmp(cmd,"bye") == 0)||(strcmp(cmd,"quit") == 0)||(strcmp(cmd,"exit") == 0)||(strcmp(cmd,"q") == 0)) { - const char* str="Bye !"; - myprintf(cs,"%s\n",str); - close_cli_session(cs); - ret = -1; - } else if((strcmp(cmd,"halt") == 0)||(strcmp(cmd,"shutdown") == 0)||(strcmp(cmd,"stop") == 0)) { - addr_debug_print(1, &(cs->addr),"Shutdown command received from CLI user"); - const char* str="TURN server is shutting down"; - myprintf(cs,"%s\n",str); - close_cli_session(cs); - turn_params.stop_turn_server = 1; - sleep(10); - exit(0); - } else if((strcmp(cmd,"?") == 0)||(strcmp(cmd,"h") == 0)||(strcmp(cmd,"help") == 0)) { - print_str_array(cs, CLI_GREETING_STR); - print_str_array(cs, CLI_HELP_STR); - type_cli_cursor(cs); - } else if(strcmp(cmd,"pc")==0) { - cli_print_configuration(cs); - type_cli_cursor(cs); - } else if(strstr(cmd,"tc ") == cmd) { - toggle_cli_param(cs,cmd+3); - } else if(strstr(cmd,"sr ") == cmd) { - STRCPY(cs->realm,cmd+3); - cs->rp = get_realm(cs->realm); - type_cli_cursor(cs); - } else if(strcmp(cmd,"ur") == 0) { - cs->realm[0]=0; - cs->rp = get_realm(NULL); - type_cli_cursor(cs); - } else if(strstr(cmd,"so ") == cmd) { - STRCPY(cs->origin,cmd+3); - type_cli_cursor(cs); - } else if(strcmp(cmd,"uo") == 0) { - cs->origin[0]=0; - type_cli_cursor(cs); - } else if(strstr(cmd,"tc") == cmd) { - toggle_cli_param(cs,cmd+2); - type_cli_cursor(cs); - } else if(strstr(cmd,"psp") == cmd) { - print_sessions(cs,cmd+3,0,0); - type_cli_cursor(cs); - } else if(strstr(cmd,"psd") == cmd) { - cmd += 3; - while(cmd[0]==' ') ++cmd; - if(!(cmd[0])) { - const char* str="You have to provide file name for ps dump\n"; - myprintf(cs,"%s\n",str); - } else { - cs->f = fopen(cmd,"w"); - if(!(cs->f)) { - const char* str="Cannot open file for writing\n"; - myprintf(cs,"%s\n",str); - } else { - print_sessions(cs,"",1,0); - fclose(cs->f); - cs->f = NULL; - } - } - type_cli_cursor(cs); - } else if(strstr(cmd,"pu ") == cmd) { - print_sessions(cs,cmd+3,0,1); - type_cli_cursor(cs); - } else if(!strcmp(cmd,"pu")) { - print_sessions(cs,cmd+2,0,1); - type_cli_cursor(cs); - } else if(strstr(cmd,"ps") == cmd) { - print_sessions(cs,cmd+2,1,0); - type_cli_cursor(cs); - } else if(strstr(cmd,"cs ") == cmd) { - cancel_session(cs,cmd+3); - type_cli_cursor(cs); - } else if(strstr(cmd,"lr") == cmd) { - log_reset(cs); - type_cli_cursor(cs); - } else if(strstr(cmd,"cc ") == cmd) { - change_cli_param(cs,cmd+3); - type_cli_cursor(cs); - } else if(strstr(cmd,"cc") == cmd) { - change_cli_param(cs,cmd+2); - type_cli_cursor(cs); - } else if(strstr(cmd,"aas ") == cmd) { - cli_add_alternate_server(cs,cmd+4); - type_cli_cursor(cs); - } else if(strstr(cmd,"atas ") == cmd) { - cli_add_tls_alternate_server(cs,cmd+5); - type_cli_cursor(cs); - } else if(strstr(cmd,"das ") == cmd) { - cli_del_alternate_server(cs,cmd+4); - type_cli_cursor(cs); - } else if(strstr(cmd,"dtas ") == cmd) { - cli_del_tls_alternate_server(cs,cmd+5); - type_cli_cursor(cs); - } else { - const char* str="Unknown command\n"; - myprintf(cs,"%s\n",str); - type_cli_cursor(cs); - } - } else { - type_cli_cursor(cs); - } + if (sl) { + cs->cmds += 1; + if (cli_password[0] && !(cs->auth_completed)) { + if (check_password(cmd, cli_password)) { + if (cs->cmds >= CLI_PASSWORD_TRY_NUMBER) { + addr_debug_print(1, &(cs->addr), "CLI authentication error"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "CLI authentication error\n"); + close_cli_session(cs); + } else { + const char *ipwd = "Enter password: "; + myprintf(cs, "%s\n", ipwd); + } + } else { + cs->auth_completed = 1; + addr_debug_print(1, &(cs->addr), "CLI authentication success"); + type_cli_cursor(cs); + } + } else if ((strcmp(cmd, "bye") == 0) || (strcmp(cmd, "quit") == 0) || (strcmp(cmd, "exit") == 0) || + (strcmp(cmd, "q") == 0)) { + const char *str = "Bye !"; + myprintf(cs, "%s\n", str); + close_cli_session(cs); + ret = -1; + } else if ((strcmp(cmd, "halt") == 0) || (strcmp(cmd, "shutdown") == 0) || (strcmp(cmd, "stop") == 0)) { + addr_debug_print(1, &(cs->addr), "Shutdown command received from CLI user"); + const char *str = "TURN server is shutting down"; + myprintf(cs, "%s\n", str); + close_cli_session(cs); + turn_params.stop_turn_server = 1; + sleep(10); + exit(0); + } else if ((strcmp(cmd, "?") == 0) || (strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) { + print_str_array(cs, CLI_GREETING_STR); + print_str_array(cs, CLI_HELP_STR); + type_cli_cursor(cs); + } else if (strcmp(cmd, "pc") == 0) { + cli_print_configuration(cs); + type_cli_cursor(cs); + } else if (strstr(cmd, "tc ") == cmd) { + toggle_cli_param(cs, cmd + 3); + } else if (strstr(cmd, "sr ") == cmd) { + STRCPY(cs->realm, cmd + 3); + cs->rp = get_realm(cs->realm); + type_cli_cursor(cs); + } else if (strcmp(cmd, "ur") == 0) { + cs->realm[0] = 0; + cs->rp = get_realm(NULL); + type_cli_cursor(cs); + } else if (strstr(cmd, "so ") == cmd) { + STRCPY(cs->origin, cmd + 3); + type_cli_cursor(cs); + } else if (strcmp(cmd, "uo") == 0) { + cs->origin[0] = 0; + type_cli_cursor(cs); + } else if (strstr(cmd, "tc") == cmd) { + toggle_cli_param(cs, cmd + 2); + type_cli_cursor(cs); + } else if (strstr(cmd, "psp") == cmd) { + print_sessions(cs, cmd + 3, 0, 0); + type_cli_cursor(cs); + } else if (strstr(cmd, "psd") == cmd) { + cmd += 3; + while (cmd[0] == ' ') + ++cmd; + if (!(cmd[0])) { + const char *str = "You have to provide file name for ps dump\n"; + myprintf(cs, "%s\n", str); + } else { + cs->f = fopen(cmd, "w"); + if (!(cs->f)) { + const char *str = "Cannot open file for writing\n"; + myprintf(cs, "%s\n", str); + } else { + print_sessions(cs, "", 1, 0); + fclose(cs->f); + cs->f = NULL; + } + } + type_cli_cursor(cs); + } else if (strstr(cmd, "pu ") == cmd) { + print_sessions(cs, cmd + 3, 0, 1); + type_cli_cursor(cs); + } else if (!strcmp(cmd, "pu")) { + print_sessions(cs, cmd + 2, 0, 1); + type_cli_cursor(cs); + } else if (strstr(cmd, "ps") == cmd) { + print_sessions(cs, cmd + 2, 1, 0); + type_cli_cursor(cs); + } else if (strstr(cmd, "cs ") == cmd) { + cancel_session(cs, cmd + 3); + type_cli_cursor(cs); + } else if (strstr(cmd, "lr") == cmd) { + log_reset(cs); + type_cli_cursor(cs); + } else if (strstr(cmd, "cc ") == cmd) { + change_cli_param(cs, cmd + 3); + type_cli_cursor(cs); + } else if (strstr(cmd, "cc") == cmd) { + change_cli_param(cs, cmd + 2); + type_cli_cursor(cs); + } else if (strstr(cmd, "aas ") == cmd) { + cli_add_alternate_server(cs, cmd + 4); + type_cli_cursor(cs); + } else if (strstr(cmd, "atas ") == cmd) { + cli_add_tls_alternate_server(cs, cmd + 5); + type_cli_cursor(cs); + } else if (strstr(cmd, "das ") == cmd) { + cli_del_alternate_server(cs, cmd + 4); + type_cli_cursor(cs); + } else if (strstr(cmd, "dtas ") == cmd) { + cli_del_tls_alternate_server(cs, cmd + 5); + type_cli_cursor(cs); + } else { + const char *str = "Unknown command\n"; + myprintf(cs, "%s\n", str); + type_cli_cursor(cs); + } + } else { + type_cli_cursor(cs); + } - free(buf); - } + free(buf); + } - return ret; + return ret; } -static void cli_socket_input_handler_bev(struct bufferevent *bev, void* arg) -{ - if (bev && arg) { +static void cli_socket_input_handler_bev(struct bufferevent *bev, void *arg) { + if (bev && arg) { - struct cli_session* cs = (struct cli_session*) arg; + struct cli_session *cs = (struct cli_session *)arg; - if(!(cs->ts)) - return; + if (!(cs->ts)) + return; - stun_buffer buf; + stun_buffer buf; - if(cs->bev) { + if (cs->bev) { - int len = (int)bufferevent_read(cs->bev, buf.buf, STUN_BUFFER_SIZE-1); - if(len < 0) { - close_cli_session(cs); - return; - } else if(len == 0) { - return; - } + int len = (int)bufferevent_read(cs->bev, buf.buf, STUN_BUFFER_SIZE - 1); + if (len < 0) { + close_cli_session(cs); + return; + } else if (len == 0) { + return; + } - buf.len = len; - buf.offset = 0; - buf.buf[len]=0; + buf.len = len; + buf.offset = 0; + buf.buf[len] = 0; - telnet_recv(cs->ts, (const char *)buf.buf, (unsigned int)(buf.len)); - } - } + telnet_recv(cs->ts, (const char *)buf.buf, (unsigned int)(buf.len)); + } + } } -static void cli_eventcb_bev(struct bufferevent *bev, short events, void *arg) -{ - UNUSED_ARG(bev); +static void cli_eventcb_bev(struct bufferevent *bev, short events, void *arg) { + UNUSED_ARG(bev); - if (events & BEV_EVENT_CONNECTED) { - // Connect okay - } else if (events & (BEV_EVENT_ERROR | BEV_EVENT_EOF)) { - if (arg) { + if (events & BEV_EVENT_CONNECTED) { + // Connect okay + } else if (events & (BEV_EVENT_ERROR | BEV_EVENT_EOF)) { + if (arg) { - struct cli_session* cs = (struct cli_session*) arg; + struct cli_session *cs = (struct cli_session *)arg; - close_cli_session(cs); - } - } + close_cli_session(cs); + } + } } -static void cli_telnet_event_handler(telnet_t *telnet, telnet_event_t *event, void *user_data) -{ - if (user_data && telnet) { +static void cli_telnet_event_handler(telnet_t *telnet, telnet_event_t *event, void *user_data) { + if (user_data && telnet) { - struct cli_session *cs = (struct cli_session *) user_data; + struct cli_session *cs = (struct cli_session *)user_data; - switch (event->type){ - case TELNET_EV_DATA: - run_cli_input(cs, event->data.buffer, event->data.size); - break; - case TELNET_EV_SEND: - run_cli_output(cs, event->data.buffer, event->data.size); - break; - case TELNET_EV_ERROR: - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TELNET error: %s", event->error.msg); - break; - default: - ; - }; - } + switch (event->type) { + case TELNET_EV_DATA: + run_cli_input(cs, event->data.buffer, event->data.size); + break; + case TELNET_EV_SEND: + run_cli_output(cs, event->data.buffer, event->data.size); + break; + case TELNET_EV_ERROR: + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TELNET error: %s", event->error.msg); + break; + default:; + }; + } } -static void cliserver_input_handler(struct evconnlistener *l, evutil_socket_t fd, - struct sockaddr *sa, int socklen, void *arg) -{ - UNUSED_ARG(l); - UNUSED_ARG(arg); - UNUSED_ARG(socklen); +static void cliserver_input_handler(struct evconnlistener *l, evutil_socket_t fd, struct sockaddr *sa, int socklen, + void *arg) { + UNUSED_ARG(l); + UNUSED_ARG(arg); + UNUSED_ARG(socklen); - addr_debug_print(adminserver.verbose, (ioa_addr*)sa,"CLI connected to"); + addr_debug_print(adminserver.verbose, (ioa_addr *)sa, "CLI connected to"); - struct cli_session *clisession = (struct cli_session*)calloc(sizeof(struct cli_session), 1); + struct cli_session *clisession = (struct cli_session *)calloc(sizeof(struct cli_session), 1); - clisession->rp = get_realm(NULL); + clisession->rp = get_realm(NULL); - set_socket_options_fd(fd, TCP_SOCKET, sa->sa_family); + set_socket_options_fd(fd, TCP_SOCKET, sa->sa_family); - clisession->fd = fd; + clisession->fd = fd; - addr_cpy(&(clisession->addr),(ioa_addr*)sa); + addr_cpy(&(clisession->addr), (ioa_addr *)sa); - clisession->bev = bufferevent_socket_new(adminserver.event_base, - fd, - TURN_BUFFEREVENTS_OPTIONS); - bufferevent_setcb(clisession->bev, cli_socket_input_handler_bev, NULL, - cli_eventcb_bev, clisession); - bufferevent_setwatermark(clisession->bev, EV_READ|EV_WRITE, 0, BUFFEREVENT_HIGH_WATERMARK); - bufferevent_enable(clisession->bev, EV_READ); /* Start reading. */ + clisession->bev = bufferevent_socket_new(adminserver.event_base, fd, TURN_BUFFEREVENTS_OPTIONS); + bufferevent_setcb(clisession->bev, cli_socket_input_handler_bev, NULL, cli_eventcb_bev, clisession); + bufferevent_setwatermark(clisession->bev, EV_READ | EV_WRITE, 0, BUFFEREVENT_HIGH_WATERMARK); + bufferevent_enable(clisession->bev, EV_READ); /* Start reading. */ - clisession->ts = telnet_init(cli_telopts, cli_telnet_event_handler, 0, clisession); + clisession->ts = telnet_init(cli_telopts, cli_telnet_event_handler, 0, clisession); - if(!(clisession->ts)) { - const char *str = "Cannot open telnet session\n"; - addr_debug_print(adminserver.verbose, (ioa_addr*)sa,str); - close_cli_session(clisession); - } else { - print_str_array(clisession, CLI_GREETING_STR); - telnet_printf(clisession->ts,"\n"); - telnet_printf(clisession->ts,"Type '?' for help\n"); - if(cli_password[0]) { - const char* ipwd="Enter password: "; - telnet_printf(clisession->ts,"%s\n",ipwd); - } else { - type_cli_cursor(clisession); - } - } + if (!(clisession->ts)) { + const char *str = "Cannot open telnet session\n"; + addr_debug_print(adminserver.verbose, (ioa_addr *)sa, str); + close_cli_session(clisession); + } else { + print_str_array(clisession, CLI_GREETING_STR); + telnet_printf(clisession->ts, "\n"); + telnet_printf(clisession->ts, "Type '?' for help\n"); + if (cli_password[0]) { + const char *ipwd = "Enter password: "; + telnet_printf(clisession->ts, "%s\n", ipwd); + } else { + type_cli_cursor(clisession); + } + } } -static void web_admin_input_handler(ioa_socket_handle s, int event_type, - ioa_net_data *in_buffer, void *arg, int can_resume) { - UNUSED_ARG(event_type); - UNUSED_ARG(can_resume); - UNUSED_ARG(arg); +static void web_admin_input_handler(ioa_socket_handle s, int event_type, ioa_net_data *in_buffer, void *arg, + int can_resume) { + UNUSED_ARG(event_type); + UNUSED_ARG(can_resume); + UNUSED_ARG(arg); - int to_be_closed = 0; + int to_be_closed = 0; - int buffer_size = (int)ioa_network_buffer_get_size(in_buffer->nbh); - if (buffer_size >= UDP_STUN_BUFFER_SIZE) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "%s: request is too big: %d\n", __FUNCTION__, buffer_size); - to_be_closed = 1; - } - else if (buffer_size > 0) { - - SOCKET_TYPE st = get_ioa_socket_type(s); - - if(is_stream_socket(st)) { - if(is_http((char*)ioa_network_buffer_data(in_buffer->nbh), buffer_size)) { - const char *proto = "HTTP"; - ioa_network_buffer_data(in_buffer->nbh)[buffer_size] = 0; - if(st == TLS_SOCKET) { - proto = "HTTPS"; - set_ioa_socket_app_type(s, HTTPS_CLIENT_SOCKET); + int buffer_size = (int)ioa_network_buffer_get_size(in_buffer->nbh); + if (buffer_size >= UDP_STUN_BUFFER_SIZE) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "%s: request is too big: %d\n", __FUNCTION__, buffer_size); + to_be_closed = 1; + } else if (buffer_size > 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %s\n", __FUNCTION__, proto, get_ioa_socket_cipher(s), get_ioa_socket_ssl_method(s), (char*)ioa_network_buffer_data(in_buffer->nbh)); + SOCKET_TYPE st = get_ioa_socket_type(s); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s socket to be detached: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)s, get_ioa_socket_type(s), get_ioa_socket_app_type(s)); + if (is_stream_socket(st)) { + if (is_http((char *)ioa_network_buffer_data(in_buffer->nbh), buffer_size)) { + const char *proto = "HTTP"; + ioa_network_buffer_data(in_buffer->nbh)[buffer_size] = 0; + if (st == TLS_SOCKET) { + proto = "HTTPS"; + set_ioa_socket_app_type(s, HTTPS_CLIENT_SOCKET); - ioa_socket_handle new_s = detach_ioa_socket(s); - if(new_s) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s new detached socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)new_s, get_ioa_socket_type(new_s), get_ioa_socket_app_type(new_s)); - - send_https_socket(new_s); - } - to_be_closed = 1; - - } else { - set_ioa_socket_app_type(s, HTTP_CLIENT_SOCKET); - if(adminserver.verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s request: %s\n", __FUNCTION__, proto, (char*)ioa_network_buffer_data(in_buffer->nbh)); - } - handle_http_echo(s); - } - } - } - } + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %s\n", __FUNCTION__, proto, + get_ioa_socket_cipher(s), get_ioa_socket_ssl_method(s), + (char *)ioa_network_buffer_data(in_buffer->nbh)); - if (to_be_closed) { - if(adminserver.verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: web-admin socket to be closed in client handler: s=0x%lx\n", __FUNCTION__, (long)s); - } - set_ioa_socket_tobeclosed(s); - } + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s socket to be detached: 0x%lx, st=%d, sat=%d\n", __FUNCTION__, (long)s, + get_ioa_socket_type(s), get_ioa_socket_app_type(s)); + + ioa_socket_handle new_s = detach_ioa_socket(s); + if (new_s) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s new detached socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__, + (long)new_s, get_ioa_socket_type(new_s), get_ioa_socket_app_type(new_s)); + + send_https_socket(new_s); + } + to_be_closed = 1; + + } else { + set_ioa_socket_app_type(s, HTTP_CLIENT_SOCKET); + if (adminserver.verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s request: %s\n", __FUNCTION__, proto, + (char *)ioa_network_buffer_data(in_buffer->nbh)); + } + handle_http_echo(s); + } + } + } + } + + if (to_be_closed) { + if (adminserver.verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: web-admin socket to be closed in client handler: s=0x%lx\n", __FUNCTION__, + (long)s); + } + set_ioa_socket_tobeclosed(s); + } } -static int send_socket_to_admin_server(ioa_engine_handle e, struct message_to_relay *sm) -{ - // sm->relay_server is null for us. +static int send_socket_to_admin_server(ioa_engine_handle e, struct message_to_relay *sm) { + // sm->relay_server is null for us. - sm->t = RMT_SOCKET; + sm->t = RMT_SOCKET; - if (sm->m.sm.s->defer_nbh) { - if (!sm->m.sm.nd.nbh) { - sm->m.sm.nd.nbh = sm->m.sm.s->defer_nbh; - sm->m.sm.s->defer_nbh = NULL; - } else { - ioa_network_buffer_delete(e, sm->m.sm.s->defer_nbh); - sm->m.sm.s->defer_nbh = NULL; - } - } + if (sm->m.sm.s->defer_nbh) { + if (!sm->m.sm.nd.nbh) { + sm->m.sm.nd.nbh = sm->m.sm.s->defer_nbh; + sm->m.sm.s->defer_nbh = NULL; + } else { + ioa_network_buffer_delete(e, sm->m.sm.s->defer_nbh); + sm->m.sm.s->defer_nbh = NULL; + } + } - ioa_socket_handle s = sm->m.sm.s; + ioa_socket_handle s = sm->m.sm.s; - if (!s) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: web-admin socket EMPTY\n", __FUNCTION__); - - } else if (s->read_event || s->bev) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: web-admin socket wrongly preset: 0x%lx : 0x%lx\n", - __FUNCTION__, (long) s->read_event, (long) s->bev); - - IOA_CLOSE_SOCKET(s); - sm->m.sm.s = NULL; - } else { - s->e = e; - - struct socket_message *msg = &(sm->m.sm); - - if(register_callback_on_ioa_socket(e, msg->s, IOA_EV_READ, - web_admin_input_handler, NULL, 0) < 0) { - - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: Failed to register callback on web-admin ioa socket\n", __FUNCTION__); - IOA_CLOSE_SOCKET(s); - sm->m.sm.s = NULL; - - } else { - - if(msg->nd.nbh) { - web_admin_input_handler(msg->s, IOA_EV_READ, &(msg->nd), NULL, msg->can_resume); - ioa_network_buffer_delete(e, msg->nd.nbh); - msg->nd.nbh = NULL; - } - } - } + if (!s) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: web-admin socket EMPTY\n", __FUNCTION__); - ioa_network_buffer_delete(e, sm->m.sm.nd.nbh); - sm->m.sm.nd.nbh = NULL; + } else if (s->read_event || s->bev) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: web-admin socket wrongly preset: 0x%lx : 0x%lx\n", __FUNCTION__, + (long)s->read_event, (long)s->bev); - return 0; + IOA_CLOSE_SOCKET(s); + sm->m.sm.s = NULL; + } else { + s->e = e; + + struct socket_message *msg = &(sm->m.sm); + + if (register_callback_on_ioa_socket(e, msg->s, IOA_EV_READ, web_admin_input_handler, NULL, 0) < 0) { + + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: Failed to register callback on web-admin ioa socket\n", __FUNCTION__); + IOA_CLOSE_SOCKET(s); + sm->m.sm.s = NULL; + + } else { + + if (msg->nd.nbh) { + web_admin_input_handler(msg->s, IOA_EV_READ, &(msg->nd), NULL, msg->can_resume); + ioa_network_buffer_delete(e, msg->nd.nbh); + msg->nd.nbh = NULL; + } + } + } + + ioa_network_buffer_delete(e, sm->m.sm.nd.nbh); + sm->m.sm.nd.nbh = NULL; + + return 0; } -void setup_admin_thread(void) -{ - adminserver.event_base = turn_event_base_new(); - super_memory_t* sm = new_super_memory_region(); - adminserver.e = create_ioa_engine(sm, adminserver.event_base, turn_params.listener.tp, turn_params.relay_ifname, turn_params.relays_number, turn_params.relay_addrs, - turn_params.default_relays, turn_params.verbose - #if !defined(TURN_NO_HIREDIS) - ,&turn_params.redis_statsdb - #endif - ); +void setup_admin_thread(void) { + adminserver.event_base = turn_event_base_new(); + super_memory_t *sm = new_super_memory_region(); + adminserver.e = create_ioa_engine(sm, adminserver.event_base, turn_params.listener.tp, turn_params.relay_ifname, + turn_params.relays_number, turn_params.relay_addrs, turn_params.default_relays, + turn_params.verbose +#if !defined(TURN_NO_HIREDIS) + , + &turn_params.redis_statsdb +#endif + ); - if(use_web_admin) { - // Support encryption on this ioa engine - // because the web-admin needs HTTPS - set_ssl_ctx(adminserver.e, &turn_params); - } - - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"IO method (admin thread): %s\n",event_base_get_method(adminserver.event_base)); + if (use_web_admin) { + // Support encryption on this ioa engine + // because the web-admin needs HTTPS + set_ssl_ctx(adminserver.e, &turn_params); + } - { - struct bufferevent *pair[2]; + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "IO method (admin thread): %s\n", event_base_get_method(adminserver.event_base)); - bufferevent_pair_new(adminserver.event_base, TURN_BUFFEREVENTS_OPTIONS, pair); + { + struct bufferevent *pair[2]; - adminserver.in_buf = pair[0]; - adminserver.out_buf = pair[1]; + bufferevent_pair_new(adminserver.event_base, TURN_BUFFEREVENTS_OPTIONS, pair); - bufferevent_setcb(adminserver.in_buf, admin_server_receive_message, NULL, NULL, &adminserver); - bufferevent_enable(adminserver.in_buf, EV_READ); - } + adminserver.in_buf = pair[0]; + adminserver.out_buf = pair[1]; - { - struct bufferevent *pair[2]; + bufferevent_setcb(adminserver.in_buf, admin_server_receive_message, NULL, NULL, &adminserver); + bufferevent_enable(adminserver.in_buf, EV_READ); + } - bufferevent_pair_new(adminserver.event_base, TURN_BUFFEREVENTS_OPTIONS, pair); + { + struct bufferevent *pair[2]; - adminserver.https_in_buf = pair[0]; - adminserver.https_out_buf = pair[1]; + bufferevent_pair_new(adminserver.event_base, TURN_BUFFEREVENTS_OPTIONS, pair); - bufferevent_setcb(adminserver.https_in_buf, https_admin_server_receive_message, NULL, NULL, &adminserver); - bufferevent_enable(adminserver.https_in_buf, EV_READ); - } + adminserver.https_in_buf = pair[0]; + adminserver.https_out_buf = pair[1]; - - // Setup the web-admin server - if(use_web_admin) { - if(!web_admin_addr_set) { - if(make_ioa_addr((const uint8_t*)WEB_ADMIN_DEFAULT_IP, 0, &web_admin_addr) < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot set web-admin address %s\n", WEB_ADMIN_DEFAULT_IP); - return; - } - } - - addr_set_port(&web_admin_addr, web_admin_port); - - char saddr[129]; - addr_to_string_no_port(&web_admin_addr,(uint8_t*)saddr); - - tls_listener_relay_server_type *tls_service = create_tls_listener_server(turn_params.listener_ifname, saddr, web_admin_port, turn_params.verbose, adminserver.e, send_socket_to_admin_server, NULL); - - if (tls_service == NULL) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot create web-admin listener\n"); - return; - } - - addr_debug_print(adminserver.verbose, &web_admin_addr, "web-admin listener opened on "); - } - - if(use_cli) { - if(!cli_addr_set) { - if(make_ioa_addr((const uint8_t*)CLI_DEFAULT_IP,0,&cli_addr)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot set cli address %s\n",CLI_DEFAULT_IP); - return; - } - } + bufferevent_setcb(adminserver.https_in_buf, https_admin_server_receive_message, NULL, NULL, &adminserver); + bufferevent_enable(adminserver.https_in_buf, EV_READ); + } - addr_set_port(&cli_addr,cli_port); + // Setup the web-admin server + if (use_web_admin) { + if (!web_admin_addr_set) { + if (make_ioa_addr((const uint8_t *)WEB_ADMIN_DEFAULT_IP, 0, &web_admin_addr) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot set web-admin address %s\n", WEB_ADMIN_DEFAULT_IP); + return; + } + } - adminserver.listen_fd = socket(cli_addr.ss.sa_family, ADMIN_STREAM_SOCKET_TYPE, ADMIN_STREAM_SOCKET_PROTOCOL); - if (adminserver.listen_fd < 0) { - perror("socket"); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot open CLI socket\n"); - return; - } + addr_set_port(&web_admin_addr, web_admin_port); - if(addr_bind(adminserver.listen_fd,&cli_addr,1,1,TCP_SOCKET)<0) { - perror("Cannot bind CLI socket to addr"); - char saddr[129]; - addr_to_string(&cli_addr,(uint8_t*)saddr); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot bind CLI listener socket to addr %s\n",saddr); - socket_closesocket(adminserver.listen_fd); - return; - } + char saddr[129]; + addr_to_string_no_port(&web_admin_addr, (uint8_t *)saddr); - socket_tcp_set_keepalive(adminserver.listen_fd,TCP_SOCKET); + tls_listener_relay_server_type *tls_service = + create_tls_listener_server(turn_params.listener_ifname, saddr, web_admin_port, turn_params.verbose, + adminserver.e, send_socket_to_admin_server, NULL); - socket_set_nonblocking(adminserver.listen_fd); + if (tls_service == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot create web-admin listener\n"); + return; + } - adminserver.l = evconnlistener_new(adminserver.event_base, - cliserver_input_handler, &adminserver, - LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, - 1024, adminserver.listen_fd); + addr_debug_print(adminserver.verbose, &web_admin_addr, "web-admin listener opened on "); + } - if(!(adminserver.l)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot create CLI listener\n"); - socket_closesocket(adminserver.listen_fd); - return; - } + if (use_cli) { + if (!cli_addr_set) { + if (make_ioa_addr((const uint8_t *)CLI_DEFAULT_IP, 0, &cli_addr) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot set cli address %s\n", CLI_DEFAULT_IP); + return; + } + } - addr_debug_print(adminserver.verbose, &cli_addr,"CLI listener opened on "); - } + addr_set_port(&cli_addr, cli_port); - adminserver.sessions = ur_map_create(); + adminserver.listen_fd = socket(cli_addr.ss.sa_family, ADMIN_STREAM_SOCKET_TYPE, ADMIN_STREAM_SOCKET_PROTOCOL); + if (adminserver.listen_fd < 0) { + perror("socket"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open CLI socket\n"); + return; + } + + if (addr_bind(adminserver.listen_fd, &cli_addr, 1, 1, TCP_SOCKET) < 0) { + perror("Cannot bind CLI socket to addr"); + char saddr[129]; + addr_to_string(&cli_addr, (uint8_t *)saddr); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot bind CLI listener socket to addr %s\n", saddr); + socket_closesocket(adminserver.listen_fd); + return; + } + + socket_tcp_set_keepalive(adminserver.listen_fd, TCP_SOCKET); + + socket_set_nonblocking(adminserver.listen_fd); + + adminserver.l = evconnlistener_new(adminserver.event_base, cliserver_input_handler, &adminserver, + LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, 1024, adminserver.listen_fd); + + if (!(adminserver.l)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot create CLI listener\n"); + socket_closesocket(adminserver.listen_fd); + return; + } + + addr_debug_print(adminserver.verbose, &cli_addr, "CLI listener opened on "); + } + + adminserver.sessions = ur_map_create(); } -void admin_server_receive_message(struct bufferevent *bev, void *ptr) -{ - UNUSED_ARG(ptr); +void admin_server_receive_message(struct bufferevent *bev, void *ptr) { + UNUSED_ARG(ptr); - struct turn_session_info *tsi = (struct turn_session_info*)malloc(sizeof(struct turn_session_info)); - turn_session_info_init(tsi); - int n = 0; - struct evbuffer *input = bufferevent_get_input(bev); + struct turn_session_info *tsi = (struct turn_session_info *)malloc(sizeof(struct turn_session_info)); + turn_session_info_init(tsi); + int n = 0; + struct evbuffer *input = bufferevent_get_input(bev); - while ((n = evbuffer_remove(input, tsi, sizeof(struct turn_session_info))) > 0) { - if (n != sizeof(struct turn_session_info)) { - fprintf(stderr,"%s: Weird CLI buffer error: size=%d\n",__FUNCTION__,n); - continue; - } + while ((n = evbuffer_remove(input, tsi, sizeof(struct turn_session_info))) > 0) { + if (n != sizeof(struct turn_session_info)) { + fprintf(stderr, "%s: Weird CLI buffer error: size=%d\n", __FUNCTION__, n); + continue; + } - ur_map_value_type t = 0; - if (ur_map_get(adminserver.sessions, (ur_map_key_type)tsi->id, &t) && t) { - struct turn_session_info *old = (struct turn_session_info*)t; - turn_session_info_clean(old); - free(old); - ur_map_del(adminserver.sessions, (ur_map_key_type)tsi->id, NULL); - } + ur_map_value_type t = 0; + if (ur_map_get(adminserver.sessions, (ur_map_key_type)tsi->id, &t) && t) { + struct turn_session_info *old = (struct turn_session_info *)t; + turn_session_info_clean(old); + free(old); + ur_map_del(adminserver.sessions, (ur_map_key_type)tsi->id, NULL); + } - if(tsi->valid) { - ur_map_put(adminserver.sessions, (ur_map_key_type)tsi->id, (ur_map_value_type)tsi); - tsi = (struct turn_session_info*)malloc(sizeof(struct turn_session_info)); - turn_session_info_init(tsi); - } else { - turn_session_info_clean(tsi); - } - } + if (tsi->valid) { + ur_map_put(adminserver.sessions, (ur_map_key_type)tsi->id, (ur_map_value_type)tsi); + tsi = (struct turn_session_info *)malloc(sizeof(struct turn_session_info)); + turn_session_info_init(tsi); + } else { + turn_session_info_clean(tsi); + } + } - if(tsi) { - turn_session_info_clean(tsi); - free(tsi); - } + if (tsi) { + turn_session_info_clean(tsi); + free(tsi); + } } -int send_turn_session_info(struct turn_session_info* tsi) -{ - int ret = -1; +int send_turn_session_info(struct turn_session_info *tsi) { + int ret = -1; - if(tsi) { - struct evbuffer *output = bufferevent_get_output(adminserver.out_buf); - if(output) { - if(evbuffer_add(output,tsi,sizeof(struct turn_session_info))>=0) { - ret = 0; - } - } - } + if (tsi) { + struct evbuffer *output = bufferevent_get_output(adminserver.out_buf); + if (output) { + if (evbuffer_add(output, tsi, sizeof(struct turn_session_info)) >= 0) { + ret = 0; + } + } + } - return ret; + return ret; } /////////// HTTPS ///////////// enum _AS_FORM { - AS_FORM_LOGON, - AS_FORM_LOGOUT, - AS_FORM_PC, - AS_FORM_HOME, - AS_FORM_TOGGLE, - AS_FORM_UPDATE, - AS_FORM_PS, - AS_FORM_USERS, - AS_FORM_SS, - AS_FORM_OS, - AS_FORM_OAUTH, - AS_FORM_OAUTH_SHOW_KEYS, - AS_FORM_UNKNOWN + AS_FORM_LOGON, + AS_FORM_LOGOUT, + AS_FORM_PC, + AS_FORM_HOME, + AS_FORM_TOGGLE, + AS_FORM_UPDATE, + AS_FORM_PS, + AS_FORM_USERS, + AS_FORM_SS, + AS_FORM_OS, + AS_FORM_OAUTH, + AS_FORM_OAUTH_SHOW_KEYS, + AS_FORM_UNKNOWN }; typedef enum _AS_FORM AS_FORM; @@ -1539,25 +1495,16 @@ typedef enum _AS_FORM AS_FORM; #define HR_OAUTH_KID "kid" struct form_name { - AS_FORM form; - const char* name; + AS_FORM form; + const char *name; }; static struct form_name form_names[] = { - {AS_FORM_LOGON,"/logon"}, - {AS_FORM_LOGOUT,"/logout"}, - {AS_FORM_PC,"/pc"}, - {AS_FORM_HOME,"/home"}, - {AS_FORM_TOGGLE,"/toggle"}, - {AS_FORM_UPDATE,"/update"}, - {AS_FORM_PS,"/ps"}, - {AS_FORM_USERS,"/us"}, - {AS_FORM_SS,"/ss"}, - {AS_FORM_OS,"/os"}, - {AS_FORM_OAUTH,"/oauth"}, - {AS_FORM_OAUTH_SHOW_KEYS,"/oauth_show_keys"}, - {AS_FORM_UNKNOWN,NULL} -}; + {AS_FORM_LOGON, "/logon"}, {AS_FORM_LOGOUT, "/logout"}, {AS_FORM_PC, "/pc"}, + {AS_FORM_HOME, "/home"}, {AS_FORM_TOGGLE, "/toggle"}, {AS_FORM_UPDATE, "/update"}, + {AS_FORM_PS, "/ps"}, {AS_FORM_USERS, "/us"}, {AS_FORM_SS, "/ss"}, + {AS_FORM_OS, "/os"}, {AS_FORM_OAUTH, "/oauth"}, {AS_FORM_OAUTH_SHOW_KEYS, "/oauth_show_keys"}, + {AS_FORM_UNKNOWN, NULL}}; #define admin_title "TURN Server (https admin connection)" #define __bold_admin_title "TURN Server
https admin connection
\r\n" @@ -1565,2274 +1512,2284 @@ static struct form_name form_names[] = { static ioa_socket_handle current_socket = NULL; -static char *get_bold_admin_title(void) -{ - static char sbat[1025]; - strncpy(sbat,__bold_admin_title,sizeof(sbat)); +static char *get_bold_admin_title(void) { + static char sbat[1025]; + strncpy(sbat, __bold_admin_title, sizeof(sbat)); - if(current_socket && current_socket->special_session) { - struct admin_session* as = (struct admin_session*)current_socket->special_session; - if(as->as_ok) { - if(as->as_login[0]) { - char *dst=sbat+strlen(sbat); - snprintf(dst,ADMIN_USER_MAX_LENGTH*2+2," admin user: %s
\r\n",as->as_login); - } - if(as->as_realm[0]) { - char *dst=sbat+strlen(sbat); - snprintf(dst,STUN_MAX_REALM_SIZE*2," admin session realm: %s
\r\n",as->as_realm); - } else if(as->as_eff_realm[0]) { - char *dst=sbat+strlen(sbat); - snprintf(dst,STUN_MAX_REALM_SIZE*2," admin session realm: %s
\r\n",as->as_eff_realm); - } - } - } - return sbat; + if (current_socket && current_socket->special_session) { + struct admin_session *as = (struct admin_session *)current_socket->special_session; + if (as->as_ok) { + if (as->as_login[0]) { + char *dst = sbat + strlen(sbat); + snprintf(dst, ADMIN_USER_MAX_LENGTH * 2 + 2, " admin user: %s
\r\n", as->as_login); + } + if (as->as_realm[0]) { + char *dst = sbat + strlen(sbat); + snprintf(dst, STUN_MAX_REALM_SIZE * 2, " admin session realm: %s
\r\n", as->as_realm); + } else if (as->as_eff_realm[0]) { + char *dst = sbat + strlen(sbat); + snprintf(dst, STUN_MAX_REALM_SIZE * 2, " admin session realm: %s
\r\n", as->as_eff_realm); + } + } + } + return sbat; } -static int wrong_html_name(const char* s) -{ - int ret = 0; - if(s) { - char* v=evhttp_encode_uri(s); - ret = strcmp(v,s); - free(v); - } - return ret; +static int wrong_html_name(const char *s) { + int ret = 0; + if (s) { + char *v = evhttp_encode_uri(s); + ret = strcmp(v, s); + free(v); + } + return ret; } static int is_as_ok(ioa_socket_handle s) { - return (s && s->special_session && - ((struct admin_session*)s->special_session)->as_ok); + return (s && s->special_session && ((struct admin_session *)s->special_session)->as_ok); } static int is_superuser(void) { - return (is_as_ok(current_socket) && - (!((struct admin_session*)current_socket->special_session)->as_realm[0])); + return (is_as_ok(current_socket) && (!((struct admin_session *)current_socket->special_session)->as_realm[0])); } -static char* current_realm(void) { - if(current_socket && current_socket->special_session && ((struct admin_session*)current_socket->special_session)->as_ok) { - return ((struct admin_session*)current_socket->special_session)->as_realm; - } else { - static char bad_realm[1025] = "_ERROR:UNKNOWN_REALM__"; - return bad_realm; - } +static char *current_realm(void) { + if (current_socket && current_socket->special_session && + ((struct admin_session *)current_socket->special_session)->as_ok) { + return ((struct admin_session *)current_socket->special_session)->as_realm; + } else { + static char bad_realm[1025] = "_ERROR:UNKNOWN_REALM__"; + return bad_realm; + } } -static char* current_eff_realm(void) { - char* r = current_realm(); - if(r && r[0]) return r; - else if(current_socket && current_socket->special_session && ((struct admin_session*)current_socket->special_session)->as_ok) { - return ((struct admin_session*)current_socket->special_session)->as_eff_realm; - } else { - static char bad_eff_realm[1025] = "_ERROR:UNKNOWN_REALM__"; - return bad_eff_realm; - } +static char *current_eff_realm(void) { + char *r = current_realm(); + if (r && r[0]) + return r; + else if (current_socket && current_socket->special_session && + ((struct admin_session *)current_socket->special_session)->as_ok) { + return ((struct admin_session *)current_socket->special_session)->as_eff_realm; + } else { + static char bad_eff_realm[1025] = "_ERROR:UNKNOWN_REALM__"; + return bad_eff_realm; + } } static size_t current_max_output_sessions(void) { - if(current_socket && current_socket->special_session && ((struct admin_session*)current_socket->special_session)->as_ok) { - return ((struct admin_session*)current_socket->special_session)->number_of_user_sessions; - } - return DEFAULT_CLI_MAX_OUTPUT_SESSIONS; + if (current_socket && current_socket->special_session && + ((struct admin_session *)current_socket->special_session)->as_ok) { + return ((struct admin_session *)current_socket->special_session)->number_of_user_sessions; + } + return DEFAULT_CLI_MAX_OUTPUT_SESSIONS; } static void set_current_max_output_sessions(size_t value) { - if(current_socket && current_socket->special_session && ((struct admin_session*)current_socket->special_session)->as_ok) { - ((struct admin_session*)current_socket->special_session)->number_of_user_sessions = value; - } + if (current_socket && current_socket->special_session && + ((struct admin_session *)current_socket->special_session)->as_ok) { + ((struct admin_session *)current_socket->special_session)->number_of_user_sessions = value; + } } -static void https_cancel_session(const char* ssid) -{ - if(ssid && *ssid) { - turnsession_id sid = (turnsession_id)strtoull(ssid,NULL,10); - send_session_cancellation_to_relay(sid); - } +static void https_cancel_session(const char *ssid) { + if (ssid && *ssid) { + turnsession_id sid = (turnsession_id)strtoull(ssid, NULL, 10); + send_session_cancellation_to_relay(sid); + } } -static void https_print_top_page_header(struct str_buffer *sb) -{ - str_buffer_append(sb,"\r\n\r\n \r\n "); - str_buffer_append(sb,admin_title); - str_buffer_append(sb,"\r\n \r\n \r\n "); - str_buffer_append(sb,bold_admin_title); +static void https_print_top_page_header(struct str_buffer *sb) { + str_buffer_append(sb, "\r\n\r\n \r\n "); + str_buffer_append(sb, admin_title); + str_buffer_append( + sb, "\r\n \r\n \r\n "); + str_buffer_append(sb, bold_admin_title); } -static void https_print_page_header(struct str_buffer *sb) -{ - https_print_top_page_header(sb); - str_buffer_append(sb,"
home page
\r\n
logout
\r\n"); - str_buffer_append(sb,"
\r\n"); +static void https_print_page_header(struct str_buffer *sb) { + https_print_top_page_header(sb); + str_buffer_append(sb, "
home page
\r\n
logout
\r\n"); + str_buffer_append(sb, "
\r\n"); } -static void https_finish_page(struct str_buffer *sb, ioa_socket_handle s, int cclose) -{ - str_buffer_append(sb,"\r\n\r\n"); +static void https_finish_page(struct str_buffer *sb, ioa_socket_handle s, int cclose) { + str_buffer_append(sb, "\r\n\r\n"); - send_str_from_ioa_socket_tcp(s,"HTTP/1.1 200 OK\r\nServer: "); - if(!turn_params.no_software_attribute) { - send_str_from_ioa_socket_tcp(s,TURN_SOFTWARE); - } - send_str_from_ioa_socket_tcp(s,"\r\n"); - send_str_from_ioa_socket_tcp(s,get_http_date_header()); - if(cclose) { - send_str_from_ioa_socket_tcp(s,"Connection: close\r\n"); - } - send_str_from_ioa_socket_tcp(s,"Content-Type: text/html; charset=UTF-8\r\nContent-Length: "); + send_str_from_ioa_socket_tcp(s, "HTTP/1.1 200 OK\r\nServer: "); + if (!turn_params.no_software_attribute) { + send_str_from_ioa_socket_tcp(s, TURN_SOFTWARE); + } + send_str_from_ioa_socket_tcp(s, "\r\n"); + send_str_from_ioa_socket_tcp(s, get_http_date_header()); + if (cclose) { + send_str_from_ioa_socket_tcp(s, "Connection: close\r\n"); + } + send_str_from_ioa_socket_tcp(s, "Content-Type: text/html; charset=UTF-8\r\nContent-Length: "); - send_ulong_from_ioa_socket_tcp(s,str_buffer_get_str_len(sb)); + send_ulong_from_ioa_socket_tcp(s, str_buffer_get_str_len(sb)); - send_str_from_ioa_socket_tcp(s,"\r\n\r\n"); - send_str_from_ioa_socket_tcp(s,str_buffer_get_str(sb)); + send_str_from_ioa_socket_tcp(s, "\r\n\r\n"); + send_str_from_ioa_socket_tcp(s, str_buffer_get_str(sb)); - str_buffer_free(sb); + str_buffer_free(sb); } -static AS_FORM get_form(const char* path) { - if(path) { - size_t i = 0; - while(form_names[i].name) { - if(!strcmp(form_names[i].name,path)) - return form_names[i].form; - ++i; - } - } - return AS_FORM_UNKNOWN; +static AS_FORM get_form(const char *path) { + if (path) { + size_t i = 0; + while (form_names[i].name) { + if (!strcmp(form_names[i].name, path)) + return form_names[i].form; + ++i; + } + } + return AS_FORM_UNKNOWN; } -static void write_https_logon_page(ioa_socket_handle s) -{ - if(s && !ioa_socket_tobeclosed(s)) { +static void write_https_logon_page(ioa_socket_handle s) { + if (s && !ioa_socket_tobeclosed(s)) { - struct str_buffer* sb = str_buffer_new(); + struct str_buffer *sb = str_buffer_new(); - https_print_top_page_header(sb); + https_print_top_page_header(sb); - int we_have_admin_users = 0; - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->list_admin_users) { - int ausers = dbd->list_admin_users(1); - if(ausers>0) { - we_have_admin_users = 1; - } - } + int we_have_admin_users = 0; + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->list_admin_users) { + int ausers = dbd->list_admin_users(1); + if (ausers > 0) { + we_have_admin_users = 1; + } + } - if(!we_have_admin_users) { - str_buffer_append(sb,"
To use the HTTPS admin connection, you have to set the database table admin_user with the admin user accounts.
\r\n"); - } else { - str_buffer_append(sb,"

\r\n"); - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"
Admin user information: user name:

password:


\r\n"); - str_buffer_append(sb,"
\r\n"); - } + if (!we_have_admin_users) { + str_buffer_append(sb, "
To use the HTTPS admin connection, you have to set the database table " + "admin_user with the admin user accounts.
\r\n"); + } else { + str_buffer_append(sb, "

\r\n"); + str_buffer_append(sb, "
\r\n"); + str_buffer_append( + sb, + "
Admin user information: user name:

password:


\r\n"); + str_buffer_append(sb, "
\r\n"); + } - https_finish_page(sb,s,!we_have_admin_users); - } + https_finish_page(sb, s, !we_have_admin_users); + } } -static void write_https_home_page(ioa_socket_handle s) -{ - if(s && !ioa_socket_tobeclosed(s)) { +static void write_https_home_page(ioa_socket_handle s) { + if (s && !ioa_socket_tobeclosed(s)) { - if(!is_as_ok(s)) { - write_https_logon_page(s); - } else { + if (!is_as_ok(s)) { + write_https_logon_page(s); + } else { - struct str_buffer* sb = str_buffer_new(); + struct str_buffer *sb = str_buffer_new(); - https_print_page_header(sb); + https_print_page_header(sb); - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"
Actions:\r\n"); + str_buffer_append(sb, "\r\n"); + str_buffer_append(sb, "
Actions:\r\n"); - str_buffer_append(sb," Realm name: "); - } else { - str_buffer_append(sb,"> "); - } + str_buffer_append(sb, " Realm name: "); + } else { + str_buffer_append(sb, "> "); + } - str_buffer_append(sb,"
"); + str_buffer_append(sb, "
"); - str_buffer_append(sb,"
Configuration Parameters"); + str_buffer_append(sb, "
Configuration Parameters"); - str_buffer_append(sb,"
TURN Sessions"); + str_buffer_append(sb, "
TURN Sessions"); - str_buffer_append(sb,"
Users"); + str_buffer_append(sb, "
Users"); - str_buffer_append(sb,"
Shared Secrets (for TURN REST API)"); + str_buffer_append(sb, "
Shared Secrets (for TURN REST API)"); - str_buffer_append(sb,"
Origins"); + str_buffer_append(sb, "
Origins"); - if(is_superuser()) { - if(ENC_ALG_NUM>0) { - str_buffer_append(sb,"
oAuth keys"); - } - } + if (is_superuser()) { + if (ENC_ALG_NUM > 0) { + str_buffer_append(sb, "
oAuth keys"); + } + } - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"\r\n"); + str_buffer_append(sb, "
\r\n"); + str_buffer_append(sb, "\r\n"); - https_finish_page(sb,s,0); - } - } + https_finish_page(sb, s, 0); + } + } } -static void sbprintf(struct str_buffer *sb, const char *format, ...) -{ - if(sb && format) { - va_list args; - va_start (args, format); - char s[1025]="\0"; - vsnprintf(s,sizeof(s)-1,format, args); - str_buffer_append(sb,s); - va_end (args); - } +static void sbprintf(struct str_buffer *sb, const char *format, ...) { + if (sb && format) { + va_list args; + va_start(args, format); + char s[1025] = "\0"; + vsnprintf(s, sizeof(s) - 1, format, args); + str_buffer_append(sb, s); + va_end(args); + } } -static void https_print_flag(struct str_buffer* sb, int flag, const char* name, const char* param_name) -{ - if(sb && name) { - if(!is_superuser()) - param_name = 0; - if(!param_name) { - sbprintf(sb,"%s%s\r\n",name,get_flag(flag)); - } else { - sbprintf(sb,"%s%s\r\n",name,HR_UPDATE_PARAMETER,param_name,get_flag(flag)); - } - } +static void https_print_flag(struct str_buffer *sb, int flag, const char *name, const char *param_name) { + if (sb && name) { + if (!is_superuser()) + param_name = 0; + if (!param_name) { + sbprintf(sb, "%s%s\r\n", name, get_flag(flag)); + } else { + sbprintf(sb, "%s%s\r\n", name, HR_UPDATE_PARAMETER, + param_name, get_flag(flag)); + } + } } -static void https_print_uint(struct str_buffer* sb, unsigned long value, const char* name, const char* param_name) -{ - if(sb && name) { - if(!is_superuser()) - param_name = 0; - if(!param_name) { - if(value) { - sbprintf(sb,"%s%lu\r\n",name,value); - } else { - sbprintf(sb,"%s \r\n",name); - } - } else { - if(value) { - sbprintf(sb,"%s
\r\n",name,form_names[AS_FORM_UPDATE].name,HR_UPDATE_PARAMETER,param_name,param_name,value); - } else { - sbprintf(sb,"%s
\r\n",name,form_names[AS_FORM_UPDATE].name,HR_UPDATE_PARAMETER,param_name,param_name); - } - } - } +static void https_print_uint(struct str_buffer *sb, unsigned long value, const char *name, const char *param_name) { + if (sb && name) { + if (!is_superuser()) + param_name = 0; + if (!param_name) { + if (value) { + sbprintf(sb, "%s%lu\r\n", name, value); + } else { + sbprintf(sb, "%s \r\n", name); + } + } else { + if (value) { + sbprintf(sb, + "%s
\r\n", + name, form_names[AS_FORM_UPDATE].name, HR_UPDATE_PARAMETER, param_name, param_name, value); + } else { + sbprintf(sb, + "%s
\r\n", + name, form_names[AS_FORM_UPDATE].name, HR_UPDATE_PARAMETER, param_name, param_name); + } + } + } } -static void https_print_str(struct str_buffer* sb, const char *value, const char* name, const char* param_name) -{ - if(sb && name && value) { - if(!is_superuser()) - param_name = 0; - if(!param_name) { - sbprintf(sb,"%s%s\r\n",name,value); - } else { - sbprintf(sb,"%s
\r\n",name,form_names[AS_FORM_UPDATE].name,HR_UPDATE_PARAMETER,param_name,param_name,value); - } - } +static void https_print_str(struct str_buffer *sb, const char *value, const char *name, const char *param_name) { + if (sb && name && value) { + if (!is_superuser()) + param_name = 0; + if (!param_name) { + sbprintf(sb, "%s%s\r\n", name, value); + } else { + sbprintf(sb, + "%s
\r\n", + name, form_names[AS_FORM_UPDATE].name, HR_UPDATE_PARAMETER, param_name, param_name, value); + } + } } -static void https_print_str_array(struct str_buffer* sb, char **value, size_t sz, const char* name) -{ - if(sb && name && value && sz) { - size_t i; - for(i=0;i %s %s\r\n",name,value[i]); - } - } - } +static void https_print_str_array(struct str_buffer *sb, char **value, size_t sz, const char *name) { + if (sb && name && value && sz) { + size_t i; + for (i = 0; i < sz; i++) { + if (value[i]) { + sbprintf(sb, " %s %s\r\n", name, value[i]); + } + } + } } -static void https_print_addr(struct str_buffer* sb, ioa_addr *value, int use_port, const char* name) -{ - if(sb && name && value) { - char s[256]; - if(!use_port) - addr_to_string_no_port(value,(uint8_t*)s); - else - addr_to_string(value,(uint8_t*)s); - sbprintf(sb," %s %s\r\n",name,s); - } +static void https_print_addr(struct str_buffer *sb, ioa_addr *value, int use_port, const char *name) { + if (sb && name && value) { + char s[256]; + if (!use_port) + addr_to_string_no_port(value, (uint8_t *)s); + else + addr_to_string(value, (uint8_t *)s); + sbprintf(sb, " %s %s\r\n", name, s); + } } -static size_t https_print_addr_list(struct str_buffer* sb, turn_server_addrs_list_t *value, int use_port, const char* name) -{ - if(sb && name && value && value->size && value->addrs) { - char s[256]; - size_t i; - for(i=0;isize;i++) { - if(!use_port) - addr_to_string_no_port(&(value->addrs[i]),(uint8_t*)s); - else - addr_to_string(&(value->addrs[i]),(uint8_t*)s); - sbprintf(sb," %s %s\r\n",name,s); - } - return i; - } - return 0; +static size_t https_print_addr_list(struct str_buffer *sb, turn_server_addrs_list_t *value, int use_port, + const char *name) { + if (sb && name && value && value->size && value->addrs) { + char s[256]; + size_t i; + for (i = 0; i < value->size; i++) { + if (!use_port) + addr_to_string_no_port(&(value->addrs[i]), (uint8_t *)s); + else + addr_to_string(&(value->addrs[i]), (uint8_t *)s); + sbprintf(sb, " %s %s\r\n", name, s); + } + return i; + } + return 0; } -static const char* change_ip_addr_html(int dynamic,const char* kind,const char* ip,const char *realm, char *buffer, size_t sz) -{ - if(!buffer || !sz) { - return ""; - } else { - buffer[0]=0; - if(dynamic && kind && ip) { +static const char *change_ip_addr_html(int dynamic, const char *kind, const char *ip, const char *realm, char *buffer, + size_t sz) { + if (!buffer || !sz) { + return ""; + } else { + buffer[0] = 0; + if (dynamic && kind && ip) { - if(!realm) realm=""; + if (!realm) + realm = ""; - if(current_realm()[0] && strcmp(current_realm(),realm)) { - //delete forbidden - } else { - char *eip = evhttp_encode_uri(ip); - snprintf(buffer,sz-1,"delete",form_names[AS_FORM_UPDATE].name,HR_DELETE_IP_KIND,kind,HR_DELETE_IP_REALM,realm,HR_DELETE_IP,eip); - free(eip); - } - } - return buffer; - } + if (current_realm()[0] && strcmp(current_realm(), realm)) { + // delete forbidden + } else { + char *eip = evhttp_encode_uri(ip); + snprintf(buffer, sz - 1, "delete", form_names[AS_FORM_UPDATE].name, + HR_DELETE_IP_KIND, kind, HR_DELETE_IP_REALM, realm, HR_DELETE_IP, eip); + free(eip); + } + } + return buffer; + } } -static void https_print_ip_range_list(struct str_buffer* sb, ip_range_list_t *value, const char* name, const char* kind, int dynamic) -{ - if(sb && name) { - if(value && value->rs) { - size_t i; - char buffer[1025]; - for(i=0;iranges_number;++i) { - if(value->rs[i].realm[0]) { - if(current_eff_realm()[0] && strcmp(current_eff_realm(),value->rs[i].realm)) { - continue; - } else { - sbprintf(sb," %s %s [%s] %s\r\n",name,value->rs[i].str,value->rs[i].realm, change_ip_addr_html(dynamic,kind,value->rs[i].str,value->rs[i].realm,buffer,sizeof(buffer))); - } - } else { - sbprintf(sb," %s %s %s\r\n",name,value->rs[i].str, change_ip_addr_html(dynamic,kind,value->rs[i].str,value->rs[i].realm,buffer,sizeof(buffer))); - } - } - } +static void https_print_ip_range_list(struct str_buffer *sb, ip_range_list_t *value, const char *name, const char *kind, + int dynamic) { + if (sb && name) { + if (value && value->rs) { + size_t i; + char buffer[1025]; + for (i = 0; i < value->ranges_number; ++i) { + if (value->rs[i].realm[0]) { + if (current_eff_realm()[0] && strcmp(current_eff_realm(), value->rs[i].realm)) { + continue; + } else { + sbprintf(sb, " %s %s [%s] %s\r\n", name, value->rs[i].str, value->rs[i].realm, + change_ip_addr_html(dynamic, kind, value->rs[i].str, value->rs[i].realm, buffer, sizeof(buffer))); + } + } else { + sbprintf(sb, " %s %s %s\r\n", name, value->rs[i].str, + change_ip_addr_html(dynamic, kind, value->rs[i].str, value->rs[i].realm, buffer, sizeof(buffer))); + } + } + } - if(dynamic) { - sbprintf(sb," Add %s",name); - sbprintf(sb,"
IP range:",form_names[AS_FORM_UPDATE].name,HR_ADD_IP_KIND,kind,HR_ADD_IP); - sbprintf(sb,"Realm: "); - sbprintf(sb,"
\r\n"); - } - } + if (dynamic) { + sbprintf(sb, " Add %s", name); + sbprintf( + sb, + "
IP range:", + form_names[AS_FORM_UPDATE].name, HR_ADD_IP_KIND, kind, HR_ADD_IP); + sbprintf(sb, "Realm: "); + sbprintf(sb, "
\r\n"); + } + } } -static void toggle_param(const char* pn) -{ - if(is_superuser()) { - if(pn) { - int i=0; - while(tcmds[i].cmd && tcmds[i].data) { - if(strcmp(tcmds[i].cmd,pn) == 0) { - *(tcmds[i].data) = !(*(tcmds[i].data)); - return; - } - ++i; - } - } - } +static void toggle_param(const char *pn) { + if (is_superuser()) { + if (pn) { + int i = 0; + while (tcmds[i].cmd && tcmds[i].data) { + if (strcmp(tcmds[i].cmd, pn) == 0) { + *(tcmds[i].data) = !(*(tcmds[i].data)); + return; + } + ++i; + } + } + } } -static void update_param(const char* pn, const char *value) -{ - if(pn) { - if(!value) - value = "0"; - if(is_superuser()) { - if(strstr(pn,"total-quota")==pn) { - turn_params.total_quota = atoi(value); - } else if(strstr(pn,"user-quota")==pn) { - turn_params.user_quota = atoi(value); - } else if(strstr(pn,"max-bps")==pn) { - set_max_bps((band_limit_t)strtoul(value,NULL,10)); - } else if(strstr(pn,"bps-capacity")==pn) { - set_bps_capacity((band_limit_t)strtoul(value,NULL,10)); - } - } - { - realm_params_t *rp = get_realm(current_eff_realm()); - if(!rp) rp = get_realm(NULL); +static void update_param(const char *pn, const char *value) { + if (pn) { + if (!value) + value = "0"; + if (is_superuser()) { + if (strstr(pn, "total-quota") == pn) { + turn_params.total_quota = atoi(value); + } else if (strstr(pn, "user-quota") == pn) { + turn_params.user_quota = atoi(value); + } else if (strstr(pn, "max-bps") == pn) { + set_max_bps((band_limit_t)strtoul(value, NULL, 10)); + } else if (strstr(pn, "bps-capacity") == pn) { + set_bps_capacity((band_limit_t)strtoul(value, NULL, 10)); + } + } + { + realm_params_t *rp = get_realm(current_eff_realm()); + if (!rp) + rp = get_realm(NULL); - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->set_realm_option_one) { - if(strstr(pn,"cr-total-quota")==pn) { - rp->options.perf_options.total_quota = atoi(value); - dbd->set_realm_option_one((uint8_t*)rp->options.name,rp->options.perf_options.total_quota,"total-quota"); - } else if(strstr(pn,"cr-user-quota")==pn) { - rp->options.perf_options.user_quota = atoi(value); - dbd->set_realm_option_one((uint8_t*)rp->options.name,rp->options.perf_options.user_quota,"user-quota"); - } else if(strstr(pn,"cr-max-bps")==pn) { - rp->options.perf_options.max_bps = (band_limit_t)strtoul(value,NULL,10); - dbd->set_realm_option_one((uint8_t*)rp->options.name,rp->options.perf_options.max_bps,"max-bps"); - } - } - } - } + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->set_realm_option_one) { + if (strstr(pn, "cr-total-quota") == pn) { + rp->options.perf_options.total_quota = atoi(value); + dbd->set_realm_option_one((uint8_t *)rp->options.name, rp->options.perf_options.total_quota, "total-quota"); + } else if (strstr(pn, "cr-user-quota") == pn) { + rp->options.perf_options.user_quota = atoi(value); + dbd->set_realm_option_one((uint8_t *)rp->options.name, rp->options.perf_options.user_quota, "user-quota"); + } else if (strstr(pn, "cr-max-bps") == pn) { + rp->options.perf_options.max_bps = (band_limit_t)strtoul(value, NULL, 10); + dbd->set_realm_option_one((uint8_t *)rp->options.name, rp->options.perf_options.max_bps, "max-bps"); + } + } + } + } } -static void https_print_empty_row(struct str_buffer* sb, size_t span) -{ - str_buffer_append(sb,"
"); +static void https_print_empty_row(struct str_buffer *sb, size_t span) { + str_buffer_append(sb, "
"); } -static void write_pc_page(ioa_socket_handle s) -{ - if(s && !ioa_socket_tobeclosed(s)) { +static void write_pc_page(ioa_socket_handle s) { + if (s && !ioa_socket_tobeclosed(s)) { - if(!is_as_ok(s)) { - write_https_logon_page(s); - } else { + if (!is_as_ok(s)) { + write_https_logon_page(s); + } else { - struct str_buffer* sb = str_buffer_new(); + struct str_buffer *sb = str_buffer_new(); - https_print_page_header(sb); + https_print_page_header(sb); - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"Configuration Parameters:

\r\n"); - str_buffer_append(sb,"\r\n"); + str_buffer_append(sb, "
\r\n"); + str_buffer_append(sb, "Configuration Parameters:

ParameterValue
\r\n"); + str_buffer_append(sb, "\r\n"); - { - https_print_flag(sb,turn_params.verbose,"verbose",0); - https_print_flag(sb,turn_params.turn_daemon,"daemon process",0); - https_print_flag(sb,turn_params.stale_nonce,"stale-nonce","stale-nonce"); - https_print_flag(sb,turn_params.stun_only,"stun-only","stun-only"); - https_print_flag(sb,turn_params.no_stun,"no-stun","no-stun"); - https_print_flag(sb,turn_params.secure_stun,"secure-stun","secure-stun"); - https_print_flag(sb,turn_params.do_not_use_config_file,"do-not-use-config-file",0); - https_print_flag(sb,turn_params.rfc5780,"RFC5780 support",0); - https_print_uint(sb,(unsigned int)turn_params.net_engine_version,"net engine version",0); - https_print_str(sb,turn_params.net_engine_version_txt[(int)turn_params.net_engine_version],"net engine",0); - https_print_flag(sb,turn_params.fingerprint,"enforce fingerprints",0); - https_print_flag(sb,turn_params.mobility,"mobility","mobility"); - https_print_flag(sb,turn_params.udp_self_balance,"udp-self-balance",0); - https_print_str(sb,turn_params.pidfile,"pidfile",0); + { + https_print_flag(sb, turn_params.verbose, "verbose", 0); + https_print_flag(sb, turn_params.turn_daemon, "daemon process", 0); + https_print_flag(sb, turn_params.stale_nonce, "stale-nonce", "stale-nonce"); + https_print_flag(sb, turn_params.stun_only, "stun-only", "stun-only"); + https_print_flag(sb, turn_params.no_stun, "no-stun", "no-stun"); + https_print_flag(sb, turn_params.secure_stun, "secure-stun", "secure-stun"); + https_print_flag(sb, turn_params.do_not_use_config_file, "do-not-use-config-file", 0); + https_print_flag(sb, turn_params.rfc5780, "RFC5780 support", 0); + https_print_uint(sb, (unsigned int)turn_params.net_engine_version, "net engine version", 0); + https_print_str(sb, turn_params.net_engine_version_txt[(int)turn_params.net_engine_version], "net engine", 0); + https_print_flag(sb, turn_params.fingerprint, "enforce fingerprints", 0); + https_print_flag(sb, turn_params.mobility, "mobility", "mobility"); + https_print_flag(sb, turn_params.udp_self_balance, "udp-self-balance", 0); + https_print_str(sb, turn_params.pidfile, "pidfile", 0); #if defined(WINDOWS) - //TODO: implement it!!! + // TODO: implement it!!! #else - https_print_uint(sb,(unsigned long)getuid(),"process user ID",0); - https_print_uint(sb,(unsigned long)getgid(),"process group ID",0); + https_print_uint(sb, (unsigned long)getuid(), "process user ID", 0); + https_print_uint(sb, (unsigned long)getgid(), "process group ID", 0); #endif - { - char wd[1025]; - if(getcwd(wd,sizeof(wd)-1)) { - https_print_str(sb,wd,"process dir",0); - } - } + { + char wd[1025]; + if (getcwd(wd, sizeof(wd) - 1)) { + https_print_str(sb, wd, "process dir", 0); + } + } - https_print_empty_row(sb,2); + https_print_empty_row(sb, 2); - if(turn_params.cipher_list[0]) - https_print_str(sb,turn_params.cipher_list,"cipher-list",0); - else - https_print_str(sb,DEFAULT_CIPHER_LIST,"cipher-list",0); + if (turn_params.cipher_list[0]) + https_print_str(sb, turn_params.cipher_list, "cipher-list", 0); + else + https_print_str(sb, DEFAULT_CIPHER_LIST, "cipher-list", 0); - https_print_str(sb,turn_params.ec_curve_name,"ec-curve-name",0); - { - if(turn_params.dh_key_size == DH_CUSTOM) - https_print_str(sb,turn_params.dh_file,"dh-file",0); - else { - unsigned int dh_key_length = 1066; - if(turn_params.dh_key_size == DH_566) - dh_key_length = 566; - else if(turn_params.dh_key_size == DH_2066) - dh_key_length = 2066; - https_print_uint(sb,(unsigned long)dh_key_length,"DH-key-length",0); - } - } + https_print_str(sb, turn_params.ec_curve_name, "ec-curve-name", 0); + { + if (turn_params.dh_key_size == DH_CUSTOM) + https_print_str(sb, turn_params.dh_file, "dh-file", 0); + else { + unsigned int dh_key_length = 1066; + if (turn_params.dh_key_size == DH_566) + dh_key_length = 566; + else if (turn_params.dh_key_size == DH_2066) + dh_key_length = 2066; + https_print_uint(sb, (unsigned long)dh_key_length, "DH-key-length", 0); + } + } - https_print_str(sb,turn_params.ca_cert_file,"Certificate Authority file",0); - https_print_str(sb,turn_params.cert_file,"Certificate file",0); - https_print_str(sb,turn_params.pkey_file,"Private Key file",0); + https_print_str(sb, turn_params.ca_cert_file, "Certificate Authority file", 0); + https_print_str(sb, turn_params.cert_file, "Certificate file", 0); + https_print_str(sb, turn_params.pkey_file, "Private Key file", 0); - https_print_empty_row(sb,2); + https_print_empty_row(sb, 2); - https_print_str_array(sb,turn_params.listener.addrs,turn_params.listener.addrs_number,"Listener addr"); + https_print_str_array(sb, turn_params.listener.addrs, turn_params.listener.addrs_number, "Listener addr"); - if(turn_params.listener_ifname[0]) - https_print_str(sb,turn_params.listener_ifname,"listener-ifname",0); + if (turn_params.listener_ifname[0]) + https_print_str(sb, turn_params.listener_ifname, "listener-ifname", 0); - https_print_flag(sb,turn_params.no_udp,"no-udp",0); - https_print_flag(sb,turn_params.no_tcp,"no-tcp",0); - https_print_flag(sb,turn_params.no_dtls,"no-dtls",0); - https_print_flag(sb,turn_params.no_tls,"no-tls",0); + https_print_flag(sb, turn_params.no_udp, "no-udp", 0); + https_print_flag(sb, turn_params.no_tcp, "no-tcp", 0); + https_print_flag(sb, turn_params.no_dtls, "no-dtls", 0); + https_print_flag(sb, turn_params.no_tls, "no-tls", 0); - https_print_flag(sb,(!turn_params.no_tlsv1 && !turn_params.no_tls),"TLSv1.0",0); - https_print_flag(sb,(!turn_params.no_tlsv1_1 && !turn_params.no_tls),"TLSv1.1",0); - https_print_flag(sb,(!turn_params.no_tlsv1_2 && !turn_params.no_tls),"TLSv1.2",0); + https_print_flag(sb, (!turn_params.no_tlsv1 && !turn_params.no_tls), "TLSv1.0", 0); + https_print_flag(sb, (!turn_params.no_tlsv1_1 && !turn_params.no_tls), "TLSv1.1", 0); + https_print_flag(sb, (!turn_params.no_tlsv1_2 && !turn_params.no_tls), "TLSv1.2", 0); - https_print_uint(sb,(unsigned long)turn_params.listener_port,"listener-port",0); - https_print_uint(sb,(unsigned long)turn_params.tls_listener_port,"tls-listener-port",0); - https_print_uint(sb,(unsigned long)turn_params.alt_listener_port,"alt-listener-port",0); - https_print_uint(sb,(unsigned long)turn_params.alt_tls_listener_port,"alt-tls-listener-port",0); + https_print_uint(sb, (unsigned long)turn_params.listener_port, "listener-port", 0); + https_print_uint(sb, (unsigned long)turn_params.tls_listener_port, "tls-listener-port", 0); + https_print_uint(sb, (unsigned long)turn_params.alt_listener_port, "alt-listener-port", 0); + https_print_uint(sb, (unsigned long)turn_params.alt_tls_listener_port, "alt-tls-listener-port", 0); - https_print_addr(sb,turn_params.external_ip,0,"External public IP"); + https_print_addr(sb, turn_params.external_ip, 0, "External public IP"); - https_print_empty_row(sb,2); + https_print_empty_row(sb, 2); - { - size_t an = https_print_addr_list(sb,&turn_params.aux_servers_list,1,"Aux server"); - an += https_print_addr_list(sb,&turn_params.alternate_servers_list,1,"Alternate server"); - an += https_print_addr_list(sb,&turn_params.tls_alternate_servers_list,1,"TLS alternate server"); + { + size_t an = https_print_addr_list(sb, &turn_params.aux_servers_list, 1, "Aux server"); + an += https_print_addr_list(sb, &turn_params.alternate_servers_list, 1, "Alternate server"); + an += https_print_addr_list(sb, &turn_params.tls_alternate_servers_list, 1, "TLS alternate server"); - if(an) { - https_print_empty_row(sb,2); - } - } + if (an) { + https_print_empty_row(sb, 2); + } + } - https_print_str_array(sb,turn_params.relay_addrs,turn_params.relays_number,"Relay addr"); + https_print_str_array(sb, turn_params.relay_addrs, turn_params.relays_number, "Relay addr"); - if(turn_params.relay_ifname[0]) - https_print_str(sb,turn_params.relay_ifname,"relay-ifname",0); + if (turn_params.relay_ifname[0]) + https_print_str(sb, turn_params.relay_ifname, "relay-ifname", 0); - https_print_flag(sb,turn_params.server_relay,"server-relay",0); + https_print_flag(sb, turn_params.server_relay, "server-relay", 0); - https_print_flag(sb,turn_params.no_udp_relay,"no-udp-relay","no-udp-relay"); - https_print_flag(sb,turn_params.no_tcp_relay,"no-tcp-relay","no-tcp-relay"); + https_print_flag(sb, turn_params.no_udp_relay, "no-udp-relay", "no-udp-relay"); + https_print_flag(sb, turn_params.no_tcp_relay, "no-tcp-relay", "no-tcp-relay"); - https_print_uint(sb,(unsigned long)turn_params.min_port,"min-port",0); - https_print_uint(sb,(unsigned long)turn_params.max_port,"max-port",0); + https_print_uint(sb, (unsigned long)turn_params.min_port, "min-port", 0); + https_print_uint(sb, (unsigned long)turn_params.max_port, "max-port", 0); - https_print_flag(sb,turn_params.no_multicast_peers,"no-multicast-peers","no-multicast-peers"); - https_print_flag(sb,turn_params.allow_loopback_peers,"allow-loopback-peers","allow-loopback-peers"); + https_print_flag(sb, turn_params.no_multicast_peers, "no-multicast-peers", "no-multicast-peers"); + https_print_flag(sb, turn_params.allow_loopback_peers, "allow-loopback-peers", "allow-loopback-peers"); - https_print_empty_row(sb,2); + https_print_empty_row(sb, 2); - if(turn_params.default_users_db.persistent_users_db.userdb[0]) { - switch(turn_params.default_users_db.userdb_type) { + if (turn_params.default_users_db.persistent_users_db.userdb[0]) { + switch (turn_params.default_users_db.userdb_type) { #if !defined(TURN_NO_SQLITE) - case TURN_USERDB_TYPE_SQLITE: - https_print_str(sb,"SQLite","DB type",0); - break; + case TURN_USERDB_TYPE_SQLITE: + https_print_str(sb, "SQLite", "DB type", 0); + break; #endif #if !defined(TURN_NO_PQ) - case TURN_USERDB_TYPE_PQ: - https_print_str(sb,"Postgres","DB type",0); - break; + case TURN_USERDB_TYPE_PQ: + https_print_str(sb, "Postgres", "DB type", 0); + break; #endif #if !defined(TURN_NO_MYSQL) - case TURN_USERDB_TYPE_MYSQL: - https_print_str(sb,"MySQL/MariaDB","DB type",0); - break; + case TURN_USERDB_TYPE_MYSQL: + https_print_str(sb, "MySQL/MariaDB", "DB type", 0); + break; #endif #if !defined(TURN_NO_MONGO) - case TURN_USERDB_TYPE_MONGO: - https_print_str(sb,"MongoDB","DB type",0); - break; + case TURN_USERDB_TYPE_MONGO: + https_print_str(sb, "MongoDB", "DB type", 0); + break; #endif #if !defined(TURN_NO_HIREDIS) - case TURN_USERDB_TYPE_REDIS: - https_print_str(sb,"redis","DB type",0); - break; + case TURN_USERDB_TYPE_REDIS: + https_print_str(sb, "redis", "DB type", 0); + break; #endif - default: - https_print_str(sb,"unknown","DB type",0); - }; - if(is_superuser()) { - https_print_str(sb,turn_params.default_users_db.persistent_users_db.userdb,"DB",0); - } - } else { - https_print_str(sb,"none","DB type",0); - https_print_str(sb,"none","DB",0); - } + default: + https_print_str(sb, "unknown", "DB type", 0); + }; + if (is_superuser()) { + https_print_str(sb, turn_params.default_users_db.persistent_users_db.userdb, "DB", 0); + } + } else { + https_print_str(sb, "none", "DB type", 0); + https_print_str(sb, "none", "DB", 0); + } #if !defined(TURN_NO_HIREDIS) - if(is_superuser()) { - if(turn_params.use_redis_statsdb && turn_params.redis_statsdb.connection_string_sanitized[0]) { - https_print_str(sb,turn_params.redis_statsdb.connection_string_sanitized,"Redis Statistics DB",0); - } - } + if (is_superuser()) { + if (turn_params.use_redis_statsdb && turn_params.redis_statsdb.connection_string_sanitized[0]) { + https_print_str(sb, turn_params.redis_statsdb.connection_string_sanitized, "Redis Statistics DB", 0); + } + } #endif - https_print_empty_row(sb,2); + https_print_empty_row(sb, 2); - if(turn_params.ct == TURN_CREDENTIALS_LONG_TERM) - https_print_flag(sb,1,"Long-term authorization mechanism",0); - else - https_print_flag(sb,1,"Anonymous credentials",0); - https_print_flag(sb,turn_params.use_auth_secret_with_timestamp,"TURN REST API support",0); - if(turn_params.use_auth_secret_with_timestamp) { + if (turn_params.ct == TURN_CREDENTIALS_LONG_TERM) + https_print_flag(sb, 1, "Long-term authorization mechanism", 0); + else + https_print_flag(sb, 1, "Anonymous credentials", 0); + https_print_flag(sb, turn_params.use_auth_secret_with_timestamp, "TURN REST API support", 0); + if (turn_params.use_auth_secret_with_timestamp) { - if(!turn_params.rest_api_separator || ((unsigned int)turn_params.rest_api_separator == (unsigned int)':')) { - https_print_str(sb,":","TURN REST API separator",0); - } else { - https_print_uint(sb,turn_params.rest_api_separator,"TURN REST API separator ASCII number",0); - } - } + if (!turn_params.rest_api_separator || ((unsigned int)turn_params.rest_api_separator == (unsigned int)':')) { + https_print_str(sb, ":", "TURN REST API separator", 0); + } else { + https_print_uint(sb, turn_params.rest_api_separator, "TURN REST API separator ASCII number", 0); + } + } - https_print_empty_row(sb,2); + https_print_empty_row(sb, 2); - if(is_superuser()) { - char * rn = get_realm(NULL)->options.name; - if(rn[0]) - https_print_str(sb,rn,"Default realm",0); - } + if (is_superuser()) { + char *rn = get_realm(NULL)->options.name; + if (rn[0]) + https_print_str(sb, rn, "Default realm", 0); + } - realm_params_t *rp = get_realm(current_eff_realm()); - if(!rp) rp = get_realm(NULL); + realm_params_t *rp = get_realm(current_eff_realm()); + if (!rp) + rp = get_realm(NULL); - https_print_str(sb,rp->options.name,"Admin session (current) realm",0); + https_print_str(sb, rp->options.name, "Admin session (current) realm", 0); - https_print_uint(sb,(unsigned long)rp->options.perf_options.total_quota,"current realm max number of sessions (total-quota)","cr-total-quota"); - https_print_uint(sb,(unsigned long)rp->options.perf_options.user_quota,"current realm max sessions per user (user-quota)","cr-user-quota"); - https_print_uint(sb,(unsigned long)rp->options.perf_options.max_bps,"current realm max-bps (per session)","cr-max-bps"); + https_print_uint(sb, (unsigned long)rp->options.perf_options.total_quota, + "current realm max number of sessions (total-quota)", "cr-total-quota"); + https_print_uint(sb, (unsigned long)rp->options.perf_options.user_quota, + "current realm max sessions per user (user-quota)", "cr-user-quota"); + https_print_uint(sb, (unsigned long)rp->options.perf_options.max_bps, "current realm max-bps (per session)", + "cr-max-bps"); - https_print_empty_row(sb,2); + https_print_empty_row(sb, 2); - https_print_uint(sb,(unsigned long)rp->status.total_current_allocs,"total-current-allocs",0); + https_print_uint(sb, (unsigned long)rp->status.total_current_allocs, "total-current-allocs", 0); - https_print_empty_row(sb,2); + https_print_empty_row(sb, 2); - https_print_uint(sb,(unsigned long)turn_params.total_quota,"Default total-quota (per realm)","total-quota"); - https_print_uint(sb,(unsigned long)turn_params.user_quota,"Default user-quota (per realm)","user-quota"); - https_print_uint(sb,(unsigned long)get_bps_capacity(),"Total bps-capacity (per server)","bps-capacity"); - https_print_uint(sb,(unsigned long)get_bps_capacity_allocated(),"Allocated bps-capacity (per server)",0); - https_print_uint(sb,(unsigned long)get_max_bps(),"Default max-bps (per session)","max-bps"); + https_print_uint(sb, (unsigned long)turn_params.total_quota, "Default total-quota (per realm)", "total-quota"); + https_print_uint(sb, (unsigned long)turn_params.user_quota, "Default user-quota (per realm)", "user-quota"); + https_print_uint(sb, (unsigned long)get_bps_capacity(), "Total bps-capacity (per server)", "bps-capacity"); + https_print_uint(sb, (unsigned long)get_bps_capacity_allocated(), "Allocated bps-capacity (per server)", 0); + https_print_uint(sb, (unsigned long)get_max_bps(), "Default max-bps (per session)", "max-bps"); - https_print_empty_row(sb,2); + https_print_empty_row(sb, 2); - https_print_ip_range_list(sb,&turn_params.ip_whitelist,"Whitelist IP (static)",NULL,0); - { - ip_range_list_t* l = get_ip_list("allowed"); - https_print_ip_range_list(sb,l,"Whitelist IP (dynamic)","allowed",1); - ip_list_free(l); - } + https_print_ip_range_list(sb, &turn_params.ip_whitelist, "Whitelist IP (static)", NULL, 0); + { + ip_range_list_t *l = get_ip_list("allowed"); + https_print_ip_range_list(sb, l, "Whitelist IP (dynamic)", "allowed", 1); + ip_list_free(l); + } - https_print_empty_row(sb,2); + https_print_empty_row(sb, 2); - https_print_ip_range_list(sb,&turn_params.ip_blacklist,"Blacklist IP (static)", NULL, 0); - { - ip_range_list_t* l = get_ip_list("denied"); - https_print_ip_range_list(sb,l,"Blacklist IP (dynamic)", "denied", 1); - ip_list_free(l); - } - } + https_print_ip_range_list(sb, &turn_params.ip_blacklist, "Blacklist IP (static)", NULL, 0); + { + ip_range_list_t *l = get_ip_list("denied"); + https_print_ip_range_list(sb, l, "Blacklist IP (dynamic)", "denied", 1); + ip_list_free(l); + } + } - str_buffer_append(sb,"\r\n
ParameterValue
\r\n"); + str_buffer_append(sb, "\r\n\r\n"); - https_finish_page(sb,s,0); - } - } + https_finish_page(sb, s, 0); + } + } } struct https_ps_arg { - struct str_buffer* sb; - size_t counter; - turn_time_t ct; - const char* client_protocol; - const char* user_pattern; - size_t max_sessions; - turnsession_id cs; + struct str_buffer *sb; + size_t counter; + turn_time_t ct; + const char *client_protocol; + const char *user_pattern; + size_t max_sessions; + turnsession_id cs; }; -static int https_print_session(ur_map_key_type key, ur_map_value_type value, void *arg) -{ - if(key && value && arg) { - struct https_ps_arg *csarg = (struct https_ps_arg*)arg; - struct str_buffer* sb = csarg->sb; - struct turn_session_info *tsi = (struct turn_session_info *)value; +static int https_print_session(ur_map_key_type key, ur_map_value_type value, void *arg) { + if (key && value && arg) { + struct https_ps_arg *csarg = (struct https_ps_arg *)arg; + struct str_buffer *sb = csarg->sb; + struct turn_session_info *tsi = (struct turn_session_info *)value; - if(current_eff_realm()[0] && strcmp(current_eff_realm(),tsi->realm)) - return 0; + if (current_eff_realm()[0] && strcmp(current_eff_realm(), tsi->realm)) + return 0; - if(csarg->user_pattern[0]) { - if(!strstr((char*)tsi->username,csarg->user_pattern)) { - return 0; - } - } + if (csarg->user_pattern[0]) { + if (!strstr((char *)tsi->username, csarg->user_pattern)) { + return 0; + } + } - if(csarg->cs == tsi->id) { - return 0; - } + if (csarg->cs == tsi->id) { + return 0; + } - { - const char *pn=csarg->client_protocol; - if(pn[0]) { - if(!strcmp(pn,"TLS") || !strcmp(pn,"tls") || !strcmp(pn,"Tls")) { - if((tsi->client_protocol != TLS_SOCKET)&&(tsi->client_protocol != TLS_SCTP_SOCKET)) - return 0; - } else if(!strcmp(pn,"DTLS") || !strcmp(pn,"dtls") || !strcmp(pn,"Dtls")) { - if(tsi->client_protocol != DTLS_SOCKET) - return 0; - } else if(!strcmp(pn,"TCP") || !strcmp(pn,"tcp") || !strcmp(pn,"Tcp")) { - if((tsi->client_protocol != TCP_SOCKET)&&(tsi->client_protocol != SCTP_SOCKET)) - return 0; - } else if(!strcmp(pn,"UDP") || !strcmp(pn,"udp") || !strcmp(pn,"Udp")) { - if(tsi->client_protocol != UDP_SOCKET) - return 0; - } else { - return 0; - } - } - } + { + const char *pn = csarg->client_protocol; + if (pn[0]) { + if (!strcmp(pn, "TLS") || !strcmp(pn, "tls") || !strcmp(pn, "Tls")) { + if ((tsi->client_protocol != TLS_SOCKET) && (tsi->client_protocol != TLS_SCTP_SOCKET)) + return 0; + } else if (!strcmp(pn, "DTLS") || !strcmp(pn, "dtls") || !strcmp(pn, "Dtls")) { + if (tsi->client_protocol != DTLS_SOCKET) + return 0; + } else if (!strcmp(pn, "TCP") || !strcmp(pn, "tcp") || !strcmp(pn, "Tcp")) { + if ((tsi->client_protocol != TCP_SOCKET) && (tsi->client_protocol != SCTP_SOCKET)) + return 0; + } else if (!strcmp(pn, "UDP") || !strcmp(pn, "udp") || !strcmp(pn, "Udp")) { + if (tsi->client_protocol != UDP_SOCKET) + return 0; + } else { + return 0; + } + } + } - if((unsigned long)csarg->counter<(unsigned long)csarg->max_sessions) { - str_buffer_append(sb,""); - str_buffer_append_sz(sb,(size_t)(csarg->counter+1)); - str_buffer_append(sb,""); - str_buffer_append_sid(sb,tsi->id); - str_buffer_append(sb,"
cancel"); - str_buffer_append(sb,""); - str_buffer_append(sb,(char*)tsi->username); - str_buffer_append(sb,""); - str_buffer_append(sb,tsi->realm); - str_buffer_append(sb,""); - str_buffer_append(sb,tsi->origin); - str_buffer_append(sb,""); - if(turn_time_before(csarg->ct, tsi->start_time)) { - str_buffer_append(sb,"undefined time\n"); - } else { - str_buffer_append_sz(sb,(size_t)(csarg->ct - tsi->start_time)); - } - str_buffer_append(sb,""); - if(turn_time_before(tsi->expiration_time,csarg->ct)) { - str_buffer_append(sb,"expired"); - } else { - str_buffer_append_sz(sb,(size_t)(tsi->expiration_time - csarg->ct)); - } - str_buffer_append(sb,""); - str_buffer_append(sb,socket_type_name(tsi->client_protocol)); - str_buffer_append(sb,""); - str_buffer_append(sb,socket_type_name(tsi->peer_protocol)); - str_buffer_append(sb,""); - { - if(!tsi->local_addr_data.saddr[0]) - addr_to_string(&(tsi->local_addr_data.addr),(uint8_t*)tsi->local_addr_data.saddr); - if(!tsi->remote_addr_data.saddr[0]) - addr_to_string(&(tsi->remote_addr_data.addr),(uint8_t*)tsi->remote_addr_data.saddr); - if(!tsi->relay_addr_data_ipv4.saddr[0]) - addr_to_string(&(tsi->relay_addr_data_ipv4.addr),(uint8_t*)tsi->relay_addr_data_ipv4.saddr); - if(!tsi->relay_addr_data_ipv6.saddr[0]) - addr_to_string(&(tsi->relay_addr_data_ipv6.addr),(uint8_t*)tsi->relay_addr_data_ipv6.saddr); - str_buffer_append(sb,tsi->remote_addr_data.saddr); - str_buffer_append(sb,""); - str_buffer_append(sb,tsi->local_addr_data.saddr); - str_buffer_append(sb,""); - str_buffer_append(sb,tsi->relay_addr_data_ipv4.saddr); - str_buffer_append(sb,""); - str_buffer_append(sb,tsi->relay_addr_data_ipv6.saddr); - str_buffer_append(sb,""); - str_buffer_append(sb,get_flag(tsi->enforce_fingerprints)); - str_buffer_append(sb,""); - str_buffer_append(sb,get_flag(tsi->is_mobile)); - str_buffer_append(sb,""); - str_buffer_append(sb,tsi->tls_method); - str_buffer_append(sb,""); - str_buffer_append(sb,tsi->tls_cipher); - str_buffer_append(sb,""); - str_buffer_append_sz(sb,(size_t)tsi->bps); - str_buffer_append(sb,""); - { - char str[1025]; - snprintf(str,sizeof(str)-1,"rp=%lu, rb=%lu, sp=%lu, sb=%lu\n",(unsigned long)(tsi->received_packets), (unsigned long)(tsi->received_bytes),(unsigned long)(tsi->sent_packets),(unsigned long)(tsi->sent_bytes)); - str_buffer_append(sb,str); - str_buffer_append(sb,""); - } - { - char str[1025]; - snprintf(str,sizeof(str)-1,"r=%lu, s=%lu, total=%lu (bytes per sec)\n",(unsigned long)(tsi->received_rate), (unsigned long)(tsi->sent_rate),(unsigned long)(tsi->total_rate)); - str_buffer_append(sb,str); - str_buffer_append(sb,""); - } + if ((unsigned long)csarg->counter < (unsigned long)csarg->max_sessions) { + str_buffer_append(sb, ""); + str_buffer_append_sz(sb, (size_t)(csarg->counter + 1)); + str_buffer_append(sb, ""); + str_buffer_append_sid(sb, tsi->id); + str_buffer_append(sb, "
cancel"); + str_buffer_append(sb, ""); + str_buffer_append(sb, (char *)tsi->username); + str_buffer_append(sb, ""); + str_buffer_append(sb, tsi->realm); + str_buffer_append(sb, ""); + str_buffer_append(sb, tsi->origin); + str_buffer_append(sb, ""); + if (turn_time_before(csarg->ct, tsi->start_time)) { + str_buffer_append(sb, "undefined time\n"); + } else { + str_buffer_append_sz(sb, (size_t)(csarg->ct - tsi->start_time)); + } + str_buffer_append(sb, ""); + if (turn_time_before(tsi->expiration_time, csarg->ct)) { + str_buffer_append(sb, "expired"); + } else { + str_buffer_append_sz(sb, (size_t)(tsi->expiration_time - csarg->ct)); + } + str_buffer_append(sb, ""); + str_buffer_append(sb, socket_type_name(tsi->client_protocol)); + str_buffer_append(sb, ""); + str_buffer_append(sb, socket_type_name(tsi->peer_protocol)); + str_buffer_append(sb, ""); + { + if (!tsi->local_addr_data.saddr[0]) + addr_to_string(&(tsi->local_addr_data.addr), (uint8_t *)tsi->local_addr_data.saddr); + if (!tsi->remote_addr_data.saddr[0]) + addr_to_string(&(tsi->remote_addr_data.addr), (uint8_t *)tsi->remote_addr_data.saddr); + if (!tsi->relay_addr_data_ipv4.saddr[0]) + addr_to_string(&(tsi->relay_addr_data_ipv4.addr), (uint8_t *)tsi->relay_addr_data_ipv4.saddr); + if (!tsi->relay_addr_data_ipv6.saddr[0]) + addr_to_string(&(tsi->relay_addr_data_ipv6.addr), (uint8_t *)tsi->relay_addr_data_ipv6.saddr); + str_buffer_append(sb, tsi->remote_addr_data.saddr); + str_buffer_append(sb, ""); + str_buffer_append(sb, tsi->local_addr_data.saddr); + str_buffer_append(sb, ""); + str_buffer_append(sb, tsi->relay_addr_data_ipv4.saddr); + str_buffer_append(sb, ""); + str_buffer_append(sb, tsi->relay_addr_data_ipv6.saddr); + str_buffer_append(sb, ""); + str_buffer_append(sb, get_flag(tsi->enforce_fingerprints)); + str_buffer_append(sb, ""); + str_buffer_append(sb, get_flag(tsi->is_mobile)); + str_buffer_append(sb, ""); + str_buffer_append(sb, tsi->tls_method); + str_buffer_append(sb, ""); + str_buffer_append(sb, tsi->tls_cipher); + str_buffer_append(sb, ""); + str_buffer_append_sz(sb, (size_t)tsi->bps); + str_buffer_append(sb, ""); + { + char str[1025]; + snprintf(str, sizeof(str) - 1, "rp=%lu, rb=%lu, sp=%lu, sb=%lu\n", (unsigned long)(tsi->received_packets), + (unsigned long)(tsi->received_bytes), (unsigned long)(tsi->sent_packets), + (unsigned long)(tsi->sent_bytes)); + str_buffer_append(sb, str); + str_buffer_append(sb, ""); + } + { + char str[1025]; + snprintf(str, sizeof(str) - 1, "r=%lu, s=%lu, total=%lu (bytes per sec)\n", + (unsigned long)(tsi->received_rate), (unsigned long)(tsi->sent_rate), + (unsigned long)(tsi->total_rate)); + str_buffer_append(sb, str); + str_buffer_append(sb, ""); + } - if(tsi->main_peers_size) { - size_t i; - for(i=0;imain_peers_size;++i) { - if(!(tsi->main_peers_data[i].saddr[0])) - addr_to_string(&(tsi->main_peers_data[i].addr),(uint8_t*)tsi->main_peers_data[i].saddr); - str_buffer_append(sb," "); - str_buffer_append(sb,tsi->main_peers_data[i].saddr); - str_buffer_append(sb," "); - } - if(tsi->extra_peers_size && tsi->extra_peers_data) { - for(i=0;iextra_peers_size;++i) { - if(!(tsi->extra_peers_data[i].saddr[0])) - addr_to_string(&(tsi->extra_peers_data[i].addr),(uint8_t*)tsi->extra_peers_data[i].saddr); - str_buffer_append(sb," "); - str_buffer_append(sb,tsi->extra_peers_data[i].saddr); - str_buffer_append(sb," "); - } - } - } - str_buffer_append(sb,""); - } - } + if (tsi->main_peers_size) { + size_t i; + for (i = 0; i < tsi->main_peers_size; ++i) { + if (!(tsi->main_peers_data[i].saddr[0])) + addr_to_string(&(tsi->main_peers_data[i].addr), (uint8_t *)tsi->main_peers_data[i].saddr); + str_buffer_append(sb, " "); + str_buffer_append(sb, tsi->main_peers_data[i].saddr); + str_buffer_append(sb, " "); + } + if (tsi->extra_peers_size && tsi->extra_peers_data) { + for (i = 0; i < tsi->extra_peers_size; ++i) { + if (!(tsi->extra_peers_data[i].saddr[0])) + addr_to_string(&(tsi->extra_peers_data[i].addr), (uint8_t *)tsi->extra_peers_data[i].saddr); + str_buffer_append(sb, " "); + str_buffer_append(sb, tsi->extra_peers_data[i].saddr); + str_buffer_append(sb, " "); + } + } + } + str_buffer_append(sb, ""); + } + } - csarg->counter += 1; - } - return 0; + csarg->counter += 1; + } + return 0; } -static size_t https_print_sessions(struct str_buffer* sb, const char* client_protocol, const char* user_pattern, size_t max_sessions, turnsession_id cs) -{ - struct https_ps_arg arg = {sb,0,0,client_protocol,user_pattern,max_sessions,cs}; +static size_t https_print_sessions(struct str_buffer *sb, const char *client_protocol, const char *user_pattern, + size_t max_sessions, turnsession_id cs) { + struct https_ps_arg arg = {sb, 0, 0, client_protocol, user_pattern, max_sessions, cs}; - arg.ct = turn_time(); + arg.ct = turn_time(); - ur_map_foreach_arg(adminserver.sessions, (foreachcb_arg_type)https_print_session, &arg); + ur_map_foreach_arg(adminserver.sessions, (foreachcb_arg_type)https_print_session, &arg); - return arg.counter; + return arg.counter; } -static void write_ps_page(ioa_socket_handle s, const char* client_protocol, const char* user_pattern, size_t max_sessions, turnsession_id cs) -{ - if(s && !ioa_socket_tobeclosed(s)) { +static void write_ps_page(ioa_socket_handle s, const char *client_protocol, const char *user_pattern, + size_t max_sessions, turnsession_id cs) { + if (s && !ioa_socket_tobeclosed(s)) { - if(!is_as_ok(s)) { - write_https_logon_page(s); - } else { + if (!is_as_ok(s)) { + write_https_logon_page(s); + } else { - struct str_buffer* sb = str_buffer_new(); + struct str_buffer *sb = str_buffer_new(); - https_print_page_header(sb); + https_print_page_header(sb); - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"
Filter:\r\n"); + str_buffer_append(sb, "\r\n"); + str_buffer_append(sb, "
Filter:\r\n"); - str_buffer_append(sb,"
Realm name: "); + str_buffer_append(sb, "
Realm name: "); - str_buffer_append(sb," Client protocol: "); + str_buffer_append(sb, " Client protocol: "); - str_buffer_append(sb," User name contains:

"); + str_buffer_append(sb, " User name contains:

"); - str_buffer_append(sb," Max number of output sessions in the page:
"); + str_buffer_append(sb, " Max number of output sessions in the page:
"); - str_buffer_append(sb,"
"); + str_buffer_append(sb, "
"); - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"\r\n"); + str_buffer_append(sb, "
\r\n"); + str_buffer_append(sb, "\r\n"); - str_buffer_append(sb,"
TURN Sessions:

\r\n"); - str_buffer_append(sb,"\r\n"); + str_buffer_append(sb, "
TURN Sessions:

NSession IDUserRealmOriginAge, secsExpires, secsClient protocolRelay protocolClient addrServer addrRelay addr (IPv4)Relay addr (IPv6)FingerprintsMobileTLS methodTLS cipherBPS (allocated)PacketsRatePeers
\r\n"); + str_buffer_append( + sb, + "\r\n"); - size_t total_sz = https_print_sessions(sb,client_protocol,user_pattern,max_sessions,cs); + size_t total_sz = https_print_sessions(sb, client_protocol, user_pattern, max_sessions, cs); - str_buffer_append(sb,"\r\n
NSession IDUserRealmOriginAge, secsExpires, " + "secsClient protocolRelay protocolClient addrServer addrRelay " + "addr (IPv4)Relay addr (IPv6)FingerprintsMobileTLS methodTLS " + "cipherBPS (allocated)PacketsRatePeers
\r\n"); + str_buffer_append(sb, "\r\n\r\n"); - str_buffer_append(sb,"
Total sessions = "); - str_buffer_append_sz(sb,total_sz); - str_buffer_append(sb,"
\r\n"); + str_buffer_append(sb, "
Total sessions = "); + str_buffer_append_sz(sb, total_sz); + str_buffer_append(sb, "
\r\n"); - https_finish_page(sb,s,0); - } - } + https_finish_page(sb, s, 0); + } + } } -static size_t https_print_users(struct str_buffer* sb) -{ - size_t ret = 0; - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->list_users) { - secrets_list_t users,realms; - init_secrets_list(&users); - init_secrets_list(&realms); - dbd->list_users((uint8_t*)current_eff_realm(),&users,&realms); +static size_t https_print_users(struct str_buffer *sb) { + size_t ret = 0; + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->list_users) { + secrets_list_t users, realms; + init_secrets_list(&users); + init_secrets_list(&realms); + dbd->list_users((uint8_t *)current_eff_realm(), &users, &realms); - size_t sz = get_secrets_list_size(&users); - size_t i; - for(i=0;i"); - str_buffer_append_sz(sb,i+1); - str_buffer_append(sb,""); - str_buffer_append(sb,""); - str_buffer_append(sb,get_secrets_list_elem(&users,i)); - str_buffer_append(sb,""); - if(!current_eff_realm()[0]) { - str_buffer_append(sb,""); - str_buffer_append(sb,get_secrets_list_elem(&realms,i)); - str_buffer_append(sb,""); - } - str_buffer_append(sb," delete"); - str_buffer_append(sb,""); - str_buffer_append(sb,""); - ++ret; - } + size_t sz = get_secrets_list_size(&users); + size_t i; + for (i = 0; i < sz; ++i) { + str_buffer_append(sb, ""); + str_buffer_append_sz(sb, i + 1); + str_buffer_append(sb, ""); + str_buffer_append(sb, ""); + str_buffer_append(sb, get_secrets_list_elem(&users, i)); + str_buffer_append(sb, ""); + if (!current_eff_realm()[0]) { + str_buffer_append(sb, ""); + str_buffer_append(sb, get_secrets_list_elem(&realms, i)); + str_buffer_append(sb, ""); + } + str_buffer_append(sb, " delete"); + str_buffer_append(sb, ""); + str_buffer_append(sb, ""); + ++ret; + } - clean_secrets_list(&users); - clean_secrets_list(&realms); - } + clean_secrets_list(&users); + clean_secrets_list(&realms); + } - return ret; + return ret; } -static void write_users_page(ioa_socket_handle s, const uint8_t *add_user, const uint8_t *add_realm, const char* msg) -{ - if(s && !ioa_socket_tobeclosed(s)) { +static void write_users_page(ioa_socket_handle s, const uint8_t *add_user, const uint8_t *add_realm, const char *msg) { + if (s && !ioa_socket_tobeclosed(s)) { - if(!is_as_ok(s)) { - write_https_logon_page(s); - } else { + if (!is_as_ok(s)) { + write_https_logon_page(s); + } else { - struct str_buffer* sb = str_buffer_new(); + struct str_buffer *sb = str_buffer_new(); - https_print_page_header(sb); + https_print_page_header(sb); - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"
Filter:\r\n"); + str_buffer_append(sb, "\r\n"); + str_buffer_append(sb, "
Filter:\r\n"); - str_buffer_append(sb,"
Realm name: "); + str_buffer_append(sb, "
Realm name: "); - str_buffer_append(sb,"
"); + str_buffer_append(sb, "
"); - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"\r\n"); + str_buffer_append(sb, "
\r\n"); + str_buffer_append(sb, "\r\n"); - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"
User:\r\n"); + str_buffer_append(sb, "\r\n"); + str_buffer_append(sb, "
User:\r\n"); - if(msg && msg[0]) { - str_buffer_append(sb,"
"); - str_buffer_append(sb,msg); - str_buffer_append(sb,"

"); - } + if (msg && msg[0]) { + str_buffer_append(sb, "
"); + str_buffer_append(sb, msg); + str_buffer_append(sb, "

"); + } - str_buffer_append(sb,"
Realm name:
\r\n"); + str_buffer_append(sb, "
Realm name:
\r\n"); - str_buffer_append(sb,"
User name:
\r\n"); + str_buffer_append(sb, "
User name:
\r\n"); - str_buffer_append(sb,"
Password:
\r\n"); + str_buffer_append(sb, "
Password:
\r\n"); - str_buffer_append(sb,"
Confirm password:

\r\n"); + str_buffer_append(sb, "
Confirm password:

\r\n"); - str_buffer_append(sb,"
"); + str_buffer_append(sb, "
"); - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"\r\n"); + str_buffer_append(sb, "
\r\n"); + str_buffer_append(sb, "\r\n"); - str_buffer_append(sb,"
Users:

\r\n"); - str_buffer_append(sb,"\r\n"); - str_buffer_append(sb,""); - if(!current_eff_realm()[0]) { - str_buffer_append(sb,""); - } - str_buffer_append(sb,""); - str_buffer_append(sb,"\r\n"); + str_buffer_append(sb, "
Users:

\r\n"); + str_buffer_append(sb, "
NNameRealm
\r\n"); + str_buffer_append(sb, ""); + if (!current_eff_realm()[0]) { + str_buffer_append(sb, ""); + } + str_buffer_append(sb, ""); + str_buffer_append(sb, "\r\n"); - size_t total_sz = https_print_users(sb); + size_t total_sz = https_print_users(sb); - str_buffer_append(sb,"\r\n
NNameRealm
\r\n"); + str_buffer_append(sb, "\r\n\r\n"); - str_buffer_append(sb,"
Total users = "); - str_buffer_append_sz(sb,total_sz); - str_buffer_append(sb,"
\r\n"); + str_buffer_append(sb, "
Total users = "); + str_buffer_append_sz(sb, total_sz); + str_buffer_append(sb, "
\r\n"); - https_finish_page(sb,s,0); - } - } + https_finish_page(sb, s, 0); + } + } } -static size_t https_print_secrets(struct str_buffer* sb) -{ - size_t ret = 0; - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->list_secrets) { - secrets_list_t secrets,realms; - init_secrets_list(&secrets); - init_secrets_list(&realms); - dbd->list_secrets((uint8_t*)current_eff_realm(),&secrets,&realms); +static size_t https_print_secrets(struct str_buffer *sb) { + size_t ret = 0; + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->list_secrets) { + secrets_list_t secrets, realms; + init_secrets_list(&secrets); + init_secrets_list(&realms); + dbd->list_secrets((uint8_t *)current_eff_realm(), &secrets, &realms); - size_t sz = get_secrets_list_size(&secrets); - size_t i; - for(i=0;i"); - str_buffer_append_sz(sb,i+1); - str_buffer_append(sb,""); - str_buffer_append(sb,""); - str_buffer_append(sb,get_secrets_list_elem(&secrets,i)); - str_buffer_append(sb,""); - if(!current_eff_realm()[0]) { - str_buffer_append(sb,""); - str_buffer_append(sb,get_secrets_list_elem(&realms,i)); - str_buffer_append(sb,""); - } - str_buffer_append(sb," delete"); - str_buffer_append(sb,""); - str_buffer_append(sb,""); - ++ret; - } + size_t sz = get_secrets_list_size(&secrets); + size_t i; + for (i = 0; i < sz; ++i) { + str_buffer_append(sb, ""); + str_buffer_append_sz(sb, i + 1); + str_buffer_append(sb, ""); + str_buffer_append(sb, ""); + str_buffer_append(sb, get_secrets_list_elem(&secrets, i)); + str_buffer_append(sb, ""); + if (!current_eff_realm()[0]) { + str_buffer_append(sb, ""); + str_buffer_append(sb, get_secrets_list_elem(&realms, i)); + str_buffer_append(sb, ""); + } + str_buffer_append(sb, " delete"); + str_buffer_append(sb, ""); + str_buffer_append(sb, ""); + ++ret; + } - clean_secrets_list(&secrets); - clean_secrets_list(&realms); - } + clean_secrets_list(&secrets); + clean_secrets_list(&realms); + } - return ret; + return ret; } -static void write_shared_secrets_page(ioa_socket_handle s, const char* add_secret, const char* add_realm, const char* msg) -{ - if(s && !ioa_socket_tobeclosed(s)) { +static void write_shared_secrets_page(ioa_socket_handle s, const char *add_secret, const char *add_realm, + const char *msg) { + if (s && !ioa_socket_tobeclosed(s)) { - if(!is_as_ok(s)) { - write_https_logon_page(s); - } else { + if (!is_as_ok(s)) { + write_https_logon_page(s); + } else { - struct str_buffer* sb = str_buffer_new(); + struct str_buffer *sb = str_buffer_new(); - https_print_page_header(sb); + https_print_page_header(sb); - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"
Filter:\r\n"); + str_buffer_append(sb, "\r\n"); + str_buffer_append(sb, "
Filter:\r\n"); - str_buffer_append(sb,"
Realm name: "); + str_buffer_append(sb, "
Realm name: "); - str_buffer_append(sb,"
"); + str_buffer_append(sb, "
"); - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"\r\n"); + str_buffer_append(sb, "
\r\n"); + str_buffer_append(sb, "\r\n"); - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"
Secret:\r\n"); + str_buffer_append(sb, "\r\n"); + str_buffer_append(sb, "
Secret:\r\n"); - if(msg && msg[0]) { - str_buffer_append(sb,"
"); - str_buffer_append(sb,msg); - str_buffer_append(sb,"

"); - } + if (msg && msg[0]) { + str_buffer_append(sb, "
"); + str_buffer_append(sb, msg); + str_buffer_append(sb, "

"); + } - str_buffer_append(sb,"
Realm name:
\r\n"); + str_buffer_append(sb, "
Realm name:
\r\n"); - str_buffer_append(sb,"
Secret:
\r\n"); + str_buffer_append(sb, "
Secret:
\r\n"); - str_buffer_append(sb,"
"); + str_buffer_append(sb, "
"); - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"\r\n"); + str_buffer_append(sb, "
\r\n"); + str_buffer_append(sb, "\r\n"); - str_buffer_append(sb,"
Shared secrets:

\r\n"); - str_buffer_append(sb,"\r\n"); - str_buffer_append(sb,""); - if(!current_eff_realm()[0]) { - str_buffer_append(sb,""); - } - str_buffer_append(sb,""); - str_buffer_append(sb,"\r\n"); + str_buffer_append(sb, "
Shared secrets:

\r\n"); + str_buffer_append(sb, "
NValueRealm
\r\n"); + str_buffer_append(sb, ""); + if (!current_eff_realm()[0]) { + str_buffer_append(sb, ""); + } + str_buffer_append(sb, ""); + str_buffer_append(sb, "\r\n"); - size_t total_sz = https_print_secrets(sb); + size_t total_sz = https_print_secrets(sb); - str_buffer_append(sb,"\r\n
NValueRealm
\r\n"); + str_buffer_append(sb, "\r\n\r\n"); - str_buffer_append(sb,"
Total secrets = "); - str_buffer_append_sz(sb,total_sz); - str_buffer_append(sb,"
\r\n"); + str_buffer_append(sb, "
Total secrets = "); + str_buffer_append_sz(sb, total_sz); + str_buffer_append(sb, "
\r\n"); - https_finish_page(sb,s,0); - } - } + https_finish_page(sb, s, 0); + } + } } -static size_t https_print_origins(struct str_buffer* sb) -{ - size_t ret = 0; - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->list_origins) { - secrets_list_t origins,realms; - init_secrets_list(&origins); - init_secrets_list(&realms); - dbd->list_origins((uint8_t*)current_eff_realm(),&origins,&realms); +static size_t https_print_origins(struct str_buffer *sb) { + size_t ret = 0; + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->list_origins) { + secrets_list_t origins, realms; + init_secrets_list(&origins); + init_secrets_list(&realms); + dbd->list_origins((uint8_t *)current_eff_realm(), &origins, &realms); - size_t sz = get_secrets_list_size(&origins); - size_t i; - for(i=0;i"); - str_buffer_append_sz(sb,i+1); - str_buffer_append(sb,""); - str_buffer_append(sb,""); - str_buffer_append(sb,get_secrets_list_elem(&origins,i)); - str_buffer_append(sb,""); - if(!current_eff_realm()[0]) { - str_buffer_append(sb,""); - str_buffer_append(sb,get_secrets_list_elem(&realms,i)); - str_buffer_append(sb,""); - } - if(is_superuser()) { - str_buffer_append(sb," delete"); - str_buffer_append(sb,""); - } - str_buffer_append(sb,""); - ++ret; - } + size_t sz = get_secrets_list_size(&origins); + size_t i; + for (i = 0; i < sz; ++i) { + str_buffer_append(sb, ""); + str_buffer_append_sz(sb, i + 1); + str_buffer_append(sb, ""); + str_buffer_append(sb, ""); + str_buffer_append(sb, get_secrets_list_elem(&origins, i)); + str_buffer_append(sb, ""); + if (!current_eff_realm()[0]) { + str_buffer_append(sb, ""); + str_buffer_append(sb, get_secrets_list_elem(&realms, i)); + str_buffer_append(sb, ""); + } + if (is_superuser()) { + str_buffer_append(sb, " delete"); + str_buffer_append(sb, ""); + } + str_buffer_append(sb, ""); + ++ret; + } - clean_secrets_list(&origins); - clean_secrets_list(&realms); - } + clean_secrets_list(&origins); + clean_secrets_list(&realms); + } - return ret; + return ret; } -static void write_origins_page(ioa_socket_handle s, const char* add_origin, const char* add_realm, const char* msg) -{ - if(s && !ioa_socket_tobeclosed(s)) { +static void write_origins_page(ioa_socket_handle s, const char *add_origin, const char *add_realm, const char *msg) { + if (s && !ioa_socket_tobeclosed(s)) { - if(!is_as_ok(s)) { - write_https_logon_page(s); - } else { + if (!is_as_ok(s)) { + write_https_logon_page(s); + } else { - struct str_buffer* sb = str_buffer_new(); + struct str_buffer *sb = str_buffer_new(); - https_print_page_header(sb); + https_print_page_header(sb); - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"
Filter:\r\n"); + str_buffer_append(sb, "\r\n"); + str_buffer_append(sb, "
Filter:\r\n"); - str_buffer_append(sb,"
Realm name: "); + str_buffer_append(sb, "
Realm name: "); - str_buffer_append(sb,"
"); + str_buffer_append(sb, "
"); - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"\r\n"); + str_buffer_append(sb, "
\r\n"); + str_buffer_append(sb, "\r\n"); - if(is_superuser()) { - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"
Origin:\r\n"); + if (is_superuser()) { + str_buffer_append(sb, "\r\n"); + str_buffer_append(sb, "
Origin:\r\n"); - if(msg && msg[0]) { - str_buffer_append(sb,"
"); - str_buffer_append(sb,msg); - str_buffer_append(sb,"

"); - } + if (msg && msg[0]) { + str_buffer_append(sb, "
"); + str_buffer_append(sb, msg); + str_buffer_append(sb, "

"); + } - str_buffer_append(sb,"
Realm name:
\r\n"); + str_buffer_append(sb, "
Realm name:
\r\n"); - str_buffer_append(sb,"
Origin:
\r\n"); + str_buffer_append(sb, "
Origin:
\r\n"); - str_buffer_append(sb,"
"); + str_buffer_append(sb, "
"); - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"\r\n"); - } + str_buffer_append(sb, "
\r\n"); + str_buffer_append(sb, "\r\n"); + } - str_buffer_append(sb,"
Origins:

\r\n"); - str_buffer_append(sb,"\r\n"); - str_buffer_append(sb,""); - if(!current_eff_realm()[0]) { - str_buffer_append(sb,""); - } - if(is_superuser()) { - str_buffer_append(sb,""); - } - str_buffer_append(sb,"\r\n"); + str_buffer_append(sb, "
Origins:

\r\n"); + str_buffer_append(sb, "
NValueRealm
\r\n"); + str_buffer_append(sb, ""); + if (!current_eff_realm()[0]) { + str_buffer_append(sb, ""); + } + if (is_superuser()) { + str_buffer_append(sb, ""); + } + str_buffer_append(sb, "\r\n"); - size_t total_sz = https_print_origins(sb); + size_t total_sz = https_print_origins(sb); - str_buffer_append(sb,"\r\n
NValueRealm
\r\n"); + str_buffer_append(sb, "\r\n\r\n"); - str_buffer_append(sb,"
Total origins = "); - str_buffer_append_sz(sb,total_sz); - str_buffer_append(sb,"
\r\n"); + str_buffer_append(sb, "
Total origins = "); + str_buffer_append_sz(sb, total_sz); + str_buffer_append(sb, "
\r\n"); - https_finish_page(sb,s,0); - } - } + https_finish_page(sb, s, 0); + } + } } -static size_t https_print_oauth_keys(struct str_buffer* sb) -{ - size_t ret = 0; - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->list_oauth_keys) { - secrets_list_t kids,teas,tss,lts,realms; - init_secrets_list(&kids); - init_secrets_list(&teas); - init_secrets_list(&tss); - init_secrets_list(<s); - init_secrets_list(&realms); - dbd->list_oauth_keys(&kids,&teas,&tss,<s,&realms); +static size_t https_print_oauth_keys(struct str_buffer *sb) { + size_t ret = 0; + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->list_oauth_keys) { + secrets_list_t kids, teas, tss, lts, realms; + init_secrets_list(&kids); + init_secrets_list(&teas); + init_secrets_list(&tss); + init_secrets_list(<s); + init_secrets_list(&realms); + dbd->list_oauth_keys(&kids, &teas, &tss, <s, &realms); - size_t sz = get_secrets_list_size(&kids); - size_t i; - for(i=0;i"); - str_buffer_append_sz(sb,i+1); - str_buffer_append(sb,""); - str_buffer_append(sb,""); - str_buffer_append(sb,get_secrets_list_elem(&kids,i)); - str_buffer_append(sb,""); + size_t sz = get_secrets_list_size(&kids); + size_t i; + for (i = 0; i < sz; ++i) { + str_buffer_append(sb, ""); + str_buffer_append_sz(sb, i + 1); + str_buffer_append(sb, ""); + str_buffer_append(sb, ""); + str_buffer_append(sb, get_secrets_list_elem(&kids, i)); + str_buffer_append(sb, ""); - str_buffer_append(sb," show "); + str_buffer_append(sb, " show "); - str_buffer_append(sb,""); - str_buffer_append(sb,get_secrets_list_elem(&tss,i)); - str_buffer_append(sb,""); - str_buffer_append(sb,""); - str_buffer_append(sb,get_secrets_list_elem(<s,i)); - str_buffer_append(sb,""); - str_buffer_append(sb,""); - str_buffer_append(sb,get_secrets_list_elem(&teas,i)); - str_buffer_append(sb,""); - str_buffer_append(sb,""); - str_buffer_append(sb,get_secrets_list_elem(&realms,i)); - str_buffer_append(sb,""); + str_buffer_append(sb, ""); + str_buffer_append(sb, get_secrets_list_elem(&tss, i)); + str_buffer_append(sb, ""); + str_buffer_append(sb, ""); + str_buffer_append(sb, get_secrets_list_elem(<s, i)); + str_buffer_append(sb, ""); + str_buffer_append(sb, ""); + str_buffer_append(sb, get_secrets_list_elem(&teas, i)); + str_buffer_append(sb, ""); + str_buffer_append(sb, ""); + str_buffer_append(sb, get_secrets_list_elem(&realms, i)); + str_buffer_append(sb, ""); - { - str_buffer_append(sb," delete"); - str_buffer_append(sb,""); - } - str_buffer_append(sb,""); - ++ret; - } + { + str_buffer_append(sb, " delete"); + str_buffer_append(sb, ""); + } + str_buffer_append(sb, ""); + ++ret; + } - clean_secrets_list(&kids); - clean_secrets_list(&teas); - clean_secrets_list(&tss); - clean_secrets_list(<s); - clean_secrets_list(&realms); - } + clean_secrets_list(&kids); + clean_secrets_list(&teas); + clean_secrets_list(&tss); + clean_secrets_list(<s); + clean_secrets_list(&realms); + } - return ret; + return ret; } -static void write_https_oauth_show_keys(ioa_socket_handle s, const char* kid) -{ - if(s && !ioa_socket_tobeclosed(s)) { +static void write_https_oauth_show_keys(ioa_socket_handle s, const char *kid) { + if (s && !ioa_socket_tobeclosed(s)) { - if(!is_as_ok(s)) { - write_https_logon_page(s); - } else if(!is_superuser()) { - write_https_home_page(s); - } else { + if (!is_as_ok(s)) { + write_https_logon_page(s); + } else if (!is_superuser()) { + write_https_home_page(s); + } else { - struct str_buffer* sb = str_buffer_new(); + struct str_buffer *sb = str_buffer_new(); - https_print_page_header(sb); + https_print_page_header(sb); - str_buffer_append(sb,"back to oauth list

\r\n"); + str_buffer_append(sb, "back to oauth list

\r\n"); - if(kid && kid[0]) { - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->get_oauth_key) { - oauth_key_data_raw key; - if((*dbd->get_oauth_key)((const uint8_t*)kid,&key)<0) { - str_buffer_append(sb,"data retrieval error"); - } else { + if (kid && kid[0]) { + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->get_oauth_key) { + oauth_key_data_raw key; + if ((*dbd->get_oauth_key)((const uint8_t *)kid, &key) < 0) { + str_buffer_append(sb, "data retrieval error"); + } else { - oauth_key_data okd; - memset(&okd, 0, sizeof(okd)); + oauth_key_data okd; + memset(&okd, 0, sizeof(okd)); - convert_oauth_key_data_raw(&key, &okd); + convert_oauth_key_data_raw(&key, &okd); - char err_msg[1025] = "\0"; - size_t err_msg_size = sizeof(err_msg) - 1; + char err_msg[1025] = "\0"; + size_t err_msg_size = sizeof(err_msg) - 1; - oauth_key okey; - memset(&okey, 0, sizeof(okey)); + oauth_key okey; + memset(&okey, 0, sizeof(okey)); - if (convert_oauth_key_data(&okd, &okey, err_msg, err_msg_size) < 0) { - str_buffer_append(sb,err_msg); - } else { + if (convert_oauth_key_data(&okd, &okey, err_msg, err_msg_size) < 0) { + str_buffer_append(sb, err_msg); + } else { - str_buffer_append(sb,"\r\n"); + str_buffer_append(sb, "
\r\n"); - if(key.ikm_key[0]) { - str_buffer_append(sb,"\r\n"); - } + if (key.ikm_key[0]) { + str_buffer_append(sb, "\r\n"); + } - str_buffer_append(sb,"
Base64-encoded key:"); - str_buffer_append(sb,key.ikm_key); - str_buffer_append(sb,"
Base64-encoded key:"); + str_buffer_append(sb, key.ikm_key); + str_buffer_append(sb, "
\r\n"); - } - } - } - } + str_buffer_append(sb, "\r\n"); + } + } + } + } - https_finish_page(sb,s,0); - } - } + https_finish_page(sb, s, 0); + } + } } -static void write_https_oauth_page(ioa_socket_handle s, - const char* add_kid, - const char* add_ikm, - const char* add_tea, - const char *add_ts, - const char* add_lt, - const char* add_realm, - const char* msg) -{ - if(s && !ioa_socket_tobeclosed(s)) { +static void write_https_oauth_page(ioa_socket_handle s, const char *add_kid, const char *add_ikm, const char *add_tea, + const char *add_ts, const char *add_lt, const char *add_realm, const char *msg) { + if (s && !ioa_socket_tobeclosed(s)) { - if(!is_as_ok(s)) { - write_https_logon_page(s); - } else if(!is_superuser()) { - write_https_home_page(s); - } else { + if (!is_as_ok(s)) { + write_https_logon_page(s); + } else if (!is_superuser()) { + write_https_home_page(s); + } else { - struct str_buffer* sb = str_buffer_new(); + struct str_buffer *sb = str_buffer_new(); - https_print_page_header(sb); + https_print_page_header(sb); - { - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"
oAuth key:\r\n"); + { + str_buffer_append(sb, "\r\n"); + str_buffer_append(sb, "
oAuth key:\r\n"); - if(msg && msg[0]) { - str_buffer_append(sb,"
"); - str_buffer_append(sb,msg); - str_buffer_append(sb,"

"); - } + if (msg && msg[0]) { + str_buffer_append(sb, "
"); + str_buffer_append(sb, msg); + str_buffer_append(sb, "

"); + } - str_buffer_append(sb,"\r\n
"); + str_buffer_append(sb, "\r\n"); + str_buffer_append(sb, "\r\n"); - str_buffer_append(sb,"\r\n
"); - { - if(!add_kid) add_kid=""; + { + if (!add_kid) + add_kid = ""; - str_buffer_append(sb,"
KID (required):
\r\n"); - } + str_buffer_append(sb, "
KID (required):
\r\n"); + } - str_buffer_append(sb,"
"); + str_buffer_append(sb, ""); - { - if(!add_ts) add_ts=""; + { + if (!add_ts) + add_ts = ""; - str_buffer_append(sb,"
Timestamp, secs (optional):
\r\n"); - } + str_buffer_append(sb, "
Timestamp, secs (optional):
\r\n"); + } - str_buffer_append(sb,"
"); + str_buffer_append(sb, ""); - { - if(!add_lt) add_lt=""; + { + if (!add_lt) + add_lt = ""; - str_buffer_append(sb,"
Lifetime, secs (optional):
\r\n"); - } + str_buffer_append(sb, "
Lifetime, secs (optional):
\r\n"); + } - str_buffer_append(sb,"
"); + str_buffer_append(sb, "
"); - { - if(!add_ikm) add_ikm = ""; + { + if (!add_ikm) + add_ikm = ""; - str_buffer_append(sb,"
Base64-encoded input keying material (required):
"); - str_buffer_append(sb,"
\r\n"); - } + str_buffer_append(sb, "
Base64-encoded input keying material (required):
"); + str_buffer_append(sb, "
\r\n"); + } - str_buffer_append(sb,"
"); + str_buffer_append(sb, ""); - { - if(!add_realm) add_realm = ""; + { + if (!add_realm) + add_realm = ""; - str_buffer_append(sb,"
Realm (optional):
\r\n"); - } + str_buffer_append(sb, "
Realm (optional):
\r\n"); + } - str_buffer_append(sb,"
"); + str_buffer_append(sb, ""); - { - str_buffer_append(sb,"
Token encryption algorithm (required):
\r\n"); + { + str_buffer_append(sb, "
Token encryption algorithm (required):
\r\n"); - if(!add_tea || !add_tea[0]) - add_tea = "A256GCM"; + if (!add_tea || !add_tea[0]) + add_tea = "A256GCM"; - str_buffer_append(sb,"A128GCM\r\n
\r\n"); + str_buffer_append(sb, "A128GCM\r\n
\r\n"); - str_buffer_append(sb,"A256GCM\r\n
\r\n"); - } + str_buffer_append(sb, "A256GCM\r\n
\r\n"); + } - str_buffer_append(sb,"
\r\n"); + str_buffer_append(sb, "
\r\n"); - str_buffer_append(sb,"
"); + str_buffer_append(sb, "
"); - str_buffer_append(sb,"
\r\n"); - str_buffer_append(sb,"\r\n"); - } + str_buffer_append(sb, "
\r\n"); + str_buffer_append(sb, "\r\n"); + } - str_buffer_append(sb,"
OAuth keys:

\r\n"); - str_buffer_append(sb,"\r\n"); - str_buffer_append(sb,""); - str_buffer_append(sb,""); - str_buffer_append(sb,""); - str_buffer_append(sb,""); - str_buffer_append(sb,""); - str_buffer_append(sb,""); - str_buffer_append(sb,"\r\n"); + str_buffer_append(sb, "
OAuth keys:

\r\n"); + str_buffer_append(sb, "
NKIDkeysTimestamp, secsLifetime,secsToken encryption algorithmRealm
\r\n"); + str_buffer_append(sb, ""); + str_buffer_append(sb, ""); + str_buffer_append(sb, ""); + str_buffer_append(sb, ""); + str_buffer_append(sb, ""); + str_buffer_append(sb, ""); + str_buffer_append(sb, "\r\n"); - size_t total_sz = https_print_oauth_keys(sb); + size_t total_sz = https_print_oauth_keys(sb); - str_buffer_append(sb,"\r\n
NKIDkeysTimestamp, secsLifetime,secsToken encryption algorithmRealm
\r\n"); + str_buffer_append(sb, "\r\n\r\n"); - str_buffer_append(sb,"
Total oAuth keys = "); - str_buffer_append_sz(sb,total_sz); - str_buffer_append(sb,"
\r\n"); + str_buffer_append(sb, "
Total oAuth keys = "); + str_buffer_append_sz(sb, total_sz); + str_buffer_append(sb, "
\r\n"); - https_finish_page(sb,s,0); - } - } + https_finish_page(sb, s, 0); + } + } } -static void handle_toggle_request(ioa_socket_handle s, struct http_request* hr) -{ - if(s && hr) { - const char *param = get_http_header_value(hr, HR_UPDATE_PARAMETER, NULL); - toggle_param(param); - } +static void handle_toggle_request(ioa_socket_handle s, struct http_request *hr) { + if (s && hr) { + const char *param = get_http_header_value(hr, HR_UPDATE_PARAMETER, NULL); + toggle_param(param); + } } -static void handle_update_request(ioa_socket_handle s, struct http_request* hr) -{ - if(s && hr) { - { - const char *param = get_http_header_value(hr, HR_UPDATE_PARAMETER, NULL); - if(param) { - update_param(param,get_http_header_value(hr,param,"")); - } - } +static void handle_update_request(ioa_socket_handle s, struct http_request *hr) { + if (s && hr) { + { + const char *param = get_http_header_value(hr, HR_UPDATE_PARAMETER, NULL); + if (param) { + update_param(param, get_http_header_value(hr, param, "")); + } + } - { - const char* eip = get_http_header_value(hr, HR_DELETE_IP, NULL); - if(eip && eip[0]) { - char* ip = evhttp_decode_uri(eip); - const char* r = get_http_header_value(hr, HR_DELETE_IP_REALM,""); - const char* kind = get_http_header_value(hr, HR_DELETE_IP_KIND,""); + { + const char *eip = get_http_header_value(hr, HR_DELETE_IP, NULL); + if (eip && eip[0]) { + char *ip = evhttp_decode_uri(eip); + const char *r = get_http_header_value(hr, HR_DELETE_IP_REALM, ""); + const char *kind = get_http_header_value(hr, HR_DELETE_IP_KIND, ""); - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->set_permission_ip) { + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->set_permission_ip) { - if(!r || !r[0]) { - r = current_realm(); - } + if (!r || !r[0]) { + r = current_realm(); + } - if(current_realm()[0] && strcmp(current_realm(),r)) { - //forbidden - } else if (strcmp(kind, "allowed") != 0 && strcmp(kind, "denied") != 0) { - //forbidden - } else { + if (current_realm()[0] && strcmp(current_realm(), r)) { + // forbidden + } else if (strcmp(kind, "allowed") != 0 && strcmp(kind, "denied") != 0) { + // forbidden + } else { - uint8_t realm[STUN_MAX_REALM_SIZE+1]="\0"; - STRCPY(realm,r); + uint8_t realm[STUN_MAX_REALM_SIZE + 1] = "\0"; + STRCPY(realm, r); - dbd->set_permission_ip(kind, realm, ip, 1); - } - } - free(ip); - } - } + dbd->set_permission_ip(kind, realm, ip, 1); + } + } + free(ip); + } + } - { - const char* eip = get_http_header_value(hr, HR_ADD_IP,NULL); - if(eip && eip[0]) { - char* ip = evhttp_decode_uri(eip); + { + const char *eip = get_http_header_value(hr, HR_ADD_IP, NULL); + if (eip && eip[0]) { + char *ip = evhttp_decode_uri(eip); - if(check_ip_list_range(ip)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong address range format: %s\n", ip); - } else { + if (check_ip_list_range(ip) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong address range format: %s\n", ip); + } else { - const char* r = get_http_header_value(hr, HR_ADD_IP_REALM,""); - const char* kind = get_http_header_value(hr, HR_ADD_IP_KIND,""); + const char *r = get_http_header_value(hr, HR_ADD_IP_REALM, ""); + const char *kind = get_http_header_value(hr, HR_ADD_IP_KIND, ""); - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->set_permission_ip) { + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->set_permission_ip) { - if(!r || !r[0]) { - r = current_realm(); - } + if (!r || !r[0]) { + r = current_realm(); + } - if(current_realm()[0] && strcmp(current_realm(),r)) { - //forbidden - } else if (strcmp(kind, "allowed") != 0 && strcmp(kind, "denied") != 0) { - //forbidden - } else { + if (current_realm()[0] && strcmp(current_realm(), r)) { + // forbidden + } else if (strcmp(kind, "allowed") != 0 && strcmp(kind, "denied") != 0) { + // forbidden + } else { - uint8_t realm[STUN_MAX_REALM_SIZE+1]="\0"; - STRCPY(realm,r); + uint8_t realm[STUN_MAX_REALM_SIZE + 1] = "\0"; + STRCPY(realm, r); - dbd->set_permission_ip(kind, realm, ip, 0); - } - } - } - free(ip); - } - } - } + dbd->set_permission_ip(kind, realm, ip, 0); + } + } + } + free(ip); + } + } + } } -static void handle_logon_request(ioa_socket_handle s, struct http_request* hr) -{ - if(s && hr) { - const char *uname = get_http_header_value(hr, HR_USERNAME, NULL); - const char *pwd = get_http_header_value(hr, HR_PASSWORD, NULL); +static void handle_logon_request(ioa_socket_handle s, struct http_request *hr) { + if (s && hr) { + const char *uname = get_http_header_value(hr, HR_USERNAME, NULL); + const char *pwd = get_http_header_value(hr, HR_PASSWORD, NULL); - struct admin_session* as = (struct admin_session*)s->special_session; - if(!as) { - as = (struct admin_session*)calloc(sizeof(struct admin_session), 1); - s->special_session = as; - s->special_session_size = sizeof(struct admin_session); - } + struct admin_session *as = (struct admin_session *)s->special_session; + if (!as) { + as = (struct admin_session *)calloc(sizeof(struct admin_session), 1); + s->special_session = as; + s->special_session_size = sizeof(struct admin_session); + } - if(!(as->as_ok) && uname && is_secure_string((const uint8_t*)uname,1) && pwd) { - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->get_admin_user) { - password_t password; - char realm[STUN_MAX_REALM_SIZE+1]="\0"; - if((*(dbd->get_admin_user))((const uint8_t*)uname,(uint8_t*)realm,password)>=0) { - if(!check_password(pwd,(char*)password)) { - STRCPY(as->as_login,uname); - STRCPY(as->as_realm,realm); - as->as_eff_realm[0]=0; - as->as_ok = 1; - as->number_of_user_sessions = DEFAULT_CLI_MAX_OUTPUT_SESSIONS; - } - } - } - } - } + if (!(as->as_ok) && uname && is_secure_string((const uint8_t *)uname, 1) && pwd) { + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->get_admin_user) { + password_t password; + char realm[STUN_MAX_REALM_SIZE + 1] = "\0"; + if ((*(dbd->get_admin_user))((const uint8_t *)uname, (uint8_t *)realm, password) >= 0) { + if (!check_password(pwd, (char *)password)) { + STRCPY(as->as_login, uname); + STRCPY(as->as_realm, realm); + as->as_eff_realm[0] = 0; + as->as_ok = 1; + as->number_of_user_sessions = DEFAULT_CLI_MAX_OUTPUT_SESSIONS; + } + } + } + } + } } -static void handle_logout_request(ioa_socket_handle s, struct http_request* hr) -{ - UNUSED_ARG(hr); - if(s) { - struct admin_session* as = (struct admin_session*)s->special_session; - if(as) { - as->as_login[0] = 0; - as->as_ok = 0; - as->as_realm[0] = 0; - as->as_eff_realm[0] = 0; - } - } +static void handle_logout_request(ioa_socket_handle s, struct http_request *hr) { + UNUSED_ARG(hr); + if (s) { + struct admin_session *as = (struct admin_session *)s->special_session; + if (as) { + as->as_login[0] = 0; + as->as_ok = 0; + as->as_realm[0] = 0; + as->as_eff_realm[0] = 0; + } + } } -static void handle_https(ioa_socket_handle s, ioa_network_buffer_handle nbh) -{ - current_socket = s; +static void handle_https(ioa_socket_handle s, ioa_network_buffer_handle nbh) { + current_socket = s; - if(turn_params.verbose) { - if(nbh) { - ((char*)ioa_network_buffer_data(nbh))[ioa_network_buffer_get_size(nbh)] = 0; - if(!strstr((char*)ioa_network_buffer_data(nbh),"pwd")) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: HTTPS connection input: %s\n", __FUNCTION__, (char*)ioa_network_buffer_data(nbh)); - } - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: HTTPS connection initial input\n", __FUNCTION__); - } - } + if (turn_params.verbose) { + if (nbh) { + ((char *)ioa_network_buffer_data(nbh))[ioa_network_buffer_get_size(nbh)] = 0; + if (!strstr((char *)ioa_network_buffer_data(nbh), "pwd")) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: HTTPS connection input: %s\n", __FUNCTION__, + (char *)ioa_network_buffer_data(nbh)); + } + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: HTTPS connection initial input\n", __FUNCTION__); + } + } - if(!nbh) { - write_https_logon_page(s); - } else { - ((char*)ioa_network_buffer_data(nbh))[ioa_network_buffer_get_size(nbh)] = 0; - struct http_request* hr = parse_http_request((char*)ioa_network_buffer_data(nbh)); - if(!hr) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: wrong HTTPS request (I cannot parse it)\n", __FUNCTION__); - write_https_logon_page(s); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: HTTPS request, path %s\n", __FUNCTION__,hr->path); + if (!nbh) { + write_https_logon_page(s); + } else { + ((char *)ioa_network_buffer_data(nbh))[ioa_network_buffer_get_size(nbh)] = 0; + struct http_request *hr = parse_http_request((char *)ioa_network_buffer_data(nbh)); + if (!hr) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: wrong HTTPS request (I cannot parse it)\n", __FUNCTION__); + write_https_logon_page(s); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: HTTPS request, path %s\n", __FUNCTION__, hr->path); - AS_FORM form = get_form(hr->path); + AS_FORM form = get_form(hr->path); - switch(form) { - case AS_FORM_PC: { - if(is_as_ok(s)) { - const char *realm0 = get_http_header_value(hr, HR_REALM, current_realm()); - if(!is_superuser()) - realm0 = current_realm(); - strncpy(current_eff_realm(),realm0,STUN_MAX_REALM_SIZE); - write_pc_page(s); - } else { - write_https_logon_page(s); - } - break; - } - case AS_FORM_PS: { - if(is_as_ok(s)) { - const char *realm0 = get_http_header_value(hr, HR_REALM, current_realm()); - if(!is_superuser()) - realm0 = current_realm(); - strncpy(current_eff_realm(),realm0,STUN_MAX_REALM_SIZE); + switch (form) { + case AS_FORM_PC: { + if (is_as_ok(s)) { + const char *realm0 = get_http_header_value(hr, HR_REALM, current_realm()); + if (!is_superuser()) + realm0 = current_realm(); + strncpy(current_eff_realm(), realm0, STUN_MAX_REALM_SIZE); + write_pc_page(s); + } else { + write_https_logon_page(s); + } + break; + } + case AS_FORM_PS: { + if (is_as_ok(s)) { + const char *realm0 = get_http_header_value(hr, HR_REALM, current_realm()); + if (!is_superuser()) + realm0 = current_realm(); + strncpy(current_eff_realm(), realm0, STUN_MAX_REALM_SIZE); - const char* client_protocol = get_http_header_value(hr, HR_CLIENT_PROTOCOL, ""); + const char *client_protocol = get_http_header_value(hr, HR_CLIENT_PROTOCOL, ""); - const char* user_pattern = get_http_header_value(hr, HR_USER_PATTERN, ""); + const char *user_pattern = get_http_header_value(hr, HR_USER_PATTERN, ""); - turnsession_id csid=0; - const char* ssid = get_http_header_value(hr, HR_CANCEL_SESSION, NULL); - if(ssid) { - https_cancel_session(ssid); - csid = (turnsession_id)strtoull(ssid,NULL,10); - } + turnsession_id csid = 0; + const char *ssid = get_http_header_value(hr, HR_CANCEL_SESSION, NULL); + if (ssid) { + https_cancel_session(ssid); + csid = (turnsession_id)strtoull(ssid, NULL, 10); + } - size_t max_sessions = current_max_output_sessions(); - const char* s_max_sessions = get_http_header_value(hr, HR_MAX_SESSIONS,NULL); - if(s_max_sessions) { - max_sessions=strtoul(s_max_sessions,NULL,10); - if(!max_sessions) max_sessions = current_max_output_sessions(); - set_current_max_output_sessions(max_sessions); - } + size_t max_sessions = current_max_output_sessions(); + const char *s_max_sessions = get_http_header_value(hr, HR_MAX_SESSIONS, NULL); + if (s_max_sessions) { + max_sessions = strtoul(s_max_sessions, NULL, 10); + if (!max_sessions) + max_sessions = current_max_output_sessions(); + set_current_max_output_sessions(max_sessions); + } - if(!max_sessions) max_sessions = DEFAULT_CLI_MAX_OUTPUT_SESSIONS; + if (!max_sessions) + max_sessions = DEFAULT_CLI_MAX_OUTPUT_SESSIONS; - write_ps_page(s,client_protocol,user_pattern,max_sessions,csid); - } else { - write_https_logon_page(s); - } - break; - } - case AS_FORM_USERS: { - if(is_as_ok(s)) { - { - const char *realm0 = get_http_header_value(hr, HR_REALM, current_realm()); - if(!is_superuser()) - realm0 = current_realm(); - strncpy(current_eff_realm(),realm0,STUN_MAX_REALM_SIZE); - } + write_ps_page(s, client_protocol, user_pattern, max_sessions, csid); + } else { + write_https_logon_page(s); + } + break; + } + case AS_FORM_USERS: { + if (is_as_ok(s)) { + { + const char *realm0 = get_http_header_value(hr, HR_REALM, current_realm()); + if (!is_superuser()) + realm0 = current_realm(); + strncpy(current_eff_realm(), realm0, STUN_MAX_REALM_SIZE); + } - { - const uint8_t *user = (const uint8_t*)get_http_header_value(hr, HR_DELETE_USER, NULL); - if(user && user[0]) { - const uint8_t *realm = (const uint8_t*)get_http_header_value(hr, HR_DELETE_REALM, ""); - if(!is_superuser()) { - realm = (const uint8_t*)current_realm(); - } - if(realm && realm[0]) { - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->del_user) { - uint8_t u[STUN_MAX_USERNAME_SIZE+1]; - uint8_t r[STUN_MAX_REALM_SIZE+1]; - STRCPY(u,user); - STRCPY(r,realm); - dbd->del_user(u,r); - } - } - } - } + { + const uint8_t *user = (const uint8_t *)get_http_header_value(hr, HR_DELETE_USER, NULL); + if (user && user[0]) { + const uint8_t *realm = (const uint8_t *)get_http_header_value(hr, HR_DELETE_REALM, ""); + if (!is_superuser()) { + realm = (const uint8_t *)current_realm(); + } + if (realm && realm[0]) { + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->del_user) { + uint8_t u[STUN_MAX_USERNAME_SIZE + 1]; + uint8_t r[STUN_MAX_REALM_SIZE + 1]; + STRCPY(u, user); + STRCPY(r, realm); + dbd->del_user(u, r); + } + } + } + } - const uint8_t *add_realm = (const uint8_t*)current_eff_realm(); - const uint8_t *add_user = (const uint8_t*)get_http_header_value(hr, HR_ADD_USER,""); - const char* msg = ""; - if(wrong_html_name((const char*)add_user)) { - msg = "Error: wrong user name"; - add_user = (const uint8_t*)""; - } - if(add_user[0]) { - add_realm = (const uint8_t*)get_http_header_value(hr, HR_ADD_REALM, current_realm()); - if(!is_superuser()) { - add_realm = (const uint8_t*)current_realm(); - } - if(!add_realm[0]) { - add_realm=(const uint8_t*)current_eff_realm(); - } - if(!add_realm[0]) { - add_realm = (const uint8_t*)get_realm(NULL)->options.name; - } - if(wrong_html_name((const char*)add_realm)) { - msg = "Error: wrong realm name"; - add_realm = (const uint8_t*)""; - } - if(add_realm[0]) { - const uint8_t *pwd = (const uint8_t*)get_http_header_value(hr, HR_PASSWORD, NULL); - const uint8_t *pwd1 = (const uint8_t*)get_http_header_value(hr, HR_PASSWORD1, NULL); - if(pwd && pwd1 && pwd[0] && pwd1[0] && !strcmp((const char*)pwd,(const char*)pwd1)) { + const uint8_t *add_realm = (const uint8_t *)current_eff_realm(); + const uint8_t *add_user = (const uint8_t *)get_http_header_value(hr, HR_ADD_USER, ""); + const char *msg = ""; + if (wrong_html_name((const char *)add_user)) { + msg = "Error: wrong user name"; + add_user = (const uint8_t *)""; + } + if (add_user[0]) { + add_realm = (const uint8_t *)get_http_header_value(hr, HR_ADD_REALM, current_realm()); + if (!is_superuser()) { + add_realm = (const uint8_t *)current_realm(); + } + if (!add_realm[0]) { + add_realm = (const uint8_t *)current_eff_realm(); + } + if (!add_realm[0]) { + add_realm = (const uint8_t *)get_realm(NULL)->options.name; + } + if (wrong_html_name((const char *)add_realm)) { + msg = "Error: wrong realm name"; + add_realm = (const uint8_t *)""; + } + if (add_realm[0]) { + const uint8_t *pwd = (const uint8_t *)get_http_header_value(hr, HR_PASSWORD, NULL); + const uint8_t *pwd1 = (const uint8_t *)get_http_header_value(hr, HR_PASSWORD1, NULL); + if (pwd && pwd1 && pwd[0] && pwd1[0] && !strcmp((const char *)pwd, (const char *)pwd1)) { - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->set_user_key) { + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->set_user_key) { - hmackey_t key; - char skey[sizeof(hmackey_t) * 2 + 1]; + hmackey_t key; + char skey[sizeof(hmackey_t) * 2 + 1]; - { - uint8_t u[STUN_MAX_USERNAME_SIZE+1]; - uint8_t r[STUN_MAX_REALM_SIZE+1]; - uint8_t p[STUN_MAX_PWD_SIZE+1]; - STRCPY(u,add_user); - STRCPY(r,add_realm); - STRCPY(p,pwd); - stun_produce_integrity_key_str(u, r, p, key, SHATYPE_DEFAULT); - size_t i = 0; - size_t sz = get_hmackey_size(SHATYPE_DEFAULT); - int maxsz = (int) (sz * 2) + 1; - char *s = skey; - for (i = 0; (i < sz) && (maxsz > 2); i++) { - snprintf(s, (size_t) (sz * 2), "%02x", (unsigned int) key[i]); - maxsz -= 2; - s += 2; - } - skey[sz * 2] = 0; + { + uint8_t u[STUN_MAX_USERNAME_SIZE + 1]; + uint8_t r[STUN_MAX_REALM_SIZE + 1]; + uint8_t p[STUN_MAX_PWD_SIZE + 1]; + STRCPY(u, add_user); + STRCPY(r, add_realm); + STRCPY(p, pwd); + stun_produce_integrity_key_str(u, r, p, key, SHATYPE_DEFAULT); + size_t i = 0; + size_t sz = get_hmackey_size(SHATYPE_DEFAULT); + int maxsz = (int)(sz * 2) + 1; + char *s = skey; + for (i = 0; (i < sz) && (maxsz > 2); i++) { + snprintf(s, (size_t)(sz * 2), "%02x", (unsigned int)key[i]); + maxsz -= 2; + s += 2; + } + skey[sz * 2] = 0; - (*dbd->set_user_key)(u, r, skey); - } + (*dbd->set_user_key)(u, r, skey); + } - add_realm=(const uint8_t*)""; - add_user=(const uint8_t*)""; - } - } else { - msg = "Error: wrong password"; - } - } - } + add_realm = (const uint8_t *)""; + add_user = (const uint8_t *)""; + } + } else { + msg = "Error: wrong password"; + } + } + } - write_users_page(s,add_user,add_realm,msg); + write_users_page(s, add_user, add_realm, msg); - } else { - write_https_logon_page(s); - } - break; - } - case AS_FORM_SS: { - if(is_as_ok(s)) { - { - const char *realm0 = get_http_header_value(hr, HR_REALM, current_realm()); - if(!is_superuser()) - realm0 = current_realm(); - strncpy(current_eff_realm(),realm0,STUN_MAX_REALM_SIZE); - } + } else { + write_https_logon_page(s); + } + break; + } + case AS_FORM_SS: { + if (is_as_ok(s)) { + { + const char *realm0 = get_http_header_value(hr, HR_REALM, current_realm()); + if (!is_superuser()) + realm0 = current_realm(); + strncpy(current_eff_realm(), realm0, STUN_MAX_REALM_SIZE); + } - { - const uint8_t *secret = (const uint8_t*)get_http_header_value(hr, HR_DELETE_SECRET, NULL); - if(secret && secret[0]) { - const uint8_t *realm = (const uint8_t*)get_http_header_value(hr, HR_DELETE_REALM, NULL); - if(!is_superuser()) { - realm = (const uint8_t*)current_realm(); - } - if(realm && realm[0]) { - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->del_secret) { - uint8_t ss[AUTH_SECRET_SIZE+1]; - uint8_t r[STUN_MAX_REALM_SIZE+1]; - STRCPY(ss,secret); - STRCPY(r,realm); - dbd->del_secret(ss,r); - } - } - } - } + { + const uint8_t *secret = (const uint8_t *)get_http_header_value(hr, HR_DELETE_SECRET, NULL); + if (secret && secret[0]) { + const uint8_t *realm = (const uint8_t *)get_http_header_value(hr, HR_DELETE_REALM, NULL); + if (!is_superuser()) { + realm = (const uint8_t *)current_realm(); + } + if (realm && realm[0]) { + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->del_secret) { + uint8_t ss[AUTH_SECRET_SIZE + 1]; + uint8_t r[STUN_MAX_REALM_SIZE + 1]; + STRCPY(ss, secret); + STRCPY(r, realm); + dbd->del_secret(ss, r); + } + } + } + } - const uint8_t *add_realm = (const uint8_t*)current_eff_realm(); - const uint8_t *add_secret = (const uint8_t*)get_http_header_value(hr, HR_ADD_SECRET, ""); - const char* msg = ""; - if(wrong_html_name((const char*)add_secret)) { - msg = "Error: wrong secret value"; - add_secret = (const uint8_t*)""; - } - if(add_secret[0]) { - add_realm = (const uint8_t*)get_http_header_value(hr, HR_ADD_REALM, current_realm()); - if(!is_superuser()) { - add_realm = (const uint8_t*)current_realm(); - } - if(!add_realm[0]) { - add_realm=(const uint8_t*)current_eff_realm(); - } - if(!add_realm[0]) { - add_realm = (const uint8_t*)get_realm(NULL)->options.name; - } - if(wrong_html_name((const char*)add_realm)) { - msg = "Error: wrong realm name"; - add_realm = (const uint8_t*)""; - } - if(add_realm[0]) { - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->set_secret) { - uint8_t ss[AUTH_SECRET_SIZE+1]; - uint8_t r[STUN_MAX_REALM_SIZE+1]; - STRCPY(ss,add_secret); - STRCPY(r,add_realm); - (*dbd->set_secret)(ss, r); - } + const uint8_t *add_realm = (const uint8_t *)current_eff_realm(); + const uint8_t *add_secret = (const uint8_t *)get_http_header_value(hr, HR_ADD_SECRET, ""); + const char *msg = ""; + if (wrong_html_name((const char *)add_secret)) { + msg = "Error: wrong secret value"; + add_secret = (const uint8_t *)""; + } + if (add_secret[0]) { + add_realm = (const uint8_t *)get_http_header_value(hr, HR_ADD_REALM, current_realm()); + if (!is_superuser()) { + add_realm = (const uint8_t *)current_realm(); + } + if (!add_realm[0]) { + add_realm = (const uint8_t *)current_eff_realm(); + } + if (!add_realm[0]) { + add_realm = (const uint8_t *)get_realm(NULL)->options.name; + } + if (wrong_html_name((const char *)add_realm)) { + msg = "Error: wrong realm name"; + add_realm = (const uint8_t *)""; + } + if (add_realm[0]) { + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->set_secret) { + uint8_t ss[AUTH_SECRET_SIZE + 1]; + uint8_t r[STUN_MAX_REALM_SIZE + 1]; + STRCPY(ss, add_secret); + STRCPY(r, add_realm); + (*dbd->set_secret)(ss, r); + } - add_secret=(const uint8_t*)""; - add_realm=(const uint8_t*)""; - } - } + add_secret = (const uint8_t *)""; + add_realm = (const uint8_t *)""; + } + } - write_shared_secrets_page(s,(const char*)add_secret,(const char*)add_realm,msg); + write_shared_secrets_page(s, (const char *)add_secret, (const char *)add_realm, msg); - } else { - write_https_logon_page(s); - } - break; - } - case AS_FORM_OS: { - if(is_as_ok(s)) { - { - const char *realm0 = get_http_header_value(hr, HR_REALM, current_realm()); - if(!is_superuser()) - realm0 = current_realm(); - strncpy(current_eff_realm(),realm0,STUN_MAX_REALM_SIZE); - } + } else { + write_https_logon_page(s); + } + break; + } + case AS_FORM_OS: { + if (is_as_ok(s)) { + { + const char *realm0 = get_http_header_value(hr, HR_REALM, current_realm()); + if (!is_superuser()) + realm0 = current_realm(); + strncpy(current_eff_realm(), realm0, STUN_MAX_REALM_SIZE); + } - if(is_superuser()) { - const uint8_t *origin = (const uint8_t*)get_http_header_value(hr, HR_DELETE_ORIGIN, NULL); - if(origin && origin[0]) { - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->del_origin) { - uint8_t o[STUN_MAX_ORIGIN_SIZE+1]; - STRCPY(o,origin); - dbd->del_origin(o); - uint8_t corigin[STUN_MAX_ORIGIN_SIZE+1]; - get_canonic_origin((const char *)origin, (char *)corigin, sizeof(corigin)-1); - dbd->del_origin(corigin); - } - } - } + if (is_superuser()) { + const uint8_t *origin = (const uint8_t *)get_http_header_value(hr, HR_DELETE_ORIGIN, NULL); + if (origin && origin[0]) { + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->del_origin) { + uint8_t o[STUN_MAX_ORIGIN_SIZE + 1]; + STRCPY(o, origin); + dbd->del_origin(o); + uint8_t corigin[STUN_MAX_ORIGIN_SIZE + 1]; + get_canonic_origin((const char *)origin, (char *)corigin, sizeof(corigin) - 1); + dbd->del_origin(corigin); + } + } + } - const uint8_t *add_realm = (const uint8_t*)current_eff_realm(); - const uint8_t *add_origin = (const uint8_t*)get_http_header_value(hr, HR_ADD_ORIGIN, ""); - const char* msg = ""; - uint8_t corigin[STUN_MAX_ORIGIN_SIZE+1]; - get_canonic_origin((const char *)add_origin, (char *)corigin, sizeof(corigin)-1); - if(corigin[0]) { - add_realm = (const uint8_t*)get_http_header_value(hr, HR_ADD_REALM, current_realm()); - if(!is_superuser()) { - add_realm = (const uint8_t*)current_realm(); - } - if(!add_realm[0]) { - add_realm=(const uint8_t*)current_eff_realm(); - } - if(!add_realm[0]) { - add_realm = (const uint8_t*)get_realm(NULL)->options.name; - } - if(add_realm[0]) { - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->add_origin) { - uint8_t o[STUN_MAX_ORIGIN_SIZE+1]; - uint8_t r[STUN_MAX_REALM_SIZE+1]; - STRCPY(o,corigin); - STRCPY(r,add_realm); - (*dbd->add_origin)(o, r); - } + const uint8_t *add_realm = (const uint8_t *)current_eff_realm(); + const uint8_t *add_origin = (const uint8_t *)get_http_header_value(hr, HR_ADD_ORIGIN, ""); + const char *msg = ""; + uint8_t corigin[STUN_MAX_ORIGIN_SIZE + 1]; + get_canonic_origin((const char *)add_origin, (char *)corigin, sizeof(corigin) - 1); + if (corigin[0]) { + add_realm = (const uint8_t *)get_http_header_value(hr, HR_ADD_REALM, current_realm()); + if (!is_superuser()) { + add_realm = (const uint8_t *)current_realm(); + } + if (!add_realm[0]) { + add_realm = (const uint8_t *)current_eff_realm(); + } + if (!add_realm[0]) { + add_realm = (const uint8_t *)get_realm(NULL)->options.name; + } + if (add_realm[0]) { + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->add_origin) { + uint8_t o[STUN_MAX_ORIGIN_SIZE + 1]; + uint8_t r[STUN_MAX_REALM_SIZE + 1]; + STRCPY(o, corigin); + STRCPY(r, add_realm); + (*dbd->add_origin)(o, r); + } - add_origin=(const uint8_t*)""; - add_realm=(const uint8_t*)""; - } - } + add_origin = (const uint8_t *)""; + add_realm = (const uint8_t *)""; + } + } - write_origins_page(s,(const char*)add_origin,(const char*)add_realm,msg); + write_origins_page(s, (const char *)add_origin, (const char *)add_realm, msg); - } else { - write_https_logon_page(s); - } - break; - } - case AS_FORM_OAUTH_SHOW_KEYS: { - if(!is_as_ok(s)) { - write_https_logon_page(s); - } else if(!is_superuser()) { - write_https_home_page(s); - } else { - const char* kid = get_http_header_value(hr,HR_OAUTH_KID,""); - write_https_oauth_show_keys(s,kid); - } - break; - } - case AS_FORM_OAUTH: { - if(!is_as_ok(s)) { - write_https_logon_page(s); - } else if(!is_superuser()) { - write_https_home_page(s); - } else { + } else { + write_https_logon_page(s); + } + break; + } + case AS_FORM_OAUTH_SHOW_KEYS: { + if (!is_as_ok(s)) { + write_https_logon_page(s); + } else if (!is_superuser()) { + write_https_home_page(s); + } else { + const char *kid = get_http_header_value(hr, HR_OAUTH_KID, ""); + write_https_oauth_show_keys(s, kid); + } + break; + } + case AS_FORM_OAUTH: { + if (!is_as_ok(s)) { + write_https_logon_page(s); + } else if (!is_superuser()) { + write_https_home_page(s); + } else { - { - const char* del_kid = get_http_header_value(hr,HR_DELETE_OAUTH_KID,""); - if(del_kid[0]) { - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->del_oauth_key) { - (*dbd->del_oauth_key)((const uint8_t*)del_kid); - } - } - } + { + const char *del_kid = get_http_header_value(hr, HR_DELETE_OAUTH_KID, ""); + if (del_kid[0]) { + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->del_oauth_key) { + (*dbd->del_oauth_key)((const uint8_t *)del_kid); + } + } + } - const char* add_kid = ""; - const char* add_ts = "0"; - const char* add_lt = "0"; - const char* add_ikm = ""; - const char* add_tea = ""; - const char* add_realm = ""; - const char* msg = ""; + const char *add_kid = ""; + const char *add_ts = "0"; + const char *add_lt = "0"; + const char *add_ikm = ""; + const char *add_tea = ""; + const char *add_realm = ""; + const char *msg = ""; - add_kid = get_http_header_value(hr,HR_ADD_OAUTH_KID,""); - if(add_kid[0]) { - add_ikm = get_http_header_value(hr,HR_ADD_OAUTH_IKM,""); - add_ts = get_http_header_value(hr,HR_ADD_OAUTH_TS,""); - add_lt = get_http_header_value(hr,HR_ADD_OAUTH_LT,""); - add_tea = get_http_header_value(hr,HR_ADD_OAUTH_TEA,""); - add_realm = get_http_header_value(hr,HR_ADD_OAUTH_REALM,""); + add_kid = get_http_header_value(hr, HR_ADD_OAUTH_KID, ""); + if (add_kid[0]) { + add_ikm = get_http_header_value(hr, HR_ADD_OAUTH_IKM, ""); + add_ts = get_http_header_value(hr, HR_ADD_OAUTH_TS, ""); + add_lt = get_http_header_value(hr, HR_ADD_OAUTH_LT, ""); + add_tea = get_http_header_value(hr, HR_ADD_OAUTH_TEA, ""); + add_realm = get_http_header_value(hr, HR_ADD_OAUTH_REALM, ""); - int keys_ok = (add_ikm[0] != 0); - if(!keys_ok) { - msg = "You must enter the key value."; - } else { - oauth_key_data_raw key; - memset(&key, 0, sizeof(key)); - STRCPY(key.kid,add_kid); + int keys_ok = (add_ikm[0] != 0); + if (!keys_ok) { + msg = "You must enter the key value."; + } else { + oauth_key_data_raw key; + memset(&key, 0, sizeof(key)); + STRCPY(key.kid, add_kid); - if(add_lt && add_lt[0]) { - key.lifetime = (uint32_t)strtoul(add_lt,NULL,10); - if(key.lifetime) { - if(add_ts && add_ts[0]) { - key.timestamp = (uint64_t)strtoull(add_ts,NULL,10); - } - if(!key.timestamp) { - key.timestamp = (uint64_t)time(NULL); - } - } - } else if(add_ts && add_ts[0]) { - key.timestamp = (uint64_t)strtoull(add_ts,NULL,10); - } + if (add_lt && add_lt[0]) { + key.lifetime = (uint32_t)strtoul(add_lt, NULL, 10); + if (key.lifetime) { + if (add_ts && add_ts[0]) { + key.timestamp = (uint64_t)strtoull(add_ts, NULL, 10); + } + if (!key.timestamp) { + key.timestamp = (uint64_t)time(NULL); + } + } + } else if (add_ts && add_ts[0]) { + key.timestamp = (uint64_t)strtoull(add_ts, NULL, 10); + } - if(add_realm && add_realm[0]) STRCPY(key.realm,add_realm); + if (add_realm && add_realm[0]) + STRCPY(key.realm, add_realm); - STRCPY(key.ikm_key,add_ikm); - STRCPY(key.as_rs_alg,add_tea); + STRCPY(key.ikm_key, add_ikm); + STRCPY(key.as_rs_alg, add_tea); - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->set_oauth_key) { - if((*dbd->set_oauth_key)(&key)<0) { - msg = "Cannot insert oAuth key into the database"; - } else { - add_kid = ""; - add_ts = "0"; - add_lt = "0"; - add_ikm = ""; - add_tea = ""; - add_realm = ""; - } - } - } - } + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->set_oauth_key) { + if ((*dbd->set_oauth_key)(&key) < 0) { + msg = "Cannot insert oAuth key into the database"; + } else { + add_kid = ""; + add_ts = "0"; + add_lt = "0"; + add_ikm = ""; + add_tea = ""; + add_realm = ""; + } + } + } + } - write_https_oauth_page(s,add_kid,add_ikm,add_tea,add_ts,add_lt,add_realm,msg); - } - break; - } - case AS_FORM_TOGGLE: - if(is_as_ok(s)) { - handle_toggle_request(s,hr); - write_pc_page(s); - } else { - write_https_logon_page(s); - } - break; - case AS_FORM_UPDATE: - if(is_as_ok(s)) { - handle_update_request(s,hr); - write_pc_page(s); - } else { - write_https_logon_page(s); - } - break; - case AS_FORM_LOGON: - if(!is_as_ok(s)) { - handle_logon_request(s,hr); - if(is_as_ok(s)) { - write_https_home_page(s); - } else { - write_https_logon_page(s); - } - } else { - write_https_home_page(s); - } - break; - case AS_FORM_LOGOUT: - handle_logout_request(s,hr); - write_https_logon_page(s); - break; - default: { - const char *realm0 = get_http_header_value(hr, HR_REALM, current_realm()); - if(!is_superuser()) - realm0 = current_realm(); - strncpy(current_eff_realm(),realm0,STUN_MAX_REALM_SIZE); - write_https_home_page(s); - } - }; - free_http_request(hr); - } - } + write_https_oauth_page(s, add_kid, add_ikm, add_tea, add_ts, add_lt, add_realm, msg); + } + break; + } + case AS_FORM_TOGGLE: + if (is_as_ok(s)) { + handle_toggle_request(s, hr); + write_pc_page(s); + } else { + write_https_logon_page(s); + } + break; + case AS_FORM_UPDATE: + if (is_as_ok(s)) { + handle_update_request(s, hr); + write_pc_page(s); + } else { + write_https_logon_page(s); + } + break; + case AS_FORM_LOGON: + if (!is_as_ok(s)) { + handle_logon_request(s, hr); + if (is_as_ok(s)) { + write_https_home_page(s); + } else { + write_https_logon_page(s); + } + } else { + write_https_home_page(s); + } + break; + case AS_FORM_LOGOUT: + handle_logout_request(s, hr); + write_https_logon_page(s); + break; + default: { + const char *realm0 = get_http_header_value(hr, HR_REALM, current_realm()); + if (!is_superuser()) + realm0 = current_realm(); + strncpy(current_eff_realm(), realm0, STUN_MAX_REALM_SIZE); + write_https_home_page(s); + } + }; + free_http_request(hr); + } + } - current_socket = NULL; + current_socket = NULL; } static void https_input_handler(ioa_socket_handle s, int event_type, ioa_net_data *data, void *arg, int can_resume) { - UNUSED_ARG(arg); - UNUSED_ARG(s); - UNUSED_ARG(event_type); - UNUSED_ARG(can_resume); + UNUSED_ARG(arg); + UNUSED_ARG(s); + UNUSED_ARG(event_type); + UNUSED_ARG(can_resume); - handle_https(s,data->nbh); + handle_https(s, data->nbh); - ioa_network_buffer_delete(adminserver.e, data->nbh); - data->nbh = NULL; + ioa_network_buffer_delete(adminserver.e, data->nbh); + data->nbh = NULL; } -void https_admin_server_receive_message(struct bufferevent *bev, void *ptr) -{ - UNUSED_ARG(ptr); +void https_admin_server_receive_message(struct bufferevent *bev, void *ptr) { + UNUSED_ARG(ptr); - ioa_socket_handle s= NULL; - int n = 0; - struct evbuffer *input = bufferevent_get_input(bev); + ioa_socket_handle s = NULL; + int n = 0; + struct evbuffer *input = bufferevent_get_input(bev); - while ((n = evbuffer_remove(input, &s, sizeof(s))) > 0) { - if (n != sizeof(s)) { - fprintf(stderr,"%s: Weird HTTPS CLI buffer error: size=%d\n",__FUNCTION__,n); - continue; - } + while ((n = evbuffer_remove(input, &s, sizeof(s))) > 0) { + if (n != sizeof(s)) { + fprintf(stderr, "%s: Weird HTTPS CLI buffer error: size=%d\n", __FUNCTION__, n); + continue; + } - register_callback_on_ioa_socket(adminserver.e, s, IOA_EV_READ, https_input_handler, NULL, 0); + register_callback_on_ioa_socket(adminserver.e, s, IOA_EV_READ, https_input_handler, NULL, 0); - handle_https(s,NULL); - } + handle_https(s, NULL); + } } void send_https_socket(ioa_socket_handle s) { - struct evbuffer *output = bufferevent_get_output(adminserver.https_out_buf); - if(output) { - evbuffer_add(output,&s,sizeof(s)); - } + struct evbuffer *output = bufferevent_get_output(adminserver.https_out_buf); + if (output) { + evbuffer_add(output, &s, sizeof(s)); + } } /////////////////////////////// diff --git a/src/apps/relay/turn_admin_server.h b/src/apps/relay/turn_admin_server.h index 7edb47f..6946561 100644 --- a/src/apps/relay/turn_admin_server.h +++ b/src/apps/relay/turn_admin_server.h @@ -31,17 +31,17 @@ #ifndef __TURN_ADMIN_SERVER__ #define __TURN_ADMIN_SERVER__ -#include #include +#include #include -#include #include +#include -#include "ns_turn_utils.h" #include "ns_turn_maps.h" #include "ns_turn_server.h" +#include "ns_turn_utils.h" #include "apputils.h" @@ -54,25 +54,25 @@ extern "C" { #define ADMIN_USER_MAX_LENGTH (32) struct admin_session { - int as_ok; - char as_login[ADMIN_USER_MAX_LENGTH + 1]; - char as_realm[STUN_MAX_REALM_SIZE + 1]; - char as_eff_realm[STUN_MAX_REALM_SIZE + 1]; - size_t number_of_user_sessions; + int as_ok; + char as_login[ADMIN_USER_MAX_LENGTH + 1]; + char as_realm[STUN_MAX_REALM_SIZE + 1]; + char as_eff_realm[STUN_MAX_REALM_SIZE + 1]; + size_t number_of_user_sessions; }; struct admin_server { - evutil_socket_t listen_fd; - struct event_base* event_base; - ioa_engine_handle e; - int verbose; - struct evconnlistener *l; - struct bufferevent *in_buf; - struct bufferevent *out_buf; - struct bufferevent *https_in_buf; - struct bufferevent *https_out_buf; - ur_map *sessions; - pthread_t thr; + evutil_socket_t listen_fd; + struct event_base *event_base; + ioa_engine_handle e; + int verbose; + struct evconnlistener *l; + struct bufferevent *in_buf; + struct bufferevent *out_buf; + struct bufferevent *https_in_buf; + struct bufferevent *https_out_buf; + ur_map *sessions; + pthread_t thr; }; /////////////////////////////////////////// @@ -94,11 +94,10 @@ extern char cli_password[CLI_PASSWORD_LENGTH]; #define DEFAULT_CLI_MAX_OUTPUT_SESSIONS (256) extern int cli_max_output_sessions; - extern int use_web_admin; #define WEB_ADMIN_DEFAULT_IP ("127.0.0.1") -extern ioa_addr web_admin_addr; +extern ioa_addr web_admin_addr; extern int web_admin_addr_set; #define WEB_ADMIN_DEFAULT_PORT (8080) @@ -111,7 +110,7 @@ void setup_admin_thread(void); void admin_server_receive_message(struct bufferevent *bev, void *ptr); void https_admin_server_receive_message(struct bufferevent *bev, void *ptr); -int send_turn_session_info(struct turn_session_info* tsi); +int send_turn_session_info(struct turn_session_info *tsi); void send_https_socket(ioa_socket_handle s); //////////////////////////////////////////// @@ -122,4 +121,3 @@ void send_https_socket(ioa_socket_handle s); #endif /// __TURN_ADMIN_SERVER__/// - diff --git a/src/apps/relay/turn_ports.c b/src/apps/relay/turn_ports.c index e2cf5c5..d4fb614 100644 --- a/src/apps/relay/turn_ports.c +++ b/src/apps/relay/turn_ports.c @@ -31,14 +31,14 @@ #include "ns_turn_maps.h" #include "ns_turn_msg_defs.h" -#include "ns_turn_ioalib.h" #include "ns_ioalib_impl.h" +#include "ns_turn_ioalib.h" #include "turn_ports.h" ////////// DATA //////////////////////////////////////////// -#define PORTS_SIZE (0xFFFF+1) +#define PORTS_SIZE (0xFFFF + 1) #define TPS_OUT_OF_RANGE ((uint32_t)(-1)) #define TPS_TAKEN_SINGLE ((uint32_t)(-2)) #define TPS_TAKEN_EVEN ((uint32_t)(-3)) @@ -57,75 +57,75 @@ typedef struct _turnports turnports; /////////////// TURNPORTS statics ////////////////////////// -static turnports* turnports_create(super_memory_t *sm, uint16_t start, uint16_t end); -static uint16_t turnports_size(turnports* tp); +static turnports *turnports_create(super_memory_t *sm, uint16_t start, uint16_t end); +static uint16_t turnports_size(turnports *tp); -static int turnports_allocate(turnports* tp); -static int turnports_allocate_even(turnports* tp, int allocate_rtcp, uint64_t *reservation_token); +static int turnports_allocate(turnports *tp); +static int turnports_allocate_even(turnports *tp, int allocate_rtcp, uint64_t *reservation_token); -static void turnports_release(turnports* tp, uint16_t port); +static void turnports_release(turnports *tp, uint16_t port); -static int turnports_is_allocated(turnports* tp, uint16_t port); -static int turnports_is_available(turnports* tp, uint16_t port); +static int turnports_is_allocated(turnports *tp, uint16_t port); +static int turnports_is_available(turnports *tp, uint16_t port); /////////////// UTILS ////////////////////////////////////// static int is_taken(uint32_t status) { - int ret = -1; - switch (status) { - case TPS_TAKEN_SINGLE : - case TPS_TAKEN_EVEN : - case TPS_TAKEN_ODD : - ret = 1; - break; - default: - ret = 0; - }; - return ret; + int ret = -1; + switch (status) { + case TPS_TAKEN_SINGLE: + case TPS_TAKEN_EVEN: + case TPS_TAKEN_ODD: + ret = 1; + break; + default: + ret = 0; + }; + return ret; } -static void turnports_randomize(turnports* tp) { - if(tp) { - unsigned int size=(unsigned int)(tp->high-tp->low); - unsigned int i=0; - unsigned int cycles=size*10; - for(i=0;ilow + (uint16_t)(((unsigned long)turn_random())%((unsigned long)size))); - uint16_t port2 = (uint16_t)(tp->low + (uint16_t)(((unsigned long)turn_random())%((unsigned long)size))); - if(port1!=port2) { - int pos1=tp->status[port1]; - int pos2=tp->status[port2]; - int tmp=(int)tp->status[port1]; - tp->status[port1]=tp->status[port2]; - tp->status[port2]=(uint32_t)tmp; - tmp=(int)tp->ports[pos1]; - tp->ports[pos1]=tp->ports[pos2]; - tp->ports[pos2]=(uint16_t)tmp; +static void turnports_randomize(turnports *tp) { + if (tp) { + unsigned int size = (unsigned int)(tp->high - tp->low); + unsigned int i = 0; + unsigned int cycles = size * 10; + for (i = 0; i < cycles; i++) { + uint16_t port1 = (uint16_t)(tp->low + (uint16_t)(((unsigned long)turn_random()) % ((unsigned long)size))); + uint16_t port2 = (uint16_t)(tp->low + (uint16_t)(((unsigned long)turn_random()) % ((unsigned long)size))); + if (port1 != port2) { + int pos1 = tp->status[port1]; + int pos2 = tp->status[port2]; + int tmp = (int)tp->status[port1]; + tp->status[port1] = tp->status[port2]; + tp->status[port2] = (uint32_t)tmp; + tmp = (int)tp->ports[pos1]; + tp->ports[pos1] = tp->ports[pos2]; + tp->ports[pos2] = (uint16_t)tmp; } } } -} +} -static void turnports_init(turnports* tp, uint16_t start, uint16_t end) { +static void turnports_init(turnports *tp, uint16_t start, uint16_t end) { - tp->low=start; - tp->high=((uint32_t)end)+1; + tp->low = start; + tp->high = ((uint32_t)end) + 1; - tp->range_start=start; - tp->range_stop=end; - - int i=0; - for(i=0;istatus[i]=TPS_OUT_OF_RANGE; - tp->ports[i]=(uint16_t)i; + tp->range_start = start; + tp->range_stop = end; + + int i = 0; + for (i = 0; i < start; i++) { + tp->status[i] = TPS_OUT_OF_RANGE; + tp->ports[i] = (uint16_t)i; } - for(i=start;i<=end;i++) { - tp->status[i]=(uint32_t)i; - tp->ports[i]=(uint16_t)i; + for (i = start; i <= end; i++) { + tp->status[i] = (uint32_t)i; + tp->ports[i] = (uint16_t)i; } - for(i=((int)end)+1;istatus[i]=TPS_OUT_OF_RANGE; - tp->ports[i]=(uint16_t)i; + for (i = ((int)end) + 1; i < PORTS_SIZE; i++) { + tp->status[i] = TPS_OUT_OF_RANGE; + tp->ports[i] = (uint16_t)i; } turnports_randomize(tp); @@ -135,57 +135,59 @@ static void turnports_init(turnports* tp, uint16_t start, uint16_t end) { /////////////// FUNC /////////////////////////////////////// -turnports* turnports_create(super_memory_t *sm, uint16_t start, uint16_t end) { +turnports *turnports_create(super_memory_t *sm, uint16_t start, uint16_t end) { - if(start>end) return NULL; + if (start > end) + return NULL; - turnports* ret=(turnports*)allocate_super_memory_region(sm, sizeof(turnports)); - turnports_init(ret,start,end); + turnports *ret = (turnports *)allocate_super_memory_region(sm, sizeof(turnports)); + turnports_init(ret, start, end); return ret; } -uint16_t turnports_size(turnports* tp) { - if(!tp) return 0; +uint16_t turnports_size(turnports *tp) { + if (!tp) + return 0; else { TURN_MUTEX_LOCK(&tp->mutex); - uint16_t ret = (uint16_t)((tp->high-tp->low)); + uint16_t ret = (uint16_t)((tp->high - tp->low)); TURN_MUTEX_UNLOCK(&tp->mutex); return ret; } } -int turnports_allocate(turnports* tp) { +int turnports_allocate(turnports *tp) { - int port=-1; + int port = -1; TURN_MUTEX_LOCK(&tp->mutex); - if(tp) { + if (tp) { - while(1) { - - if(tp->high <= tp->low) { - TURN_MUTEX_UNLOCK(&tp->mutex); - return -1; + while (1) { + + if (tp->high <= tp->low) { + TURN_MUTEX_UNLOCK(&tp->mutex); + return -1; } - - int position=(uint16_t)(tp->low & 0x0000FFFF); - - port=(int)tp->ports[position]; - if(port<(int)(tp->range_start) || port>((int)(tp->range_stop))) { - TURN_MUTEX_UNLOCK(&tp->mutex); - return -1; + + int position = (uint16_t)(tp->low & 0x0000FFFF); + + port = (int)tp->ports[position]; + if (port < (int)(tp->range_start) || port > ((int)(tp->range_stop))) { + TURN_MUTEX_UNLOCK(&tp->mutex); + return -1; } - if(is_taken(tp->status[port])) { - ++(tp->low); - continue; - } - if(tp->status[port]!=tp->low) { - ++(tp->low); - continue; + if (is_taken(tp->status[port])) { + ++(tp->low); + continue; } - tp->status[port]=TPS_TAKEN_SINGLE; + if (tp->status[port] != tp->low) { + ++(tp->low); + continue; + } + tp->status[port] = TPS_TAKEN_SINGLE; ++(tp->low); break; } @@ -196,54 +198,54 @@ int turnports_allocate(turnports* tp) { return port; } -void turnports_release(turnports* tp, uint16_t port) { +void turnports_release(turnports *tp, uint16_t port) { TURN_MUTEX_LOCK(&tp->mutex); - if(tp && port>=tp->range_start && port<=tp->range_stop) { - uint16_t position=(uint16_t)(tp->high & 0x0000FFFF); - if(is_taken(tp->status[port])) { - tp->status[port]=tp->high; - tp->ports[position]=port; + if (tp && port >= tp->range_start && port <= tp->range_stop) { + uint16_t position = (uint16_t)(tp->high & 0x0000FFFF); + if (is_taken(tp->status[port])) { + tp->status[port] = tp->high; + tp->ports[position] = port; ++(tp->high); } } TURN_MUTEX_UNLOCK(&tp->mutex); } -int turnports_allocate_even(turnports* tp, int allocate_rtcp, uint64_t *reservation_token) { - if(tp) { +int turnports_allocate_even(turnports *tp, int allocate_rtcp, uint64_t *reservation_token) { + if (tp) { TURN_MUTEX_LOCK(&tp->mutex); uint16_t size = turnports_size(tp); - if(size>1) { - uint16_t i=0; - for(i=0;imutex); - return port; - } else { - int rtcp_port=port+1; - if(rtcp_port>tp->range_stop) { - turnports_release(tp,port); - } else if(!turnports_is_available(tp,rtcp_port)) { - turnports_release(tp,port); - } else { - tp->status[port]=TPS_TAKEN_EVEN; - tp->status[rtcp_port]=TPS_TAKEN_ODD; - if(reservation_token) { - uint16_t *v16=(uint16_t*)reservation_token; - uint32_t *v32=(uint32_t*)reservation_token; - v16[0]=(uint16_t)(tp->ports[(uint16_t)(tp->low & 0x0000FFFF)]); - v16[1]=(uint16_t)(tp->ports[(uint16_t)(tp->high & 0x0000FFFF)]); - v32[1]=(uint32_t)turn_random(); - } - TURN_MUTEX_UNLOCK(&tp->mutex); - return port; - } - } - } + if (size > 1) { + uint16_t i = 0; + for (i = 0; i < size; i++) { + int port = turnports_allocate(tp); + if (port & 0x00000001) { + turnports_release(tp, port); + } else { + if (!allocate_rtcp) { + TURN_MUTEX_UNLOCK(&tp->mutex); + return port; + } else { + int rtcp_port = port + 1; + if (rtcp_port > tp->range_stop) { + turnports_release(tp, port); + } else if (!turnports_is_available(tp, rtcp_port)) { + turnports_release(tp, port); + } else { + tp->status[port] = TPS_TAKEN_EVEN; + tp->status[rtcp_port] = TPS_TAKEN_ODD; + if (reservation_token) { + uint16_t *v16 = (uint16_t *)reservation_token; + uint32_t *v32 = (uint32_t *)reservation_token; + v16[0] = (uint16_t)(tp->ports[(uint16_t)(tp->low & 0x0000FFFF)]); + v16[1] = (uint16_t)(tp->ports[(uint16_t)(tp->high & 0x0000FFFF)]); + v32[1] = (uint32_t)turn_random(); + } + TURN_MUTEX_UNLOCK(&tp->mutex); + return port; + } + } + } } } TURN_MUTEX_UNLOCK(&tp->mutex); @@ -251,8 +253,9 @@ int turnports_allocate_even(turnports* tp, int allocate_rtcp, uint64_t *reservat return -1; } -int turnports_is_allocated(turnports* tp, uint16_t port) { - if(!tp) return 0; +int turnports_is_allocated(turnports *tp, uint16_t port) { + if (!tp) + return 0; else { TURN_MUTEX_LOCK(&tp->mutex); int ret = is_taken(tp->status[port]); @@ -261,15 +264,15 @@ int turnports_is_allocated(turnports* tp, uint16_t port) { } } -int turnports_is_available(turnports* tp, uint16_t port) { - if(tp) { +int turnports_is_available(turnports *tp, uint16_t port) { + if (tp) { TURN_MUTEX_LOCK(&tp->mutex); uint32_t status = tp->status[port]; - if((status!=TPS_OUT_OF_RANGE) && !is_taken(status)) { - uint16_t position=(uint16_t)(status & 0x0000FFFF); - if(tp->ports[position]==port) { - TURN_MUTEX_UNLOCK(&tp->mutex); - return 1; + if ((status != TPS_OUT_OF_RANGE) && !is_taken(status)) { + uint16_t position = (uint16_t)(status & 0x0000FFFF); + if (tp->ports[position] == port) { + TURN_MUTEX_UNLOCK(&tp->mutex); + return 1; } } TURN_MUTEX_UNLOCK(&tp->mutex); @@ -279,139 +282,127 @@ int turnports_is_available(turnports* tp, uint16_t port) { /////////////////// IP-mapped PORTS ///////////////////////////////////// -struct _turnipports -{ - super_memory_t *sm; - uint16_t start; - uint16_t end; - ur_addr_map ip_to_turnports_udp; - ur_addr_map ip_to_turnports_tcp; - TURN_MUTEX_DECLARE(mutex) +struct _turnipports { + super_memory_t *sm; + uint16_t start; + uint16_t end; + ur_addr_map ip_to_turnports_udp; + ur_addr_map ip_to_turnports_tcp; + TURN_MUTEX_DECLARE(mutex) }; ////////////////////////////////////////////////// -static ur_addr_map *get_map(turnipports *tp, uint8_t transport) -{ - if(transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE) - return &(tp->ip_to_turnports_tcp); - return &(tp->ip_to_turnports_udp); +static ur_addr_map *get_map(turnipports *tp, uint8_t transport) { + if (transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE) + return &(tp->ip_to_turnports_tcp); + return &(tp->ip_to_turnports_udp); } ////////////////////////////////////////////////// -static turnipports* turnipports_singleton = NULL; +static turnipports *turnipports_singleton = NULL; -turnipports* turnipports_create(super_memory_t *sm, uint16_t start, uint16_t end) -{ - turnipports *ret = (turnipports*) allocate_super_memory_region(sm, sizeof(turnipports)); - ret->sm = sm; - ur_addr_map_init(&(ret->ip_to_turnports_udp)); - ur_addr_map_init(&(ret->ip_to_turnports_tcp)); - ret->start = start; - ret->end = end; - TURN_MUTEX_INIT_RECURSIVE(&(ret->mutex)); - turnipports_singleton = ret; - return ret; +turnipports *turnipports_create(super_memory_t *sm, uint16_t start, uint16_t end) { + turnipports *ret = (turnipports *)allocate_super_memory_region(sm, sizeof(turnipports)); + ret->sm = sm; + ur_addr_map_init(&(ret->ip_to_turnports_udp)); + ur_addr_map_init(&(ret->ip_to_turnports_tcp)); + ret->start = start; + ret->end = end; + TURN_MUTEX_INIT_RECURSIVE(&(ret->mutex)); + turnipports_singleton = ret; + return ret; } -static turnports* turnipports_add(turnipports* tp, uint8_t transport, const ioa_addr *backend_addr) -{ - ur_addr_map_value_type t = 0; - if (tp && backend_addr) { - ioa_addr ba; - addr_cpy(&ba, backend_addr); - addr_set_port(&ba, 0); - TURN_MUTEX_LOCK((const turn_mutex*)&(tp->mutex)); - if (!ur_addr_map_get(get_map(tp, transport), &ba, &t)) { - t = (ur_addr_map_value_type) turnports_create(tp->sm, tp->start, tp->end); - ur_addr_map_put(get_map(tp, transport), &ba, t); - } - TURN_MUTEX_UNLOCK((const turn_mutex*)&(tp->mutex)); - } - return (turnports*) t; +static turnports *turnipports_add(turnipports *tp, uint8_t transport, const ioa_addr *backend_addr) { + ur_addr_map_value_type t = 0; + if (tp && backend_addr) { + ioa_addr ba; + addr_cpy(&ba, backend_addr); + addr_set_port(&ba, 0); + TURN_MUTEX_LOCK((const turn_mutex *)&(tp->mutex)); + if (!ur_addr_map_get(get_map(tp, transport), &ba, &t)) { + t = (ur_addr_map_value_type)turnports_create(tp->sm, tp->start, tp->end); + ur_addr_map_put(get_map(tp, transport), &ba, t); + } + TURN_MUTEX_UNLOCK((const turn_mutex *)&(tp->mutex)); + } + return (turnports *)t; } -void turnipports_add_ip(uint8_t transport, const ioa_addr *backend_addr) -{ - turnipports_add(turnipports_singleton, transport, backend_addr); +void turnipports_add_ip(uint8_t transport, const ioa_addr *backend_addr) { + turnipports_add(turnipports_singleton, transport, backend_addr); } -int turnipports_allocate(turnipports* tp, uint8_t transport, const ioa_addr *backend_addr) -{ - int ret = -1; - if (tp && backend_addr) { - TURN_MUTEX_LOCK((const turn_mutex*)&(tp->mutex)); - turnports *t = turnipports_add(tp, transport, backend_addr); - ret = turnports_allocate(t); - TURN_MUTEX_UNLOCK((const turn_mutex*)&(tp->mutex)); - } - return ret; +int turnipports_allocate(turnipports *tp, uint8_t transport, const ioa_addr *backend_addr) { + int ret = -1; + if (tp && backend_addr) { + TURN_MUTEX_LOCK((const turn_mutex *)&(tp->mutex)); + turnports *t = turnipports_add(tp, transport, backend_addr); + ret = turnports_allocate(t); + TURN_MUTEX_UNLOCK((const turn_mutex *)&(tp->mutex)); + } + return ret; } -int turnipports_allocate_even(turnipports* tp, const ioa_addr *backend_addr, int allocate_rtcp, - uint64_t *reservation_token) -{ - int ret = -1; - if (tp && backend_addr) { - TURN_MUTEX_LOCK((const turn_mutex*)&(tp->mutex)); - turnports *t = turnipports_add(tp, STUN_ATTRIBUTE_TRANSPORT_UDP_VALUE, backend_addr); - ret = turnports_allocate_even(t, allocate_rtcp, reservation_token); - TURN_MUTEX_UNLOCK((const turn_mutex*)&(tp->mutex)); - } - return ret; +int turnipports_allocate_even(turnipports *tp, const ioa_addr *backend_addr, int allocate_rtcp, + uint64_t *reservation_token) { + int ret = -1; + if (tp && backend_addr) { + TURN_MUTEX_LOCK((const turn_mutex *)&(tp->mutex)); + turnports *t = turnipports_add(tp, STUN_ATTRIBUTE_TRANSPORT_UDP_VALUE, backend_addr); + ret = turnports_allocate_even(t, allocate_rtcp, reservation_token); + TURN_MUTEX_UNLOCK((const turn_mutex *)&(tp->mutex)); + } + return ret; } -void turnipports_release(turnipports* tp, uint8_t transport, const ioa_addr *socket_addr) -{ - if (tp && socket_addr) { - ioa_addr ba; - ur_addr_map_value_type t; - addr_cpy(&ba, socket_addr); - addr_set_port(&ba, 0); - TURN_MUTEX_LOCK((const turn_mutex*)&(tp->mutex)); - if (ur_addr_map_get(get_map(tp, transport), &ba, &t)) { - turnports_release((turnports*) t, addr_get_port(socket_addr)); - } - TURN_MUTEX_UNLOCK((const turn_mutex*)&(tp->mutex)); - } +void turnipports_release(turnipports *tp, uint8_t transport, const ioa_addr *socket_addr) { + if (tp && socket_addr) { + ioa_addr ba; + ur_addr_map_value_type t; + addr_cpy(&ba, socket_addr); + addr_set_port(&ba, 0); + TURN_MUTEX_LOCK((const turn_mutex *)&(tp->mutex)); + if (ur_addr_map_get(get_map(tp, transport), &ba, &t)) { + turnports_release((turnports *)t, addr_get_port(socket_addr)); + } + TURN_MUTEX_UNLOCK((const turn_mutex *)&(tp->mutex)); + } } -int turnipports_is_allocated(turnipports* tp, uint8_t transport, const ioa_addr *backend_addr, uint16_t port) -{ - int ret = 0; - if (tp && backend_addr) { - ioa_addr ba; - ur_addr_map_value_type t; - addr_cpy(&ba, backend_addr); - addr_set_port(&ba, 0); - TURN_MUTEX_LOCK((const turn_mutex*)&(tp->mutex)); - if (ur_addr_map_get(get_map(tp,transport), &ba, &t)) { - ret = turnports_is_allocated((turnports*) t, port); - } - TURN_MUTEX_UNLOCK((const turn_mutex*)&(tp->mutex)); - } - return ret; +int turnipports_is_allocated(turnipports *tp, uint8_t transport, const ioa_addr *backend_addr, uint16_t port) { + int ret = 0; + if (tp && backend_addr) { + ioa_addr ba; + ur_addr_map_value_type t; + addr_cpy(&ba, backend_addr); + addr_set_port(&ba, 0); + TURN_MUTEX_LOCK((const turn_mutex *)&(tp->mutex)); + if (ur_addr_map_get(get_map(tp, transport), &ba, &t)) { + ret = turnports_is_allocated((turnports *)t, port); + } + TURN_MUTEX_UNLOCK((const turn_mutex *)&(tp->mutex)); + } + return ret; } -int turnipports_is_available(turnipports* tp, uint8_t transport, const ioa_addr *backend_addr, uint16_t port) -{ - int ret = 0; - if (tp && backend_addr) { - ioa_addr ba; - ur_addr_map_value_type t; - addr_cpy(&ba, backend_addr); - addr_set_port(&ba, 0); - TURN_MUTEX_LOCK((const turn_mutex*)&(tp->mutex)); - if (!ur_addr_map_get(get_map(tp,transport), &ba, &t)) { - ret = 1; - } else { - ret = turnports_is_available((turnports*) t, port); - } - TURN_MUTEX_UNLOCK((const turn_mutex*)&(tp->mutex)); - } - return ret; +int turnipports_is_available(turnipports *tp, uint8_t transport, const ioa_addr *backend_addr, uint16_t port) { + int ret = 0; + if (tp && backend_addr) { + ioa_addr ba; + ur_addr_map_value_type t; + addr_cpy(&ba, backend_addr); + addr_set_port(&ba, 0); + TURN_MUTEX_LOCK((const turn_mutex *)&(tp->mutex)); + if (!ur_addr_map_get(get_map(tp, transport), &ba, &t)) { + ret = 1; + } else { + ret = turnports_is_available((turnports *)t, port); + } + TURN_MUTEX_UNLOCK((const turn_mutex *)&(tp->mutex)); + } + return ret; } ////////////////////////////////////////////////////////////////// - - diff --git a/src/apps/relay/turn_ports.h b/src/apps/relay/turn_ports.h index 6a363c4..b3bd9e3 100644 --- a/src/apps/relay/turn_ports.h +++ b/src/apps/relay/turn_ports.h @@ -51,18 +51,18 @@ typedef struct _turnipports turnipports; ////////////////////////////////////////////////// -turnipports* turnipports_create(super_memory_t *sm, uint16_t start, uint16_t end); +turnipports *turnipports_create(super_memory_t *sm, uint16_t start, uint16_t end); void turnipports_add_ip(uint8_t transport, const ioa_addr *backend_addr); -int turnipports_allocate(turnipports* tp, uint8_t transport, const ioa_addr *backend_addr); -int turnipports_allocate_even(turnipports* tp, const ioa_addr *backend_addr, - int allocate_rtcp, uint64_t *reservation_token); +int turnipports_allocate(turnipports *tp, uint8_t transport, const ioa_addr *backend_addr); +int turnipports_allocate_even(turnipports *tp, const ioa_addr *backend_addr, int allocate_rtcp, + uint64_t *reservation_token); -void turnipports_release(turnipports* tp, uint8_t transport, const ioa_addr *socket_addr); +void turnipports_release(turnipports *tp, uint8_t transport, const ioa_addr *socket_addr); -int turnipports_is_allocated(turnipports* tp, uint8_t transport, const ioa_addr *backend_addr, uint16_t port); -int turnipports_is_available(turnipports* tp, uint8_t transport, const ioa_addr *backend_addr, uint16_t port); +int turnipports_is_allocated(turnipports *tp, uint8_t transport, const ioa_addr *backend_addr, uint16_t port); +int turnipports_is_available(turnipports *tp, uint8_t transport, const ioa_addr *backend_addr, uint16_t port); ////////////////////////////////////////////////// diff --git a/src/apps/relay/userdb.c b/src/apps/relay/userdb.c index d67ba6c..58d0d63 100644 --- a/src/apps/relay/userdb.c +++ b/src/apps/relay/userdb.c @@ -28,13 +28,13 @@ * SUCH DAMAGE. */ -#include +#include +#include +#include #include +#include #include #include -#include -#include -#include #ifndef _MSC_VER #include @@ -42,20 +42,20 @@ #include -#include #include +#include -#include #include +#include -#include "userdb.h" #include "dbdrivers/dbdriver.h" #include "mainrelay.h" +#include "userdb.h" #include "ns_turn_utils.h" -#include "ns_turn_server.h" #include "ns_turn_maps.h" +#include "ns_turn_server.h" #include "apputils.h" @@ -68,724 +68,690 @@ static TURN_MUTEX_DECLARE(o_to_realm_mutex); static ur_string_map *o_to_realm = NULL; static secrets_list_t realms_list; -void lock_realms(void) { - ur_string_map_lock(realms); -} +void lock_realms(void) { ur_string_map_lock(realms); } -void unlock_realms(void) { - ur_string_map_unlock(realms); -} +void unlock_realms(void) { ur_string_map_unlock(realms); } -void update_o_to_realm(ur_string_map * o_to_realm_new) { +void update_o_to_realm(ur_string_map *o_to_realm_new) { TURN_MUTEX_LOCK(&o_to_realm_mutex); ur_string_map_free(&o_to_realm); o_to_realm = o_to_realm_new; TURN_MUTEX_UNLOCK(&o_to_realm_mutex); } -void create_default_realm(void) -{ - if(default_realm_params_ptr) { - return; - } +void create_default_realm(void) { + if (default_realm_params_ptr) { + return; + } - static realm_params_t _default_realm_params = - { - 1, - { - "\0", /* name */ - {0,0,0} - }, - {0,NULL} - }; + static realm_params_t _default_realm_params = {1, + {"\0", /* name */ + {0, 0, 0}}, + {0, NULL}}; - /* init everything: */ - TURN_MUTEX_INIT_RECURSIVE(&o_to_realm_mutex); - init_secrets_list(&realms_list); - o_to_realm = ur_string_map_create(free); - default_realm_params_ptr = &_default_realm_params; - realms = ur_string_map_create(NULL); - lock_realms(); - default_realm_params_ptr->status.alloc_counters = ur_string_map_create(NULL); - unlock_realms(); + /* init everything: */ + TURN_MUTEX_INIT_RECURSIVE(&o_to_realm_mutex); + init_secrets_list(&realms_list); + o_to_realm = ur_string_map_create(free); + default_realm_params_ptr = &_default_realm_params; + realms = ur_string_map_create(NULL); + lock_realms(); + default_realm_params_ptr->status.alloc_counters = ur_string_map_create(NULL); + unlock_realms(); } -void get_default_realm_options(realm_options_t* ro) -{ - if(ro) { - lock_realms(); - memcpy(ro,&(default_realm_params_ptr->options),sizeof(realm_options_t)); - unlock_realms(); - } +void get_default_realm_options(realm_options_t *ro) { + if (ro) { + lock_realms(); + memcpy(ro, &(default_realm_params_ptr->options), sizeof(realm_options_t)); + unlock_realms(); + } } void set_default_realm_name(char *realm) { - lock_realms(); - ur_string_map_value_type value = (ur_string_map_value_type)default_realm_params_ptr; - STRCPY(default_realm_params_ptr->options.name,realm); - ur_string_map_put(realms, (ur_string_map_key_type)default_realm_params_ptr->options.name, value); - add_to_secrets_list(&realms_list, realm); - unlock_realms(); + lock_realms(); + ur_string_map_value_type value = (ur_string_map_value_type)default_realm_params_ptr; + STRCPY(default_realm_params_ptr->options.name, realm); + ur_string_map_put(realms, (ur_string_map_key_type)default_realm_params_ptr->options.name, value); + add_to_secrets_list(&realms_list, realm); + unlock_realms(); } -realm_params_t* get_realm(char* name) -{ - if(name && name[0]) { - lock_realms(); - ur_string_map_value_type value = 0; - ur_string_map_key_type key = (ur_string_map_key_type)name; - if (ur_string_map_get(realms, key, &value)) { - unlock_realms(); - return (realm_params_t*)value; - } else { - realm_params_t *ret = (realm_params_t*)malloc(sizeof(realm_params_t)); - memcpy(ret,default_realm_params_ptr,sizeof(realm_params_t)); - STRCPY(ret->options.name,name); - value = (ur_string_map_value_type)ret; - ur_string_map_put(realms, key, value); - ret->status.alloc_counters = ur_string_map_create(NULL); - add_to_secrets_list(&realms_list, name); - unlock_realms(); - return ret; - } - } +realm_params_t *get_realm(char *name) { + if (name && name[0]) { + lock_realms(); + ur_string_map_value_type value = 0; + ur_string_map_key_type key = (ur_string_map_key_type)name; + if (ur_string_map_get(realms, key, &value)) { + unlock_realms(); + return (realm_params_t *)value; + } else { + realm_params_t *ret = (realm_params_t *)malloc(sizeof(realm_params_t)); + memcpy(ret, default_realm_params_ptr, sizeof(realm_params_t)); + STRCPY(ret->options.name, name); + value = (ur_string_map_value_type)ret; + ur_string_map_put(realms, key, value); + ret->status.alloc_counters = ur_string_map_create(NULL); + add_to_secrets_list(&realms_list, name); + unlock_realms(); + return ret; + } + } - return default_realm_params_ptr; + return default_realm_params_ptr; } -int get_realm_data(char* name, realm_params_t* rp) -{ - lock_realms(); - memcpy(rp,get_realm(name),sizeof(realm_params_t)); - unlock_realms(); - return 0; +int get_realm_data(char *name, realm_params_t *rp) { + lock_realms(); + memcpy(rp, get_realm(name), sizeof(realm_params_t)); + unlock_realms(); + return 0; } -int get_realm_options_by_origin(char *origin, realm_options_t* ro) -{ - ur_string_map_value_type value = 0; - TURN_MUTEX_LOCK(&o_to_realm_mutex); - if (ur_string_map_get(o_to_realm, (ur_string_map_key_type) origin, &value) && value) { - char *realm = strdup((char*)value); - TURN_MUTEX_UNLOCK(&o_to_realm_mutex); - realm_params_t rp; - get_realm_data(realm, &rp); - memcpy(ro,&(rp.options),sizeof(realm_options_t)); - free(realm); - return 1; - } else { - TURN_MUTEX_UNLOCK(&o_to_realm_mutex); - get_default_realm_options(ro); - return 0; - } +int get_realm_options_by_origin(char *origin, realm_options_t *ro) { + ur_string_map_value_type value = 0; + TURN_MUTEX_LOCK(&o_to_realm_mutex); + if (ur_string_map_get(o_to_realm, (ur_string_map_key_type)origin, &value) && value) { + char *realm = strdup((char *)value); + TURN_MUTEX_UNLOCK(&o_to_realm_mutex); + realm_params_t rp; + get_realm_data(realm, &rp); + memcpy(ro, &(rp.options), sizeof(realm_options_t)); + free(realm); + return 1; + } else { + TURN_MUTEX_UNLOCK(&o_to_realm_mutex); + get_default_realm_options(ro); + return 0; + } } -void get_realm_options_by_name(char *realm, realm_options_t* ro) -{ - realm_params_t rp; - get_realm_data(realm, &rp); - memcpy(ro,&(rp.options),sizeof(realm_options_t)); +void get_realm_options_by_name(char *realm, realm_options_t *ro) { + realm_params_t rp; + get_realm_data(realm, &rp); + memcpy(ro, &(rp.options), sizeof(realm_options_t)); } -int change_total_quota(char *realm, int value) -{ - int ret = value; - lock_realms(); - realm_params_t* rp = get_realm(realm); - rp->options.perf_options.total_quota = value; - unlock_realms(); - return ret; +int change_total_quota(char *realm, int value) { + int ret = value; + lock_realms(); + realm_params_t *rp = get_realm(realm); + rp->options.perf_options.total_quota = value; + unlock_realms(); + return ret; } -int change_user_quota(char *realm, int value) -{ - int ret = value; - lock_realms(); - realm_params_t* rp = get_realm(realm); - rp->options.perf_options.user_quota = value; - unlock_realms(); - return ret; +int change_user_quota(char *realm, int value) { + int ret = value; + lock_realms(); + realm_params_t *rp = get_realm(realm); + rp->options.perf_options.user_quota = value; + unlock_realms(); + return ret; } -static void must_set_admin_realm(void *realm0) -{ - char* realm = (char*)realm0; - if(!realm || !realm[0]) { - fprintf(stderr, "The operation cannot be completed: the realm must be set.\n"); - exit(-1); - } +static void must_set_admin_realm(void *realm0) { + char *realm = (char *)realm0; + if (!realm || !realm[0]) { + fprintf(stderr, "The operation cannot be completed: the realm must be set.\n"); + exit(-1); + } } -static void must_set_admin_user(void *user0) -{ - char* user = (char*)user0; - if(!user || !user[0]) { - fprintf(stderr, "The operation cannot be completed: the user must be set.\n"); - exit(-1); - } +static void must_set_admin_user(void *user0) { + char *user = (char *)user0; + if (!user || !user[0]) { + fprintf(stderr, "The operation cannot be completed: the user must be set.\n"); + exit(-1); + } } -static void must_set_admin_pwd(void *pwd0) -{ - char* pwd = (char*)pwd0; - if(!pwd || !pwd[0]) { - fprintf(stderr, "The operation cannot be completed: the password must be set.\n"); - exit(-1); - } +static void must_set_admin_pwd(void *pwd0) { + char *pwd = (char *)pwd0; + if (!pwd || !pwd[0]) { + fprintf(stderr, "The operation cannot be completed: the password must be set.\n"); + exit(-1); + } } -static void must_set_admin_origin(void *origin0) -{ - char* origin = (char*)origin0; - if(!origin || !origin[0]) { - fprintf(stderr, "The operation cannot be completed: the origin must be set.\n"); - exit(-1); - } +static void must_set_admin_origin(void *origin0) { + char *origin = (char *)origin0; + if (!origin || !origin[0]) { + fprintf(stderr, "The operation cannot be completed: the origin must be set.\n"); + exit(-1); + } } /////////// SHARED SECRETS ///////////////// -void init_secrets_list(secrets_list_t *sl) -{ - if(sl) { - memset(sl,0,sizeof(secrets_list_t)); - } +void init_secrets_list(secrets_list_t *sl) { + if (sl) { + memset(sl, 0, sizeof(secrets_list_t)); + } } -void clean_secrets_list(secrets_list_t *sl) -{ - if(sl) { - if(sl->secrets) { - size_t i = 0; - for(i = 0;isz;++i) { - if(sl->secrets[i]) { - free(sl->secrets[i]); - } - } - free(sl->secrets); - sl->secrets = NULL; - sl->sz = 0; - } - } +void clean_secrets_list(secrets_list_t *sl) { + if (sl) { + if (sl->secrets) { + size_t i = 0; + for (i = 0; i < sl->sz; ++i) { + if (sl->secrets[i]) { + free(sl->secrets[i]); + } + } + free(sl->secrets); + sl->secrets = NULL; + sl->sz = 0; + } + } } -size_t get_secrets_list_size(secrets_list_t *sl) -{ - if(sl && sl->secrets) { - return sl->sz; - } - return 0; +size_t get_secrets_list_size(secrets_list_t *sl) { + if (sl && sl->secrets) { + return sl->sz; + } + return 0; } -const char* get_secrets_list_elem(secrets_list_t *sl, size_t i) -{ - if(get_secrets_list_size(sl)>i) { - return sl->secrets[i]; - } - return NULL; +const char *get_secrets_list_elem(secrets_list_t *sl, size_t i) { + if (get_secrets_list_size(sl) > i) { + return sl->secrets[i]; + } + return NULL; } -void add_to_secrets_list(secrets_list_t *sl, const char* elem) -{ - if(sl && elem) { - sl->secrets = (char**)realloc(sl->secrets,(sizeof(char*)*(sl->sz+1))); - sl->secrets[sl->sz] = strdup(elem); - sl->sz += 1; - } +void add_to_secrets_list(secrets_list_t *sl, const char *elem) { + if (sl && elem) { + sl->secrets = (char **)realloc(sl->secrets, (sizeof(char *) * (sl->sz + 1))); + sl->secrets[sl->sz] = strdup(elem); + sl->sz += 1; + } } //////////////////////////////////////////// -static int get_auth_secrets(secrets_list_t *sl, uint8_t *realm) -{ - int ret = -1; - const turn_dbdriver_t * dbd = get_dbdriver(); +static int get_auth_secrets(secrets_list_t *sl, uint8_t *realm) { + int ret = -1; + const turn_dbdriver_t *dbd = get_dbdriver(); - clean_secrets_list(sl); + clean_secrets_list(sl); + + if (get_secrets_list_size(&turn_params.default_users_db.ram_db.static_auth_secrets)) { + size_t i = 0; + for (i = 0; i < get_secrets_list_size(&turn_params.default_users_db.ram_db.static_auth_secrets); ++i) { + add_to_secrets_list(sl, get_secrets_list_elem(&turn_params.default_users_db.ram_db.static_auth_secrets, i)); + } + ret = 0; + } - if(get_secrets_list_size(&turn_params.default_users_db.ram_db.static_auth_secrets)) { - size_t i = 0; - for(i=0;iget_auth_secrets) { ret = (*dbd->get_auth_secrets)(sl, realm); } - return ret; + return ret; } /* * Timestamp retrieval */ -static turn_time_t get_rest_api_timestamp(char *usname) -{ - turn_time_t ts = 0; - int ts_set = 0; +static turn_time_t get_rest_api_timestamp(char *usname) { + turn_time_t ts = 0; + int ts_set = 0; - char *col = strchr(usname,turn_params.rest_api_separator); + char *col = strchr(usname, turn_params.rest_api_separator); - if(col) { - if(col == usname) { - usname +=1; - } else { - char *ptr = usname; - int found_non_figure = 0; - while(ptr < col) { - if(!(ptr[0]>='0' && ptr[0]<='9')) { - found_non_figure=1; - break; - } - ++ptr; - } - if(found_non_figure) { - ts = (turn_time_t)atol(col+1); - ts_set = 1; - } else { - *col=0; - ts = (turn_time_t)atol(usname); - ts_set = 1; - *col=turn_params.rest_api_separator; - } - } - } + if (col) { + if (col == usname) { + usname += 1; + } else { + char *ptr = usname; + int found_non_figure = 0; + while (ptr < col) { + if (!(ptr[0] >= '0' && ptr[0] <= '9')) { + found_non_figure = 1; + break; + } + ++ptr; + } + if (found_non_figure) { + ts = (turn_time_t)atol(col + 1); + ts_set = 1; + } else { + *col = 0; + ts = (turn_time_t)atol(usname); + ts_set = 1; + *col = turn_params.rest_api_separator; + } + } + } - if(!ts_set) { - ts = (turn_time_t)atol(usname); - } + if (!ts_set) { + ts = (turn_time_t)atol(usname); + } - return ts; + return ts; } -static char *get_real_username(char *usname) -{ - if(usname[0] && turn_params.use_auth_secret_with_timestamp) { - char *col=strchr(usname,turn_params.rest_api_separator); - if(col) { - if(col == usname) { - usname +=1; - } else { - char *ptr = usname; - int found_non_figure = 0; - while(ptr < col) { - if(!(ptr[0]>='0' && ptr[0]<='9')) { - found_non_figure=1; - break; - } - ++ptr; - } - if(!found_non_figure) { - usname = col+1; - } else { - *col=0; - usname = strdup(usname); - *col=turn_params.rest_api_separator; - return usname; - } - } - } - } +static char *get_real_username(char *usname) { + if (usname[0] && turn_params.use_auth_secret_with_timestamp) { + char *col = strchr(usname, turn_params.rest_api_separator); + if (col) { + if (col == usname) { + usname += 1; + } else { + char *ptr = usname; + int found_non_figure = 0; + while (ptr < col) { + if (!(ptr[0] >= '0' && ptr[0] <= '9')) { + found_non_figure = 1; + break; + } + ++ptr; + } + if (!found_non_figure) { + usname = col + 1; + } else { + *col = 0; + usname = strdup(usname); + *col = turn_params.rest_api_separator; + return usname; + } + } + } + } - return strdup(usname); + return strdup(usname); } /* * Password retrieval */ -int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, uint8_t *usname, uint8_t *realm, hmackey_t key, ioa_network_buffer_handle nbh) -{ - int ret = -1; +int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, uint8_t *usname, uint8_t *realm, hmackey_t key, + ioa_network_buffer_handle nbh) { + int ret = -1; - if(max_session_time) - *max_session_time = 0; + if (max_session_time) + *max_session_time = 0; - if(in_oauth && out_oauth && usname && usname[0]) { + if (in_oauth && out_oauth && usname && usname[0]) { - stun_attr_ref sar = stun_attr_get_first_by_type_str(ioa_network_buffer_data(nbh), - ioa_network_buffer_get_size(nbh), - STUN_ATTRIBUTE_OAUTH_ACCESS_TOKEN); - if(sar) { + stun_attr_ref sar = stun_attr_get_first_by_type_str(ioa_network_buffer_data(nbh), ioa_network_buffer_get_size(nbh), + STUN_ATTRIBUTE_OAUTH_ACCESS_TOKEN); + if (sar) { - int len = stun_attr_get_len(sar); - const uint8_t *value = stun_attr_get_value(sar); + int len = stun_attr_get_len(sar); + const uint8_t *value = stun_attr_get_value(sar); - *out_oauth = 1; + *out_oauth = 1; - if(len>0 && value) { + if (len > 0 && value) { - const turn_dbdriver_t * dbd = get_dbdriver(); + const turn_dbdriver_t *dbd = get_dbdriver(); - if (dbd && dbd->get_oauth_key) { + if (dbd && dbd->get_oauth_key) { - oauth_key_data_raw rawKey; - memset(&rawKey,0,sizeof(rawKey)); + oauth_key_data_raw rawKey; + memset(&rawKey, 0, sizeof(rawKey)); - int gres = (*(dbd->get_oauth_key))(usname,&rawKey); - if(gres<0) - return ret; + int gres = (*(dbd->get_oauth_key))(usname, &rawKey); + if (gres < 0) + return ret; - if(!rawKey.kid[0]) - return ret; + if (!rawKey.kid[0]) + return ret; - if(rawKey.lifetime) { - if(!turn_time_before(turn_time(),(turn_time_t)(rawKey.timestamp + rawKey.lifetime+OAUTH_TIME_DELTA))) { - return ret; - } - } + if (rawKey.lifetime) { + if (!turn_time_before(turn_time(), (turn_time_t)(rawKey.timestamp + rawKey.lifetime + OAUTH_TIME_DELTA))) { + return ret; + } + } - oauth_key_data okd; - memset(&okd,0,sizeof(okd)); + oauth_key_data okd; + memset(&okd, 0, sizeof(okd)); - convert_oauth_key_data_raw(&rawKey, &okd); + convert_oauth_key_data_raw(&rawKey, &okd); - char err_msg[1025] = "\0"; - size_t err_msg_size = sizeof(err_msg) - 1; + char err_msg[1025] = "\0"; + size_t err_msg_size = sizeof(err_msg) - 1; - oauth_key okey; - memset(&okey, 0, sizeof(okey)); + oauth_key okey; + memset(&okey, 0, sizeof(okey)); - if (convert_oauth_key_data(&okd, &okey, err_msg, err_msg_size) < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s\n", err_msg); - return -1; - } + if (convert_oauth_key_data(&okd, &okey, err_msg, err_msg_size) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s\n", err_msg); + return -1; + } - oauth_token dot; - memset((&dot), 0, sizeof(dot)); + oauth_token dot; + memset((&dot), 0, sizeof(dot)); - encoded_oauth_token etoken; - memset(&etoken, 0, sizeof(etoken)); + encoded_oauth_token etoken; + memset(&etoken, 0, sizeof(etoken)); - if((size_t)len > sizeof(etoken.token)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Encoded oAuth token is too large\n"); - return -1; - } - memcpy(etoken.token,value,(size_t)len); - etoken.size = (size_t)len; + if ((size_t)len > sizeof(etoken.token)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Encoded oAuth token is too large\n"); + return -1; + } + memcpy(etoken.token, value, (size_t)len); + etoken.size = (size_t)len; - const char* server_name = (char*)turn_params.oauth_server_name; - if(!(server_name && server_name[0])) { - server_name = (char*)realm; - if(!(server_name && server_name[0])) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot determine oAuth server name"); - return -1; - } - } + const char *server_name = (char *)turn_params.oauth_server_name; + if (!(server_name && server_name[0])) { + server_name = (char *)realm; + if (!(server_name && server_name[0])) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot determine oAuth server name"); + return -1; + } + } - if (decode_oauth_token((const uint8_t *) server_name, &etoken,&okey, &dot) < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot decode oauth token\n"); - return -1; - } + if (decode_oauth_token((const uint8_t *)server_name, &etoken, &okey, &dot) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot decode oauth token\n"); + return -1; + } - switch(dot.enc_block.key_length) { - case SHA1SIZEBYTES: - break; - case SHA256SIZEBYTES: - case SHA384SIZEBYTES: - case SHA512SIZEBYTES: - default: - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong size of the MAC key in oAuth token(3): %d\n",(int)dot.enc_block.key_length); - return -1; - }; + switch (dot.enc_block.key_length) { + case SHA1SIZEBYTES: + break; + case SHA256SIZEBYTES: + case SHA384SIZEBYTES: + case SHA512SIZEBYTES: + default: + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong size of the MAC key in oAuth token(3): %d\n", + (int)dot.enc_block.key_length); + return -1; + }; - password_t pwdtmp; - if(stun_check_message_integrity_by_key_str(TURN_CREDENTIALS_LONG_TERM, - ioa_network_buffer_data(nbh), - ioa_network_buffer_get_size(nbh), - dot.enc_block.mac_key, - pwdtmp, - SHATYPE_DEFAULT)>0) { + password_t pwdtmp; + if (stun_check_message_integrity_by_key_str(TURN_CREDENTIALS_LONG_TERM, ioa_network_buffer_data(nbh), + ioa_network_buffer_get_size(nbh), dot.enc_block.mac_key, pwdtmp, + SHATYPE_DEFAULT) > 0) { - turn_time_t lifetime = (turn_time_t)(dot.enc_block.lifetime); - if(lifetime) { - turn_time_t ts = (turn_time_t)(dot.enc_block.timestamp >> 16); - turn_time_t to = ts + lifetime + OAUTH_TIME_DELTA; - turn_time_t ct = turn_time(); - if(!turn_time_before(ct,to)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "oAuth token is too old\n"); - return -1; - } - if(max_session_time) { - *max_session_time = to - ct; - } - } + turn_time_t lifetime = (turn_time_t)(dot.enc_block.lifetime); + if (lifetime) { + turn_time_t ts = (turn_time_t)(dot.enc_block.timestamp >> 16); + turn_time_t to = ts + lifetime + OAUTH_TIME_DELTA; + turn_time_t ct = turn_time(); + if (!turn_time_before(ct, to)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "oAuth token is too old\n"); + return -1; + } + if (max_session_time) { + *max_session_time = to - ct; + } + } - memcpy(key,dot.enc_block.mac_key,dot.enc_block.key_length); + memcpy(key, dot.enc_block.mac_key, dot.enc_block.key_length); - if(rawKey.realm[0]) { - memcpy(realm,rawKey.realm,sizeof(rawKey.realm)); - } + if (rawKey.realm[0]) { + memcpy(realm, rawKey.realm, sizeof(rawKey.realm)); + } - ret = 0; - } - } - } - } - } + ret = 0; + } + } + } + } + } - if(out_oauth && *out_oauth) { - return ret; - } + if (out_oauth && *out_oauth) { + return ret; + } - if(turn_params.use_auth_secret_with_timestamp) { + if (turn_params.use_auth_secret_with_timestamp) { - turn_time_t ctime = (turn_time_t) time(NULL); - turn_time_t ts = 0; - secrets_list_t sl; - size_t sll = 0; + turn_time_t ctime = (turn_time_t)time(NULL); + turn_time_t ts = 0; + secrets_list_t sl; + size_t sll = 0; - init_secrets_list(&sl); + init_secrets_list(&sl); - if(get_auth_secrets(&sl, realm)<0) - return ret; + if (get_auth_secrets(&sl, realm) < 0) + return ret; - ts = get_rest_api_timestamp((char*)usname); + ts = get_rest_api_timestamp((char *)usname); - if(!turn_time_before(ts, ctime)) { + if (!turn_time_before(ts, ctime)) { - uint8_t hmac[MAXSHASIZE]; - unsigned int hmac_len; - password_t pwdtmp; + uint8_t hmac[MAXSHASIZE]; + unsigned int hmac_len; + password_t pwdtmp; - hmac[0] = 0; + hmac[0] = 0; - stun_attr_ref sar = stun_attr_get_first_by_type_str(ioa_network_buffer_data(nbh), - ioa_network_buffer_get_size(nbh), - STUN_ATTRIBUTE_MESSAGE_INTEGRITY); - if (!sar) - return -1; + stun_attr_ref sar = stun_attr_get_first_by_type_str( + ioa_network_buffer_data(nbh), ioa_network_buffer_get_size(nbh), STUN_ATTRIBUTE_MESSAGE_INTEGRITY); + if (!sar) + return -1; - int sarlen = stun_attr_get_len(sar); - switch(sarlen) { - case SHA1SIZEBYTES: - hmac_len = SHA1SIZEBYTES; - break; - case SHA256SIZEBYTES: - case SHA384SIZEBYTES: - case SHA512SIZEBYTES: - default: - return -1; - }; + int sarlen = stun_attr_get_len(sar); + switch (sarlen) { + case SHA1SIZEBYTES: + hmac_len = SHA1SIZEBYTES; + break; + case SHA256SIZEBYTES: + case SHA384SIZEBYTES: + case SHA512SIZEBYTES: + default: + return -1; + }; - for(sll=0;sll=0) { - size_t pwd_length = 0; - char *pwd = base64_encode(hmac,hmac_len,&pwd_length); + if (secret) { + if (stun_calculate_hmac(usname, strlen((char *)usname), (const uint8_t *)secret, strlen(secret), hmac, + &hmac_len, SHATYPE_DEFAULT) >= 0) { + size_t pwd_length = 0; + char *pwd = base64_encode(hmac, hmac_len, &pwd_length); - if(pwd) { - if(pwd_length<1) { - free(pwd); - } else { - if(stun_produce_integrity_key_str((uint8_t*)usname, realm, (uint8_t*)pwd, key, SHATYPE_DEFAULT)>=0) { + if (pwd) { + if (pwd_length < 1) { + free(pwd); + } else { + if (stun_produce_integrity_key_str((uint8_t *)usname, realm, (uint8_t *)pwd, key, SHATYPE_DEFAULT) >= + 0) { - if(stun_check_message_integrity_by_key_str(TURN_CREDENTIALS_LONG_TERM, - ioa_network_buffer_data(nbh), - ioa_network_buffer_get_size(nbh), - key, - pwdtmp, - SHATYPE_DEFAULT)>0) { + if (stun_check_message_integrity_by_key_str(TURN_CREDENTIALS_LONG_TERM, ioa_network_buffer_data(nbh), + ioa_network_buffer_get_size(nbh), key, pwdtmp, + SHATYPE_DEFAULT) > 0) { - ret = 0; - } - } - free(pwd); + ret = 0; + } + } + free(pwd); - if(ret==0) - break; - } - } - } - } - } - } + if (ret == 0) + break; + } + } + } + } + } + } - clean_secrets_list(&sl); + clean_secrets_list(&sl); - return ret; - } + return ret; + } - ur_string_map_value_type ukey = NULL; - ur_string_map_lock(turn_params.default_users_db.ram_db.static_accounts); - if(ur_string_map_get(turn_params.default_users_db.ram_db.static_accounts, (ur_string_map_key_type)usname, &ukey)) { - ret = 0; - } - ur_string_map_unlock(turn_params.default_users_db.ram_db.static_accounts); + ur_string_map_value_type ukey = NULL; + ur_string_map_lock(turn_params.default_users_db.ram_db.static_accounts); + if (ur_string_map_get(turn_params.default_users_db.ram_db.static_accounts, (ur_string_map_key_type)usname, &ukey)) { + ret = 0; + } + ur_string_map_unlock(turn_params.default_users_db.ram_db.static_accounts); - if(ret==0) { - size_t sz = get_hmackey_size(SHATYPE_DEFAULT); - memcpy(key,ukey,sz); - return 0; - } + if (ret == 0) { + size_t sz = get_hmackey_size(SHATYPE_DEFAULT); + memcpy(key, ukey, sz); + return 0; + } - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->get_user_key) { - ret = (*(dbd->get_user_key))(usname, realm, key); - } + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->get_user_key) { + ret = (*(dbd->get_user_key))(usname, realm, key); + } - return ret; + return ret; } -uint8_t *start_user_check(turnserver_id id, turn_credential_type ct, int in_oauth, int *out_oauth, uint8_t *usname, uint8_t *realm, get_username_resume_cb resume, ioa_net_data *in_buffer, uint64_t ctxkey, int *postpone_reply) -{ - *postpone_reply = 1; +uint8_t *start_user_check(turnserver_id id, turn_credential_type ct, int in_oauth, int *out_oauth, uint8_t *usname, + uint8_t *realm, get_username_resume_cb resume, ioa_net_data *in_buffer, uint64_t ctxkey, + int *postpone_reply) { + *postpone_reply = 1; - struct auth_message am; - memset(&am, 0, sizeof(struct auth_message)); - am.id = id; - am.ct = ct; - am.in_oauth = in_oauth; - am.out_oauth = *out_oauth; - STRCPY(am.username,usname); - STRCPY(am.realm,realm); - am.resume_func = resume; - memcpy(&(am.in_buffer),in_buffer,sizeof(ioa_net_data)); - in_buffer->nbh = NULL; - am.ctxkey = ctxkey; + struct auth_message am; + memset(&am, 0, sizeof(struct auth_message)); + am.id = id; + am.ct = ct; + am.in_oauth = in_oauth; + am.out_oauth = *out_oauth; + STRCPY(am.username, usname); + STRCPY(am.realm, realm); + am.resume_func = resume; + memcpy(&(am.in_buffer), in_buffer, sizeof(ioa_net_data)); + in_buffer->nbh = NULL; + am.ctxkey = ctxkey; - send_auth_message_to_auth_server(&am); + send_auth_message_to_auth_server(&am); - return NULL; + return NULL; } -int check_new_allocation_quota(uint8_t *user, int oauth, uint8_t *realm) -{ - int ret = 0; - if (user || oauth) { - uint8_t *username = oauth ? (uint8_t*)strdup("") : (uint8_t*)get_real_username((char*)user); - realm_params_t *rp = get_realm((char*)realm); - ur_string_map_lock(rp->status.alloc_counters); - if (rp->options.perf_options.total_quota && (rp->status.total_current_allocs >= rp->options.perf_options.total_quota)) { - ret = -1; - } else if(username[0]){ - ur_string_map_value_type value = 0; - if (!ur_string_map_get(rp->status.alloc_counters, (ur_string_map_key_type) username, &value)) { - value = (ur_string_map_value_type) 1; - ur_string_map_put(rp->status.alloc_counters, (ur_string_map_key_type) username, value); - ++(rp->status.total_current_allocs); - } else { - if ((rp->options.perf_options.user_quota) && ((size_t) value >= (size_t)(rp->options.perf_options.user_quota))) { - ret = -1; - } else { - value = (ur_string_map_value_type)(((size_t)value) + 1); - ur_string_map_put(rp->status.alloc_counters, (ur_string_map_key_type) username, value); - ++(rp->status.total_current_allocs); - } - } - } else { - ++(rp->status.total_current_allocs); - } - free(username); - ur_string_map_unlock(rp->status.alloc_counters); - } - return ret; +int check_new_allocation_quota(uint8_t *user, int oauth, uint8_t *realm) { + int ret = 0; + if (user || oauth) { + uint8_t *username = oauth ? (uint8_t *)strdup("") : (uint8_t *)get_real_username((char *)user); + realm_params_t *rp = get_realm((char *)realm); + ur_string_map_lock(rp->status.alloc_counters); + if (rp->options.perf_options.total_quota && + (rp->status.total_current_allocs >= rp->options.perf_options.total_quota)) { + ret = -1; + } else if (username[0]) { + ur_string_map_value_type value = 0; + if (!ur_string_map_get(rp->status.alloc_counters, (ur_string_map_key_type)username, &value)) { + value = (ur_string_map_value_type)1; + ur_string_map_put(rp->status.alloc_counters, (ur_string_map_key_type)username, value); + ++(rp->status.total_current_allocs); + } else { + if ((rp->options.perf_options.user_quota) && ((size_t)value >= (size_t)(rp->options.perf_options.user_quota))) { + ret = -1; + } else { + value = (ur_string_map_value_type)(((size_t)value) + 1); + ur_string_map_put(rp->status.alloc_counters, (ur_string_map_key_type)username, value); + ++(rp->status.total_current_allocs); + } + } + } else { + ++(rp->status.total_current_allocs); + } + free(username); + ur_string_map_unlock(rp->status.alloc_counters); + } + return ret; } -void release_allocation_quota(uint8_t *user, int oauth, uint8_t *realm) -{ - if (user) { - uint8_t *username = oauth ? (uint8_t*)strdup("") : (uint8_t*)get_real_username((char*)user); - realm_params_t *rp = get_realm((char*)realm); - ur_string_map_lock(rp->status.alloc_counters); - if(username[0]) { - ur_string_map_value_type value = 0; - ur_string_map_get(rp->status.alloc_counters, (ur_string_map_key_type) username, &value); - if (value) { - value = (ur_string_map_value_type)(((size_t)value) - 1); - if (value == 0) { - ur_string_map_del(rp->status.alloc_counters, (ur_string_map_key_type) username); - } else { - ur_string_map_put(rp->status.alloc_counters, (ur_string_map_key_type) username, value); - } - } - } - if (rp->status.total_current_allocs) - --(rp->status.total_current_allocs); - ur_string_map_unlock(rp->status.alloc_counters); - free(username); - } +void release_allocation_quota(uint8_t *user, int oauth, uint8_t *realm) { + if (user) { + uint8_t *username = oauth ? (uint8_t *)strdup("") : (uint8_t *)get_real_username((char *)user); + realm_params_t *rp = get_realm((char *)realm); + ur_string_map_lock(rp->status.alloc_counters); + if (username[0]) { + ur_string_map_value_type value = 0; + ur_string_map_get(rp->status.alloc_counters, (ur_string_map_key_type)username, &value); + if (value) { + value = (ur_string_map_value_type)(((size_t)value) - 1); + if (value == 0) { + ur_string_map_del(rp->status.alloc_counters, (ur_string_map_key_type)username); + } else { + ur_string_map_put(rp->status.alloc_counters, (ur_string_map_key_type)username, value); + } + } + } + if (rp->status.total_current_allocs) + --(rp->status.total_current_allocs); + ur_string_map_unlock(rp->status.alloc_counters); + free(username); + } } ////////////////////////////////// -int add_static_user_account(char *user) -{ - /* Realm is either default or empty for users taken from file or command-line */ - if(user && !turn_params.use_auth_secret_with_timestamp) { - char *s = strstr(user, ":"); - if(!s || (s==user) || (strlen(s)<2)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user account: %s\n",user); - } else { - size_t ulen = s-user; - char *usname = (char*)calloc(ulen+1, sizeof(char)); - strncpy(usname,user,ulen); - usname[ulen]=0; - if(SASLprep((uint8_t*)usname)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name: %s\n",user); - free(usname); - return -1; - } - s = skip_blanks(s+1); - hmackey_t *key = (hmackey_t*)malloc(sizeof(hmackey_t)); - if(strstr(s,"0x")==s) { - char *keysource = s + 2; - size_t sz = get_hmackey_size(SHATYPE_DEFAULT); - if(strlen(keysource)options.name, (uint8_t*)s, *key, SHATYPE_DEFAULT); - } - { - ur_string_map_lock(turn_params.default_users_db.ram_db.static_accounts); - ur_string_map_put(turn_params.default_users_db.ram_db.static_accounts, (ur_string_map_key_type)usname, (ur_string_map_value_type)*key); - ur_string_map_unlock(turn_params.default_users_db.ram_db.static_accounts); - } - turn_params.default_users_db.ram_db.users_number++; - free(usname); - return 0; - } - } +int add_static_user_account(char *user) { + /* Realm is either default or empty for users taken from file or command-line */ + if (user && !turn_params.use_auth_secret_with_timestamp) { + char *s = strstr(user, ":"); + if (!s || (s == user) || (strlen(s) < 2)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user account: %s\n", user); + } else { + size_t ulen = s - user; + char *usname = (char *)calloc(ulen + 1, sizeof(char)); + strncpy(usname, user, ulen); + usname[ulen] = 0; + if (SASLprep((uint8_t *)usname) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name: %s\n", user); + free(usname); + return -1; + } + s = skip_blanks(s + 1); + hmackey_t *key = (hmackey_t *)malloc(sizeof(hmackey_t)); + if (strstr(s, "0x") == s) { + char *keysource = s + 2; + size_t sz = get_hmackey_size(SHATYPE_DEFAULT); + if (strlen(keysource) < sz * 2) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key format: %s\n", s); + } + if (convert_string_key_to_binary(keysource, *key, sz) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key: %s\n", s); + free(usname); + free(key); + return -1; + } + } else { + // this is only for default realm + stun_produce_integrity_key_str((uint8_t *)usname, (uint8_t *)get_realm(NULL)->options.name, (uint8_t *)s, *key, + SHATYPE_DEFAULT); + } + { + ur_string_map_lock(turn_params.default_users_db.ram_db.static_accounts); + ur_string_map_put(turn_params.default_users_db.ram_db.static_accounts, (ur_string_map_key_type)usname, + (ur_string_map_value_type)*key); + ur_string_map_unlock(turn_params.default_users_db.ram_db.static_accounts); + } + turn_params.default_users_db.ram_db.users_number++; + free(usname); + return 0; + } + } - return -1; + return -1; } ////////////////// Admin ///////////////////////// -static int list_users(uint8_t *realm, int is_admin) -{ - const turn_dbdriver_t * dbd = get_dbdriver(); +static int list_users(uint8_t *realm, int is_admin) { + const turn_dbdriver_t *dbd = get_dbdriver(); if (dbd) { - if(is_admin) { - if(dbd->list_admin_users) { - (*dbd->list_admin_users)(0); - } - } else { - if(dbd->list_users) { - (*dbd->list_users)(realm,NULL,NULL); - } - } + if (is_admin) { + if (dbd->list_admin_users) { + (*dbd->list_admin_users)(0); + } + } else { + if (dbd->list_users) { + (*dbd->list_users)(realm, NULL, NULL); + } + } } return 0; } -static int show_secret(uint8_t *realm) -{ - const turn_dbdriver_t * dbd = get_dbdriver(); +static int show_secret(uint8_t *realm) { + const turn_dbdriver_t *dbd = get_dbdriver(); if (dbd && dbd->list_secrets) { - (*dbd->list_secrets)(realm,NULL,NULL); + (*dbd->list_secrets)(realm, NULL, NULL); } return 0; @@ -793,215 +759,207 @@ static int show_secret(uint8_t *realm) static int del_secret(uint8_t *secret, uint8_t *realm) { - must_set_admin_realm(realm); + must_set_admin_realm(realm); - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->del_secret) { - (*dbd->del_secret)(secret, realm); - } - - return 0; -} - -static int set_secret(uint8_t *secret, uint8_t *realm) { - - if(!secret || (secret[0]==0)) - return 0; - - must_set_admin_realm(realm); - - del_secret(secret, realm); - - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->set_secret) { - (*dbd->set_secret)(secret, realm); - } - - return 0; -} - -static int add_origin(uint8_t *origin0, uint8_t *realm) -{ - uint8_t origin[STUN_MAX_ORIGIN_SIZE+1]; - - get_canonic_origin((const char *)origin0, (char *)origin, sizeof(origin)-1); - - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->add_origin) { - (*dbd->add_origin)(origin, realm); - } - - return 0; -} - -static int del_origin(uint8_t *origin0) -{ - uint8_t origin[STUN_MAX_ORIGIN_SIZE+1]; - - get_canonic_origin((const char *)origin0, (char *)origin, sizeof(origin)-1); - - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->del_origin) { - (*dbd->del_origin)(origin); - } - - return 0; -} - -static int list_origins(uint8_t *realm) -{ - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->list_origins) { - (*dbd->list_origins)(realm,NULL,NULL); + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->del_secret) { + (*dbd->del_secret)(secret, realm); } return 0; } -static int set_realm_option_one(uint8_t *realm, unsigned long value, const char* opt) -{ - if(value == (unsigned long)-1) - return 0; +static int set_secret(uint8_t *secret, uint8_t *realm) { - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->set_realm_option_one) { - (*dbd->set_realm_option_one)(realm, value, opt); - } + if (!secret || (secret[0] == 0)) + return 0; - return 0; + must_set_admin_realm(realm); + + del_secret(secret, realm); + + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->set_secret) { + (*dbd->set_secret)(secret, realm); + } + + return 0; } -static int set_realm_option(uint8_t *realm, perf_options_t *po) -{ - set_realm_option_one(realm,(unsigned long)po->max_bps,"max-bps"); - set_realm_option_one(realm,(unsigned long)po->user_quota,"user-quota"); - set_realm_option_one(realm,(unsigned long)po->total_quota,"total-quota"); - return 0; +static int add_origin(uint8_t *origin0, uint8_t *realm) { + uint8_t origin[STUN_MAX_ORIGIN_SIZE + 1]; + + get_canonic_origin((const char *)origin0, (char *)origin, sizeof(origin) - 1); + + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->add_origin) { + (*dbd->add_origin)(origin, realm); + } + + return 0; } -static int list_realm_options(uint8_t *realm) -{ - const turn_dbdriver_t * dbd = get_dbdriver(); +static int del_origin(uint8_t *origin0) { + uint8_t origin[STUN_MAX_ORIGIN_SIZE + 1]; + + get_canonic_origin((const char *)origin0, (char *)origin, sizeof(origin) - 1); + + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->del_origin) { + (*dbd->del_origin)(origin); + } + + return 0; +} + +static int list_origins(uint8_t *realm) { + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->list_origins) { + (*dbd->list_origins)(realm, NULL, NULL); + } + + return 0; +} + +static int set_realm_option_one(uint8_t *realm, unsigned long value, const char *opt) { + if (value == (unsigned long)-1) + return 0; + + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->set_realm_option_one) { + (*dbd->set_realm_option_one)(realm, value, opt); + } + + return 0; +} + +static int set_realm_option(uint8_t *realm, perf_options_t *po) { + set_realm_option_one(realm, (unsigned long)po->max_bps, "max-bps"); + set_realm_option_one(realm, (unsigned long)po->user_quota, "user-quota"); + set_realm_option_one(realm, (unsigned long)po->total_quota, "total-quota"); + return 0; +} + +static int list_realm_options(uint8_t *realm) { + const turn_dbdriver_t *dbd = get_dbdriver(); if (dbd && dbd->list_realm_options) { (*dbd->list_realm_options)(realm); - } + } - return 0; + return 0; } -int adminuser(uint8_t *user, uint8_t *realm, uint8_t *pwd, uint8_t *secret, uint8_t *origin, TURNADMIN_COMMAND_TYPE ct, perf_options_t *po, int is_admin) -{ - hmackey_t key; - char skey[sizeof(hmackey_t) * 2 + 1]; +int adminuser(uint8_t *user, uint8_t *realm, uint8_t *pwd, uint8_t *secret, uint8_t *origin, TURNADMIN_COMMAND_TYPE ct, + perf_options_t *po, int is_admin) { + hmackey_t key; + char skey[sizeof(hmackey_t) * 2 + 1]; - if (ct == TA_LIST_USERS) { - return list_users(realm, is_admin); - } + if (ct == TA_LIST_USERS) { + return list_users(realm, is_admin); + } - if (ct == TA_LIST_ORIGINS) { - return list_origins(realm); - } + if (ct == TA_LIST_ORIGINS) { + return list_origins(realm); + } - if (ct == TA_SHOW_SECRET) { - return show_secret(realm); - } + if (ct == TA_SHOW_SECRET) { + return show_secret(realm); + } - if (ct == TA_SET_SECRET) { - return set_secret(secret, realm); - } + if (ct == TA_SET_SECRET) { + return set_secret(secret, realm); + } - if (ct == TA_DEL_SECRET) { - return del_secret(secret, realm); - } + if (ct == TA_DEL_SECRET) { + return del_secret(secret, realm); + } - if (ct == TA_ADD_ORIGIN) { - must_set_admin_origin(origin); - must_set_admin_realm(realm); - return add_origin(origin, realm); - } + if (ct == TA_ADD_ORIGIN) { + must_set_admin_origin(origin); + must_set_admin_realm(realm); + return add_origin(origin, realm); + } - if (ct == TA_DEL_ORIGIN) { - must_set_admin_origin(origin); - return del_origin(origin); - } + if (ct == TA_DEL_ORIGIN) { + must_set_admin_origin(origin); + return del_origin(origin); + } - if (ct == TA_SET_REALM_OPTION) { - must_set_admin_realm(realm); - if (!(po && (po->max_bps != ((band_limit_t) -1) || po->total_quota >= 0 || po->user_quota >= 0))) { - fprintf(stderr, "The operation cannot be completed: a realm option must be set.\n"); - exit(-1); - } - return set_realm_option(realm, po); - } + if (ct == TA_SET_REALM_OPTION) { + must_set_admin_realm(realm); + if (!(po && (po->max_bps != ((band_limit_t)-1) || po->total_quota >= 0 || po->user_quota >= 0))) { + fprintf(stderr, "The operation cannot be completed: a realm option must be set.\n"); + exit(-1); + } + return set_realm_option(realm, po); + } - if (ct == TA_LIST_REALM_OPTIONS) { - return list_realm_options(realm); - } + if (ct == TA_LIST_REALM_OPTIONS) { + return list_realm_options(realm); + } - must_set_admin_user(user); + must_set_admin_user(user); - if (ct != TA_DELETE_USER && !is_admin) { + if (ct != TA_DELETE_USER && !is_admin) { - must_set_admin_pwd(pwd); + must_set_admin_pwd(pwd); - { - stun_produce_integrity_key_str(user, realm, pwd, key, SHATYPE_DEFAULT); - size_t i = 0; - size_t sz = get_hmackey_size(SHATYPE_DEFAULT); - int maxsz = (int) (sz * 2) + 1; - char *s = skey; - for (i = 0; (i < sz) && (maxsz > 2); i++) { - snprintf(s, (size_t) (sz * 2), "%02x", (unsigned int) key[i]); - maxsz -= 2; - s += 2; - } - skey[sz * 2] = 0; - } - } + { + stun_produce_integrity_key_str(user, realm, pwd, key, SHATYPE_DEFAULT); + size_t i = 0; + size_t sz = get_hmackey_size(SHATYPE_DEFAULT); + int maxsz = (int)(sz * 2) + 1; + char *s = skey; + for (i = 0; (i < sz) && (maxsz > 2); i++) { + snprintf(s, (size_t)(sz * 2), "%02x", (unsigned int)key[i]); + maxsz -= 2; + s += 2; + } + skey[sz * 2] = 0; + } + } - const turn_dbdriver_t * dbd = get_dbdriver(); + const turn_dbdriver_t *dbd = get_dbdriver(); - if (ct == TA_PRINT_KEY) { + if (ct == TA_PRINT_KEY) { - printf("0x%s\n", skey); + printf("0x%s\n", skey); - } else if (dbd) { + } else if (dbd) { - if(!is_admin) - must_set_admin_realm(realm); + if (!is_admin) + must_set_admin_realm(realm); - if (ct == TA_DELETE_USER) { - if(is_admin) { - if (dbd->del_admin_user) - (*dbd->del_admin_user)(user); - } else { - if (dbd->del_user) - (*dbd->del_user)(user, realm); - } - } else if (ct == TA_UPDATE_USER) { - if(is_admin) { - must_set_admin_pwd(pwd); - if (dbd->set_admin_user) { - password_t password; - generate_new_enc_password((char*)pwd,(char*)password); - (*dbd->set_admin_user)(user, realm, password); - } - } else { - if (dbd->set_user_key) - (*dbd->set_user_key)(user, realm, skey); - } - } + if (ct == TA_DELETE_USER) { + if (is_admin) { + if (dbd->del_admin_user) + (*dbd->del_admin_user)(user); + } else { + if (dbd->del_user) + (*dbd->del_user)(user, realm); + } + } else if (ct == TA_UPDATE_USER) { + if (is_admin) { + must_set_admin_pwd(pwd); + if (dbd->set_admin_user) { + password_t password; + generate_new_enc_password((char *)pwd, (char *)password); + (*dbd->set_admin_user)(user, realm, password); + } + } else { + if (dbd->set_user_key) + (*dbd->set_user_key)(user, realm, skey); + } + } + } - } - - return 0; + return 0; } /////////// PING ////////////// -void auth_ping(redis_context_handle rch) -{ - const turn_dbdriver_t * dbd = get_dbdriver(); +void auth_ping(redis_context_handle rch) { + const turn_dbdriver_t *dbd = get_dbdriver(); if (dbd && dbd->auth_ping) { (*dbd->auth_ping)(rch); } @@ -1011,60 +969,59 @@ void auth_ping(redis_context_handle rch) #if defined(DB_TEST) -void run_db_test(void) -{ - turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd) { +void run_db_test(void) { + turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd) { - printf("DB TEST 1:\n"); - dbd->list_oauth_keys(); + printf("DB TEST 1:\n"); + dbd->list_oauth_keys(); - printf("DB TEST 2:\n"); - oauth_key_data_raw key_; - oauth_key_data_raw *key=&key_; - dbd->get_oauth_key((const uint8_t*)"north",key); - printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s\n", - key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->as_rs_alg); + printf("DB TEST 2:\n"); + oauth_key_data_raw key_; + oauth_key_data_raw *key = &key_; + dbd->get_oauth_key((const uint8_t *)"north", key); + printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s\n", key->kid, key->ikm_key, + (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->as_rs_alg); - printf("DB TEST 3:\n"); + printf("DB TEST 3:\n"); - STRCPY(key->as_rs_alg,"as_rs_alg"); - STRCPY(key->ikm_key,"ikm_key"); - STRCPY(key->kid,"kid"); - key->timestamp = 123; - key->lifetime = 456; - dbd->del_oauth_key((const uint8_t*)"kid"); - dbd->set_oauth_key(key); - dbd->list_oauth_keys(); + STRCPY(key->as_rs_alg, "as_rs_alg"); + STRCPY(key->ikm_key, "ikm_key"); + STRCPY(key->kid, "kid"); + key->timestamp = 123; + key->lifetime = 456; + dbd->del_oauth_key((const uint8_t *)"kid"); + dbd->set_oauth_key(key); + dbd->list_oauth_keys(); - printf("DB TEST 4:\n"); - dbd->get_oauth_key((const uint8_t*)"kid",key); - printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s\n", - key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->as_rs_alg); + printf("DB TEST 4:\n"); + dbd->get_oauth_key((const uint8_t *)"kid", key); + printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s\n", key->kid, key->ikm_key, + (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->as_rs_alg); - printf("DB TEST 5:\n"); - dbd->del_oauth_key((const uint8_t*)"kid"); - dbd->list_oauth_keys(); + printf("DB TEST 5:\n"); + dbd->del_oauth_key((const uint8_t *)"kid"); + dbd->list_oauth_keys(); - printf("DB TEST 6:\n"); + printf("DB TEST 6:\n"); - dbd->get_oauth_key((const uint8_t*)"north",key); + dbd->get_oauth_key((const uint8_t *)"north", key); - oauth_key_data oakd; - convert_oauth_key_data_raw(key, &oakd); - printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s\n", - oakd.kid, oakd.ikm_key, (unsigned long long)oakd.timestamp, (unsigned long)oakd.lifetime, oakd.as_rs_alg); + oauth_key_data oakd; + convert_oauth_key_data_raw(key, &oakd); + printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s\n", oakd.kid, oakd.ikm_key, + (unsigned long long)oakd.timestamp, (unsigned long)oakd.lifetime, oakd.as_rs_alg); - oauth_key oak; - char err_msg[1025]; - err_msg[0]=0; - if(convert_oauth_key_data(&oakd,&oak,err_msg,sizeof(err_msg)-1)<0) { - printf(" ERROR: %s\n",err_msg); - } else { - printf(" OK!\n"); - } - printf("DB TEST END\n"); - } + oauth_key oak; + char err_msg[1025]; + err_msg[0] = 0; + if (convert_oauth_key_data(&oakd, &oak, err_msg, sizeof(err_msg) - 1) < 0) { + printf(" ERROR: %s\n", err_msg); + } else { + printf(" OK!\n"); + } + printf("DB TEST END\n"); + } } #endif @@ -1072,240 +1029,225 @@ void run_db_test(void) ///////////////// WHITE/BLACK IP LISTS /////////////////// #if !defined(TURN_NO_RWLOCK) -static pthread_rwlock_t* whitelist_rwlock = NULL; -static pthread_rwlock_t* blacklist_rwlock = NULL; +static pthread_rwlock_t *whitelist_rwlock = NULL; +static pthread_rwlock_t *blacklist_rwlock = NULL; #else static TURN_MUTEX_DECLARE(whitelist_mutex); static TURN_MUTEX_DECLARE(blacklist_mutex); #endif -static ip_range_list_t* ipwhitelist = NULL; -static ip_range_list_t* ipblacklist = NULL; +static ip_range_list_t *ipwhitelist = NULL; +static ip_range_list_t *ipblacklist = NULL; -void init_dynamic_ip_lists(void) -{ +void init_dynamic_ip_lists(void) { #if !defined(TURN_NO_RWLOCK) - whitelist_rwlock = (pthread_rwlock_t*) malloc(sizeof(pthread_rwlock_t)); - pthread_rwlock_init(whitelist_rwlock, NULL); + whitelist_rwlock = (pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t)); + pthread_rwlock_init(whitelist_rwlock, NULL); - blacklist_rwlock = (pthread_rwlock_t*) malloc(sizeof(pthread_rwlock_t)); - pthread_rwlock_init(blacklist_rwlock, NULL); + blacklist_rwlock = (pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t)); + pthread_rwlock_init(blacklist_rwlock, NULL); #else - TURN_MUTEX_INIT(&whitelist_mutex); - TURN_MUTEX_INIT(&blacklist_mutex); + TURN_MUTEX_INIT(&whitelist_mutex); + TURN_MUTEX_INIT(&blacklist_mutex); #endif } -void ioa_lock_whitelist(ioa_engine_handle e) -{ - UNUSED_ARG(e); +void ioa_lock_whitelist(ioa_engine_handle e) { + UNUSED_ARG(e); #if !defined(TURN_NO_RWLOCK) - pthread_rwlock_rdlock(whitelist_rwlock); + pthread_rwlock_rdlock(whitelist_rwlock); #else - TURN_MUTEX_LOCK(&whitelist_mutex); + TURN_MUTEX_LOCK(&whitelist_mutex); #endif } -void ioa_unlock_whitelist(ioa_engine_handle e) -{ - UNUSED_ARG(e); +void ioa_unlock_whitelist(ioa_engine_handle e) { + UNUSED_ARG(e); #if !defined(TURN_NO_RWLOCK) - pthread_rwlock_unlock(whitelist_rwlock); + pthread_rwlock_unlock(whitelist_rwlock); #else - TURN_MUTEX_UNLOCK(&whitelist_mutex); + TURN_MUTEX_UNLOCK(&whitelist_mutex); #endif } -static void ioa_wrlock_whitelist(ioa_engine_handle e) -{ - UNUSED_ARG(e); +static void ioa_wrlock_whitelist(ioa_engine_handle e) { + UNUSED_ARG(e); #if !defined(TURN_NO_RWLOCK) - pthread_rwlock_wrlock(whitelist_rwlock); + pthread_rwlock_wrlock(whitelist_rwlock); #else - TURN_MUTEX_LOCK(&whitelist_mutex); + TURN_MUTEX_LOCK(&whitelist_mutex); #endif } -const ip_range_list_t* ioa_get_whitelist(ioa_engine_handle e) -{ - UNUSED_ARG(e); - return ipwhitelist; +const ip_range_list_t *ioa_get_whitelist(ioa_engine_handle e) { + UNUSED_ARG(e); + return ipwhitelist; } -void ioa_lock_blacklist(ioa_engine_handle e) -{ - UNUSED_ARG(e); +void ioa_lock_blacklist(ioa_engine_handle e) { + UNUSED_ARG(e); #if !defined(TURN_NO_RWLOCK) - pthread_rwlock_rdlock(blacklist_rwlock); + pthread_rwlock_rdlock(blacklist_rwlock); #else - TURN_MUTEX_LOCK(&blacklist_mutex); + TURN_MUTEX_LOCK(&blacklist_mutex); #endif } -void ioa_unlock_blacklist(ioa_engine_handle e) -{ - UNUSED_ARG(e); +void ioa_unlock_blacklist(ioa_engine_handle e) { + UNUSED_ARG(e); #if !defined(TURN_NO_RWLOCK) - pthread_rwlock_unlock(blacklist_rwlock); + pthread_rwlock_unlock(blacklist_rwlock); #else - TURN_MUTEX_UNLOCK(&blacklist_mutex); + TURN_MUTEX_UNLOCK(&blacklist_mutex); #endif } -static void ioa_wrlock_blacklist(ioa_engine_handle e) -{ - UNUSED_ARG(e); +static void ioa_wrlock_blacklist(ioa_engine_handle e) { + UNUSED_ARG(e); #if !defined(TURN_NO_RWLOCK) - pthread_rwlock_wrlock(blacklist_rwlock); + pthread_rwlock_wrlock(blacklist_rwlock); #else - TURN_MUTEX_LOCK(&blacklist_mutex); + TURN_MUTEX_LOCK(&blacklist_mutex); #endif } -const ip_range_list_t* ioa_get_blacklist(ioa_engine_handle e) -{ - UNUSED_ARG(e); - return ipblacklist; +const ip_range_list_t *ioa_get_blacklist(ioa_engine_handle e) { + UNUSED_ARG(e); + return ipblacklist; } -ip_range_list_t* get_ip_list(const char *kind) -{ - ip_range_list_t *ret = (ip_range_list_t*) calloc(sizeof(ip_range_list_t), 1); +ip_range_list_t *get_ip_list(const char *kind) { + ip_range_list_t *ret = (ip_range_list_t *)calloc(sizeof(ip_range_list_t), 1); - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->get_ip_list && !turn_params.no_dynamic_ip_list) { - (*dbd->get_ip_list)(kind, ret); - } + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->get_ip_list && !turn_params.no_dynamic_ip_list) { + (*dbd->get_ip_list)(kind, ret); + } - return ret; + return ret; } -void ip_list_free(ip_range_list_t *l) -{ - if(l) { - if(l->rs) - free(l->rs); - free(l); - } +void ip_list_free(ip_range_list_t *l) { + if (l) { + if (l->rs) + free(l->rs); + free(l); + } } -void update_white_and_black_lists(void) -{ - { - ip_range_list_t *wl = get_ip_list("allowed"); - ip_range_list_t *owl = NULL; - ioa_wrlock_whitelist(NULL); - owl = ipwhitelist; - ipwhitelist = wl; - ioa_unlock_whitelist(NULL); - ip_list_free(owl); - } - { - ip_range_list_t *bl = get_ip_list("denied"); - ip_range_list_t *obl = NULL; - ioa_wrlock_blacklist(NULL); - obl = ipblacklist; - ipblacklist = bl; - ioa_unlock_blacklist(NULL); - ip_list_free(obl); - } +void update_white_and_black_lists(void) { + { + ip_range_list_t *wl = get_ip_list("allowed"); + ip_range_list_t *owl = NULL; + ioa_wrlock_whitelist(NULL); + owl = ipwhitelist; + ipwhitelist = wl; + ioa_unlock_whitelist(NULL); + ip_list_free(owl); + } + { + ip_range_list_t *bl = get_ip_list("denied"); + ip_range_list_t *obl = NULL; + ioa_wrlock_blacklist(NULL); + obl = ipblacklist; + ipblacklist = bl; + ioa_unlock_blacklist(NULL); + ip_list_free(obl); + } } /////////////// add ACL record /////////////////// -int add_ip_list_range(const char * range0, const char * realm, ip_range_list_t * list) -{ - char *range = strdup(range0); +int add_ip_list_range(const char *range0, const char *realm, ip_range_list_t *list) { + char *range = strdup(range0); - char* separator = strchr(range, '-'); + char *separator = strchr(range, '-'); - if (separator) { - *separator = '\0'; - } + if (separator) { + *separator = '\0'; + } - ioa_addr min, max; + ioa_addr min, max; - if (make_ioa_addr((const uint8_t*) range, 0, &min) < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong address format: %s\n", range); - free(range); - return -1; - } + if (make_ioa_addr((const uint8_t *)range, 0, &min) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong address format: %s\n", range); + free(range); + return -1; + } - if (separator) { - if (make_ioa_addr((const uint8_t*) separator + 1, 0, &max) < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong address format: %s\n", separator + 1); - free(range); - return -1; - } - } else { - // Doesn't have a '-' character in it, so assume that this is a single address - addr_cpy(&max, &min); - } + if (separator) { + if (make_ioa_addr((const uint8_t *)separator + 1, 0, &max) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong address format: %s\n", separator + 1); + free(range); + return -1; + } + } else { + // Doesn't have a '-' character in it, so assume that this is a single address + addr_cpy(&max, &min); + } - if (separator) - *separator = '-'; + if (separator) + *separator = '-'; - ++(list->ranges_number); - list->rs = (ip_range_t*) realloc(list->rs, sizeof(ip_range_t) * list->ranges_number); - STRCPY(list->rs[list->ranges_number - 1].str,range); - if(realm) - STRCPY(list->rs[list->ranges_number - 1].realm,realm); - else - list->rs[list->ranges_number - 1].realm[0]=0; - free(range); - ioa_addr_range_set(&(list->rs[list->ranges_number - 1].enc), &min, &max); + ++(list->ranges_number); + list->rs = (ip_range_t *)realloc(list->rs, sizeof(ip_range_t) * list->ranges_number); + STRCPY(list->rs[list->ranges_number - 1].str, range); + if (realm) + STRCPY(list->rs[list->ranges_number - 1].realm, realm); + else + list->rs[list->ranges_number - 1].realm[0] = 0; + free(range); + ioa_addr_range_set(&(list->rs[list->ranges_number - 1].enc), &min, &max); - return 0; + return 0; } -int check_ip_list_range(const char * range0) -{ - char *range = strdup(range0); +int check_ip_list_range(const char *range0) { + char *range = strdup(range0); - char* separator = strchr(range, '-'); + char *separator = strchr(range, '-'); - if (separator) { - *separator = '\0'; - } + if (separator) { + *separator = '\0'; + } - ioa_addr min, max; + ioa_addr min, max; - if (make_ioa_addr((const uint8_t*) range, 0, &min) < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong address range format: %s\n", range); - free(range); - return -1; - } + if (make_ioa_addr((const uint8_t *)range, 0, &min) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong address range format: %s\n", range); + free(range); + return -1; + } - if (separator) { - if (make_ioa_addr((const uint8_t*) separator + 1, 0, &max) < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong address range format: %s\n", separator + 1); - free(range); - return -1; - } - } else { - // Doesn't have a '-' character in it, so assume that this is a single address - addr_cpy(&max, &min); - } + if (separator) { + if (make_ioa_addr((const uint8_t *)separator + 1, 0, &max) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong address range format: %s\n", separator + 1); + free(range); + return -1; + } + } else { + // Doesn't have a '-' character in it, so assume that this is a single address + addr_cpy(&max, &min); + } - if (separator) - *separator = '-'; + if (separator) + *separator = '-'; - free(range); + free(range); - return 0; + return 0; } /////////// REALM ////////////// -void reread_realms(void) -{ - { - realm_params_t* defrp = get_realm(NULL); - lock_realms(); - defrp->options.perf_options.max_bps = turn_params.max_bps; - defrp->options.perf_options.total_quota = turn_params.total_quota; - defrp->options.perf_options.user_quota = turn_params.user_quota; - unlock_realms(); - } +void reread_realms(void) { + { + realm_params_t *defrp = get_realm(NULL); + lock_realms(); + defrp->options.perf_options.max_bps = turn_params.max_bps; + defrp->options.perf_options.total_quota = turn_params.total_quota; + defrp->options.perf_options.user_quota = turn_params.user_quota; + unlock_realms(); + } - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->reread_realms && !turn_params.no_dynamic_realms) { - (*dbd->reread_realms)(&realms_list); - } + const turn_dbdriver_t *dbd = get_dbdriver(); + if (dbd && dbd->reread_realms && !turn_params.no_dynamic_realms) { + (*dbd->reread_realms)(&realms_list); + } } /////////////////////////////// diff --git a/src/apps/relay/userdb.h b/src/apps/relay/userdb.h index 95980d1..b770da6 100644 --- a/src/apps/relay/userdb.h +++ b/src/apps/relay/userdb.h @@ -31,14 +31,14 @@ #ifndef __USERDB__ #define __USERDB__ -#include #include +#include #include "hiredis_libevent2.h" -#include "ns_turn_utils.h" #include "ns_turn_maps.h" #include "ns_turn_server.h" +#include "ns_turn_utils.h" #include "apputils.h" @@ -56,78 +56,80 @@ typedef struct _realm_params_t realm_params_t; struct _realm_status_t { - vint total_current_allocs; - ur_string_map *alloc_counters; - + vint total_current_allocs; + ur_string_map *alloc_counters; }; struct _realm_params_t { - int is_default_realm; + int is_default_realm; - realm_options_t options; - - realm_status_t status; + realm_options_t options; + realm_status_t status; }; void lock_realms(void); void unlock_realms(void); -void update_o_to_realm(ur_string_map * o_to_realm_new); +void update_o_to_realm(ur_string_map *o_to_realm_new); //////////// USER DB ////////////////////////////// struct auth_message { - turnserver_id id; - turn_credential_type ct; - int in_oauth; - int out_oauth; - int max_session_time; - uint8_t username[STUN_MAX_USERNAME_SIZE + 1]; - uint8_t realm[STUN_MAX_REALM_SIZE + 1]; - hmackey_t key; - password_t pwd; - get_username_resume_cb resume_func; - ioa_net_data in_buffer; - uint64_t ctxkey; - int success; + turnserver_id id; + turn_credential_type ct; + int in_oauth; + int out_oauth; + int max_session_time; + uint8_t username[STUN_MAX_USERNAME_SIZE + 1]; + uint8_t realm[STUN_MAX_REALM_SIZE + 1]; + hmackey_t key; + password_t pwd; + get_username_resume_cb resume_func; + ioa_net_data in_buffer; + uint64_t ctxkey; + int success; }; enum _TURN_USERDB_TYPE { #if !defined(TURN_NO_SQLITE) - TURN_USERDB_TYPE_UNKNOWN=-1, - TURN_USERDB_TYPE_SQLITE=0 + TURN_USERDB_TYPE_UNKNOWN = -1, + TURN_USERDB_TYPE_SQLITE = 0 #else - TURN_USERDB_TYPE_UNKNOWN=0 + TURN_USERDB_TYPE_UNKNOWN = 0 #endif #if !defined(TURN_NO_PQ) - ,TURN_USERDB_TYPE_PQ + , + TURN_USERDB_TYPE_PQ #endif #if !defined(TURN_NO_MYSQL) - ,TURN_USERDB_TYPE_MYSQL + , + TURN_USERDB_TYPE_MYSQL #endif #if !defined(TURN_NO_MONGO) - ,TURN_USERDB_TYPE_MONGO + , + TURN_USERDB_TYPE_MONGO #endif - ,TURN_USERDB_TYPE_REDIS + , + TURN_USERDB_TYPE_REDIS }; typedef enum _TURN_USERDB_TYPE TURN_USERDB_TYPE; enum _TURNADMIN_COMMAND_TYPE { - TA_COMMAND_UNKNOWN, - TA_PRINT_KEY, - TA_UPDATE_USER, - TA_DELETE_USER, - TA_LIST_USERS, - TA_SET_SECRET, - TA_SHOW_SECRET, - TA_DEL_SECRET, - TA_ADD_ORIGIN, - TA_DEL_ORIGIN, - TA_LIST_ORIGINS, - TA_SET_REALM_OPTION, - TA_LIST_REALM_OPTIONS + TA_COMMAND_UNKNOWN, + TA_PRINT_KEY, + TA_UPDATE_USER, + TA_DELETE_USER, + TA_LIST_USERS, + TA_SET_SECRET, + TA_SHOW_SECRET, + TA_DEL_SECRET, + TA_ADD_ORIGIN, + TA_DEL_ORIGIN, + TA_LIST_ORIGINS, + TA_SET_REALM_OPTION, + TA_LIST_REALM_OPTIONS }; typedef enum _TURNADMIN_COMMAND_TYPE TURNADMIN_COMMAND_TYPE; @@ -135,8 +137,8 @@ typedef enum _TURNADMIN_COMMAND_TYPE TURNADMIN_COMMAND_TYPE; /////////// SHARED SECRETS ////////////////// struct _secrets_list { - char **secrets; - size_t sz; + char **secrets; + size_t sz; }; typedef struct _secrets_list secrets_list_t; @@ -145,34 +147,33 @@ typedef struct _secrets_list secrets_list_t; #define TURN_LONG_STRING_SIZE (1025) typedef struct _redis_stats_db_t { - char connection_string[TURN_LONG_STRING_SIZE]; - char connection_string_sanitized[TURN_LONG_STRING_SIZE]; + char connection_string[TURN_LONG_STRING_SIZE]; + char connection_string_sanitized[TURN_LONG_STRING_SIZE]; } redis_stats_db_t; typedef struct _ram_users_db_t { - size_t users_number; - ur_string_map *static_accounts; - secrets_list_t static_auth_secrets; + size_t users_number; + ur_string_map *static_accounts; + secrets_list_t static_auth_secrets; } ram_users_db_t; typedef struct _persistent_users_db_t { - char userdb[TURN_LONG_STRING_SIZE]; - char userdb_sanitized[TURN_LONG_STRING_SIZE]; + char userdb[TURN_LONG_STRING_SIZE]; + char userdb_sanitized[TURN_LONG_STRING_SIZE]; } persistent_users_db_t; -typedef struct _default_users_db_t -{ - TURN_USERDB_TYPE userdb_type; +typedef struct _default_users_db_t { + TURN_USERDB_TYPE userdb_type; - persistent_users_db_t persistent_users_db; + persistent_users_db_t persistent_users_db; - ram_users_db_t ram_db; + ram_users_db_t ram_db; } default_users_db_t; ///////////////////////////////////////////// -realm_params_t* get_realm(char* name); +realm_params_t *get_realm(char *name); void set_default_realm_name(char *realm); int change_total_quota(char *realm, int value); int change_user_quota(char *realm, int value); @@ -184,36 +185,41 @@ void init_dynamic_ip_lists(void); void update_white_and_black_lists(void); void clean_secrets_list(secrets_list_t *sl); size_t get_secrets_list_size(secrets_list_t *sl); -const char* get_secrets_list_elem(secrets_list_t *sl, size_t i); -void add_to_secrets_list(secrets_list_t *sl, const char* elem); +const char *get_secrets_list_elem(secrets_list_t *sl, size_t i); +void add_to_secrets_list(secrets_list_t *sl, const char *elem); /////////// USER DB CHECK ////////////////// -int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, uint8_t *uname, uint8_t *realm, hmackey_t key, ioa_network_buffer_handle nbh); -uint8_t *start_user_check(turnserver_id id, turn_credential_type ct, int in_oauth, int *out_oauth, uint8_t *uname, uint8_t *realm, get_username_resume_cb resume, ioa_net_data *in_buffer, uint64_t ctxkey, int *postpone_reply); +int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, uint8_t *uname, uint8_t *realm, hmackey_t key, + ioa_network_buffer_handle nbh); +uint8_t *start_user_check(turnserver_id id, turn_credential_type ct, int in_oauth, int *out_oauth, uint8_t *uname, + uint8_t *realm, get_username_resume_cb resume, ioa_net_data *in_buffer, uint64_t ctxkey, + int *postpone_reply); int check_new_allocation_quota(uint8_t *username, int oauth, uint8_t *realm); void release_allocation_quota(uint8_t *username, int oauth, uint8_t *realm); /////////// Handle user DB ///////////////// #if defined(DB_TEST) - void run_db_test(void); +void run_db_test(void); #endif void auth_ping(redis_context_handle rch); void reread_realms(void); int add_static_user_account(char *user); -int adminuser(uint8_t *user, uint8_t *realm, uint8_t *pwd, uint8_t *secret, uint8_t *origin, TURNADMIN_COMMAND_TYPE ct, perf_options_t* po, int is_admin); +int adminuser(uint8_t *user, uint8_t *realm, uint8_t *pwd, uint8_t *secret, uint8_t *origin, TURNADMIN_COMMAND_TYPE ct, + perf_options_t *po, int is_admin); -int add_ip_list_range(const char* range, const char* realm, ip_range_list_t * list); -int check_ip_list_range(const char* range); -ip_range_list_t* get_ip_list(const char *kind); +int add_ip_list_range(const char *range, const char *realm, ip_range_list_t *list); +int check_ip_list_range(const char *range); +ip_range_list_t *get_ip_list(const char *kind); void ip_list_free(ip_range_list_t *l); ///////////// Redis ////////////////////// #if !defined(TURN_NO_HIREDIS) -redis_context_handle get_redis_async_connection(struct event_base *base, redis_stats_db_t* redis_stats_db, int delete_keys); +redis_context_handle get_redis_async_connection(struct event_base *base, redis_stats_db_t *redis_stats_db, + int delete_keys); #endif //////////////////////////////////////////// @@ -224,4 +230,3 @@ redis_context_handle get_redis_async_connection(struct event_base *base, redis_s #endif /// __USERDB__/// - diff --git a/src/apps/rfc5769/rfc5769check.c b/src/apps/rfc5769/rfc5769check.c index bb6da3f..d8ec7ed 100644 --- a/src/apps/rfc5769/rfc5769check.c +++ b/src/apps/rfc5769/rfc5769check.c @@ -28,8 +28,8 @@ * SUCH DAMAGE. */ -#include #include +#include #include #include @@ -39,540 +39,527 @@ #include #endif -#include "ns_turn_utils.h" #include "apputils.h" +#include "ns_turn_utils.h" #include "stun_buffer.h" //////////// OAUTH ////////////////// -static const char* encs[]={ +static const char *encs[] = { #if !defined(TURN_NO_GCM) - "A128GCM", "A256GCM", + "A128GCM", "A256GCM", #endif - NULL}; + NULL}; static int print_extra = 0; -void print_field5769(const char* name, const void* f0, size_t len); -void print_field5769(const char* name, const void* f0, size_t len) { - const unsigned char* f = (const unsigned char*)f0; - printf("\nfield %s %lu==>>\n",name,(unsigned long)len); +void print_field5769(const char *name, const void *f0, size_t len); +void print_field5769(const char *name, const void *f0, size_t len) { + const unsigned char *f = (const unsigned char *)f0; + printf("\nfield %s %lu==>>\n", name, (unsigned long)len); size_t i; - for(i = 0;i1) - print_extra = 1; + if (argc > 1) + print_extra = 1; - set_logfile("stdout"); - set_no_stdout_log(1); - set_system_parameters(0); + set_logfile("stdout"); + set_no_stdout_log(1); + set_system_parameters(0); - { - const unsigned char reqstc[] = - "\x00\x01\x00\x58" - "\x21\x12\xa4\x42" - "\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" - "\x80\x22\x00\x10" - "STUN test client" - "\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" - "\x9a\xea\xa7\x0c\xbf\xd8\xcb\x56\x78\x1e\xf2\xb5" - "\xb2\xd3\xf2\x49\xc1\xb5\x71\xa2" - "\x80\x28\x00\x04" - "\xe5\x7a\x3b\xcf"; + { + const unsigned char reqstc[] = "\x00\x01\x00\x58" + "\x21\x12\xa4\x42" + "\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" + "\x80\x22\x00\x10" + "STUN test client" + "\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" + "\x9a\xea\xa7\x0c\xbf\xd8\xcb\x56\x78\x1e\xf2\xb5" + "\xb2\xd3\xf2\x49\xc1\xb5\x71\xa2" + "\x80\x28\x00\x04" + "\xe5\x7a\x3b\xcf"; - uint8_t buf[sizeof(reqstc)]; - memcpy(buf, reqstc, sizeof(reqstc)); + uint8_t buf[sizeof(reqstc)]; + memcpy(buf, reqstc, sizeof(reqstc)); - {//fingerprintfs etc + { // fingerprintfs etc - res = stun_is_command_message_full_check_str(buf, sizeof(reqstc) - 1, 1, NULL); - printf("RFC 5769 message fingerprint test(0) result: "); + res = stun_is_command_message_full_check_str(buf, sizeof(reqstc) - 1, 1, NULL); + printf("RFC 5769 message fingerprint test(0) result: "); - if (res) { - printf("success\n"); - } else if (res == 0) { - printf("failure on fingerprint(0) check\n"); - exit(-1); - } - } + if (res) { + printf("success\n"); + } else if (res == 0) { + printf("failure on fingerprint(0) check\n"); + exit(-1); + } + } - {//short-term credentials - uint8_t uname[33]; - uint8_t realm[33]; - uint8_t upwd[33]; - strcpy((char*) upwd, "VOkJxbRl1RmTxUk/WvJxBt"); + { // short-term credentials + uint8_t uname[33]; + uint8_t realm[33]; + uint8_t upwd[33]; + strcpy((char *)upwd, "VOkJxbRl1RmTxUk/WvJxBt"); - res = stun_check_message_integrity_str(TURN_CREDENTIALS_SHORT_TERM, buf, sizeof(reqstc) - 1, uname, realm, upwd, shatype); - printf("RFC 5769 simple request short-term credentials and integrity test result: "); + res = stun_check_message_integrity_str(TURN_CREDENTIALS_SHORT_TERM, buf, sizeof(reqstc) - 1, uname, realm, upwd, + shatype); + printf("RFC 5769 simple request short-term credentials and integrity test result: "); - if (res > 0) { - printf("success\n"); - } else if (res == 0) { - printf("failure on integrity check\n"); - exit(-1); - } else { - printf("failure on message structure check\n"); - exit(-1); - } - } + if (res > 0) { + printf("success\n"); + } else if (res == 0) { + printf("failure on integrity check\n"); + exit(-1); + } else { + printf("failure on message structure check\n"); + exit(-1); + } + } - {//negative fingerprint - buf[27] = 23; + { // negative fingerprint + buf[27] = 23; - res = stun_is_command_message_full_check_str(buf, sizeof(reqstc) - 1, 1, NULL); - printf("RFC 5769 NEGATIVE fingerprint test(0) result: "); + res = stun_is_command_message_full_check_str(buf, sizeof(reqstc) - 1, 1, NULL); + printf("RFC 5769 NEGATIVE fingerprint test(0) result: "); - if (!res) { - printf("success\n"); - } else if (res == 0) { - printf("failure on NEGATIVE fingerprint check\n"); - exit(-1); - } - } - } + if (!res) { + printf("success\n"); + } else if (res == 0) { + printf("failure on NEGATIVE fingerprint check\n"); + exit(-1); + } + } + } - { - const unsigned char reqltc[] = "\x00\x01\x00\x60" - "\x21\x12\xa4\x42" - "\x78\xad\x34\x33\xc6\xad\x72\xc0\x29\xda\x41\x2e" - "\x00\x06\x00\x12" - "\xe3\x83\x9e\xe3\x83\x88\xe3\x83\xaa\xe3\x83\x83" - "\xe3\x82\xaf\xe3\x82\xb9\x00\x00" - "\x00\x15\x00\x1c" - "\x66\x2f\x2f\x34\x39\x39\x6b\x39\x35\x34\x64\x36" - "\x4f\x4c\x33\x34\x6f\x4c\x39\x46\x53\x54\x76\x79" - "\x36\x34\x73\x41" - "\x00\x14\x00\x0b" - "\x65\x78\x61\x6d\x70\x6c\x65\x2e\x6f\x72\x67\x00" - "\x00\x08\x00\x14" - "\xf6\x70\x24\x65\x6d\xd6\x4a\x3e\x02\xb8\xe0\x71" - "\x2e\x85\xc9\xa2\x8c\xa8\x96\x66"; + { + const unsigned char reqltc[] = "\x00\x01\x00\x60" + "\x21\x12\xa4\x42" + "\x78\xad\x34\x33\xc6\xad\x72\xc0\x29\xda\x41\x2e" + "\x00\x06\x00\x12" + "\xe3\x83\x9e\xe3\x83\x88\xe3\x83\xaa\xe3\x83\x83" + "\xe3\x82\xaf\xe3\x82\xb9\x00\x00" + "\x00\x15\x00\x1c" + "\x66\x2f\x2f\x34\x39\x39\x6b\x39\x35\x34\x64\x36" + "\x4f\x4c\x33\x34\x6f\x4c\x39\x46\x53\x54\x76\x79" + "\x36\x34\x73\x41" + "\x00\x14\x00\x0b" + "\x65\x78\x61\x6d\x70\x6c\x65\x2e\x6f\x72\x67\x00" + "\x00\x08\x00\x14" + "\xf6\x70\x24\x65\x6d\xd6\x4a\x3e\x02\xb8\xe0\x71" + "\x2e\x85\xc9\xa2\x8c\xa8\x96\x66"; - uint8_t user[] = "\xe3\x83\x9e\xe3\x83\x88\xe3\x83\xaa\xe3\x83\x83" - "\xe3\x82\xaf\xe3\x82\xb9"; + uint8_t user[] = "\xe3\x83\x9e\xe3\x83\x88\xe3\x83\xaa\xe3\x83\x83" + "\xe3\x82\xaf\xe3\x82\xb9"; - uint8_t realm[33]; - uint8_t nonce[29]; - uint8_t upwd[33]; + uint8_t realm[33]; + uint8_t nonce[29]; + uint8_t upwd[33]; - uint8_t buf[sizeof(reqltc)]; - memcpy(buf, reqltc, sizeof(reqltc)); + uint8_t buf[sizeof(reqltc)]; + memcpy(buf, reqltc, sizeof(reqltc)); - uint8_t uname[sizeof(user)]; - memcpy(uname, user, sizeof(user)); + uint8_t uname[sizeof(user)]; + memcpy(uname, user, sizeof(user)); - strcpy((char*) realm, "example.org"); - strcpy((char*) upwd, "TheMatrIX"); - strcpy((char*)nonce,"f//499k954d6OL34oL9FSTvy64sA"); + strcpy((char *)realm, "example.org"); + strcpy((char *)upwd, "TheMatrIX"); + strcpy((char *)nonce, "f//499k954d6OL34oL9FSTvy64sA"); - res = stun_check_message_integrity_str(TURN_CREDENTIALS_LONG_TERM, buf, sizeof(reqltc) - 1, uname, realm, - upwd, shatype); + res = stun_check_message_integrity_str(TURN_CREDENTIALS_LONG_TERM, buf, sizeof(reqltc) - 1, uname, realm, upwd, + shatype); - printf("RFC 5769 message structure, long-term credentials and integrity test result: "); + printf("RFC 5769 message structure, long-term credentials and integrity test result: "); - if (res > 0) { - printf("success\n"); - } else if (res == 0) { - printf("failure on integrity check\n"); - exit(-1); - } else { - printf("failure on message structure check\n"); - exit(-1); - } + if (res > 0) { + printf("success\n"); + } else if (res == 0) { + printf("failure on integrity check\n"); + exit(-1); + } else { + printf("failure on message structure check\n"); + exit(-1); + } - { //encoding test - printf("RFC 5769 message encoding test result: "); - size_t len = 0; - uint16_t message_type = STUN_METHOD_BINDING; - stun_tid tid; - uint16_t *buf16 = (uint16_t*)buf; - uint32_t *buf32 = (uint32_t*)buf; - memcpy(tid.tsx_id,"\x78\xad\x34\x33\xc6\xad\x72\xc0\x29\xda\x41\x2e",12); - stun_init_buffer_str(buf,&len); - message_type &= (uint16_t)(0x3FFF); - buf16[0]=nswap16(message_type); - buf16[1]=0; - buf32[1]=nswap32(STUN_MAGIC_COOKIE); - stun_tid_message_cpy(buf, &tid); - stun_attr_add_integrity_by_user_str(buf, &len, uname, realm, upwd, nonce, shatype); - if(len != (sizeof(reqltc)-1)) { - printf("failure: length %d, must be %d\n",(int)len,(int)(sizeof(reqltc)-1)); - exit(-1); - } - if(memcmp(buf,reqltc,len)) { - printf("failure: wrong message content\n"); - { - int lines = 29; - int line = 0; - int col = 0; - int cols = 4; - for(line = 0;line 0) { - printf("success\n"); - } else if (res == 0) { - printf("failure on integrity check\n"); - exit(-1); - } else { - printf("failure on message structure check\n"); - exit(-1); - } - } + if (res > 0) { + printf("success\n"); + } else if (res == 0) { + printf("failure on integrity check\n"); + exit(-1); + } else { + printf("failure on message structure check\n"); + exit(-1); + } + } - {//negative fingerprint - buf[27] = 23; + { // negative fingerprint + buf[27] = 23; - res = stun_is_command_message_full_check_str(buf, sizeof(respv4) - 1, 1, NULL); - printf("RFC 5769 NEGATIVE fingerprint test(1) result: "); + res = stun_is_command_message_full_check_str(buf, sizeof(respv4) - 1, 1, NULL); + printf("RFC 5769 NEGATIVE fingerprint test(1) result: "); - if (!res) { - printf("success\n"); - } else if (res == 0) { - printf("failure on NEGATIVE fingerprint check\n"); - exit(-1); - } - } + if (!res) { + printf("success\n"); + } else if (res == 0) { + printf("failure on NEGATIVE fingerprint check\n"); + exit(-1); + } + } - {//IPv4 addr - ioa_addr addr4; - ioa_addr addr4_test; + { // IPv4 addr + ioa_addr addr4; + ioa_addr addr4_test; - printf("RFC 5769 IPv4 encoding result: "); + printf("RFC 5769 IPv4 encoding result: "); - res = stun_attr_get_first_addr_str(buf, sizeof(respv4)-1, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &addr4, NULL); - if(res < 0) { - printf("failure on message structure check\n"); - exit(-1); - } + res = stun_attr_get_first_addr_str(buf, sizeof(respv4) - 1, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &addr4, NULL); + if (res < 0) { + printf("failure on message structure check\n"); + exit(-1); + } - make_ioa_addr((const uint8_t*)"192.0.2.1", 32853, &addr4_test); - if(addr_eq(&addr4,&addr4_test)) { - printf("success\n"); - } else { - printf("failure on IPv4 deconding check\n"); - exit(-1); - } - } - } + make_ioa_addr((const uint8_t *)"192.0.2.1", 32853, &addr4_test); + if (addr_eq(&addr4, &addr4_test)) { + printf("success\n"); + } else { + printf("failure on IPv4 deconding check\n"); + exit(-1); + } + } + } - { - const unsigned char respv6[] = "\x01\x01\x00\x48" - "\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\x14" - "\x00\x02\xa1\x47" - "\x01\x13\xa9\xfa\xa5\xd3\xf1\x79" - "\xbc\x25\xf4\xb5\xbe\xd2\xb9\xd9" - "\x00\x08\x00\x14" - "\xa3\x82\x95\x4e\x4b\xe6\x7b\xf1\x17\x84\xc9\x7c" - "\x82\x92\xc2\x75\xbf\xe3\xed\x41" - "\x80\x28\x00\x04" - "\xc8\xfb\x0b\x4c"; + { + const unsigned char respv6[] = "\x01\x01\x00\x48" + "\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\x14" + "\x00\x02\xa1\x47" + "\x01\x13\xa9\xfa\xa5\xd3\xf1\x79" + "\xbc\x25\xf4\xb5\xbe\xd2\xb9\xd9" + "\x00\x08\x00\x14" + "\xa3\x82\x95\x4e\x4b\xe6\x7b\xf1\x17\x84\xc9\x7c" + "\x82\x92\xc2\x75\xbf\xe3\xed\x41" + "\x80\x28\x00\x04" + "\xc8\xfb\x0b\x4c"; - uint8_t buf[sizeof(respv6)]; + uint8_t buf[sizeof(respv6)]; - { //decoding test - memcpy(buf, respv6, sizeof(respv6)); + { // decoding test + memcpy(buf, respv6, sizeof(respv6)); - res = stun_is_command_message_full_check_str(buf, sizeof(respv6) - 1, 1, NULL); - printf("RFC 5769 message fingerprint test(2) result: "); + res = stun_is_command_message_full_check_str(buf, sizeof(respv6) - 1, 1, NULL); + printf("RFC 5769 message fingerprint test(2) result: "); - if (res) { - printf("success\n"); - } else if (res == 0) { - printf("failure on fingerprint(2) check\n"); - exit(-1); - } - } + if (res) { + printf("success\n"); + } else if (res == 0) { + printf("failure on fingerprint(2) check\n"); + exit(-1); + } + } - {//short-term credentials test - uint8_t uname[33]; - uint8_t realm[33]; - uint8_t upwd[33]; - strcpy((char*) upwd, "VOkJxbRl1RmTxUk/WvJxBt"); + { // short-term credentials test + uint8_t uname[33]; + uint8_t realm[33]; + uint8_t upwd[33]; + strcpy((char *)upwd, "VOkJxbRl1RmTxUk/WvJxBt"); - res = stun_check_message_integrity_str(TURN_CREDENTIALS_SHORT_TERM, buf, sizeof(respv6) - 1, uname, realm, upwd, shatype); - printf("RFC 5769 IPv6 response short-term credentials and integrity test result: "); + res = stun_check_message_integrity_str(TURN_CREDENTIALS_SHORT_TERM, buf, sizeof(respv6) - 1, uname, realm, upwd, + shatype); + printf("RFC 5769 IPv6 response short-term credentials and integrity test result: "); - if (res > 0) { - printf("success\n"); - } else if (res == 0) { - printf("failure on integrity check\n"); - exit(-1); - } else { - printf("failure on message structure check\n"); - exit(-1); - } - } + if (res > 0) { + printf("success\n"); + } else if (res == 0) { + printf("failure on integrity check\n"); + exit(-1); + } else { + printf("failure on message structure check\n"); + exit(-1); + } + } - {//negative decoding test - buf[27] = 23; + { // negative decoding test + buf[27] = 23; - res = stun_is_command_message_full_check_str(buf, sizeof(respv6) - 1, 1, NULL); - printf("RFC 5769 NEGATIVE fingerprint test(2) result: "); + res = stun_is_command_message_full_check_str(buf, sizeof(respv6) - 1, 1, NULL); + printf("RFC 5769 NEGATIVE fingerprint test(2) result: "); - if (!res) { - printf("success\n"); - } else if (res == 0) { - printf("failure on NEGATIVE fingerprint check\n"); - exit(-1); - } - } + if (!res) { + printf("success\n"); + } else if (res == 0) { + printf("failure on NEGATIVE fingerprint check\n"); + exit(-1); + } + } - {//IPv6 deconding test - ioa_addr addr6; - ioa_addr addr6_test; + { // IPv6 deconding test + ioa_addr addr6; + ioa_addr addr6_test; - printf("RFC 5769 IPv6 encoding result: "); + printf("RFC 5769 IPv6 encoding result: "); - res = stun_attr_get_first_addr_str(buf, sizeof(respv6) - 1, - STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &addr6, NULL); - if (res < 0) { - printf("failure on message structure check\n"); - exit(-1); - } + res = stun_attr_get_first_addr_str(buf, sizeof(respv6) - 1, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &addr6, NULL); + if (res < 0) { + printf("failure on message structure check\n"); + exit(-1); + } - make_ioa_addr((const uint8_t*) "2001:db8:1234:5678:11:2233:4455:6677", 32853, &addr6_test); - if (addr_eq(&addr6, &addr6_test)) { - printf("success\n"); - } else { - printf("failure on IPv6 deconding check\n"); - exit(-1); - } - } - } + make_ioa_addr((const uint8_t *)"2001:db8:1234:5678:11:2233:4455:6677", 32853, &addr6_test); + if (addr_eq(&addr6, &addr6_test)) { + printf("success\n"); + } else { + printf("failure on IPv6 deconding check\n"); + exit(-1); + } + } + } - { - if(check_oauth()<0) - exit(-1); - } + { + if (check_oauth() < 0) + exit(-1); + } - return 0; + return 0; } diff --git a/src/apps/stunclient/stunclient.c b/src/apps/stunclient/stunclient.c index ea39df9..cec877f 100644 --- a/src/apps/stunclient/stunclient.c +++ b/src/apps/stunclient/stunclient.c @@ -28,21 +28,21 @@ * SUCH DAMAGE. */ -#include #include +#include #include #include #if defined(_MSC_VER) - #include +#include #else - #include - #if !defined(WINDOWS) - #include - #endif +#include +#if !defined(WINDOWS) +#include +#endif #endif -#include "ns_turn_utils.h" #include "apputils.h" +#include "ns_turn_utils.h" #include "stun_buffer.h" #ifdef __cplusplus @@ -57,383 +57,380 @@ static int counter = 0; #ifdef __cplusplus -static int run_stunclient(const char* rip, int rport, int *port, int *rfc5780, int response_port, int change_ip, int change_port, int padding) -{ +static int run_stunclient(const char *rip, int rport, int *port, int *rfc5780, int response_port, int change_ip, + int change_port, int padding) { - ioa_addr remote_addr; - int new_udp_fd = -1; + ioa_addr remote_addr; + int new_udp_fd = -1; - memset((void *) &remote_addr, 0, sizeof(ioa_addr)); - if (make_ioa_addr((const uint8_t*) rip, rport, &remote_addr) < 0) - err(-1, NULL); + memset((void *)&remote_addr, 0, sizeof(ioa_addr)); + if (make_ioa_addr((const uint8_t *)rip, rport, &remote_addr) < 0) + err(-1, NULL); - if (udp_fd < 0) { - udp_fd = socket(remote_addr.ss.sa_family, SOCK_DGRAM, 0); - if (udp_fd < 0) - err(-1, NULL); + if (udp_fd < 0) { + udp_fd = socket(remote_addr.ss.sa_family, SOCK_DGRAM, 0); + if (udp_fd < 0) + err(-1, NULL); - if (!addr_any(&real_local_addr)) { - if (addr_bind(udp_fd, &real_local_addr,0,1,UDP_SOCKET) < 0) - err(-1, NULL); - } - } + if (!addr_any(&real_local_addr)) { + if (addr_bind(udp_fd, &real_local_addr, 0, 1, UDP_SOCKET) < 0) + err(-1, NULL); + } + } - if (response_port >= 0) { + if (response_port >= 0) { - new_udp_fd = socket(remote_addr.ss.sa_family, SOCK_DGRAM, 0); - if (new_udp_fd < 0) - err(-1, NULL); + new_udp_fd = socket(remote_addr.ss.sa_family, SOCK_DGRAM, 0); + if (new_udp_fd < 0) + err(-1, NULL); - addr_set_port(&real_local_addr, response_port); + addr_set_port(&real_local_addr, response_port); - if (addr_bind(new_udp_fd, &real_local_addr, 0, 1, UDP_SOCKET) < 0) - err(-1, NULL); - } + if (addr_bind(new_udp_fd, &real_local_addr, 0, 1, UDP_SOCKET) < 0) + err(-1, NULL); + } - turn::StunMsgRequest req(STUN_METHOD_BINDING); + turn::StunMsgRequest req(STUN_METHOD_BINDING); - req.constructBindingRequest(); + req.constructBindingRequest(); - if (response_port >= 0) { - turn::StunAttrResponsePort rpa; - rpa.setResponsePort((uint16_t)response_port); - try { - req.addAttr(rpa); - } catch(turn::WrongStunAttrFormatException &ex1) { - printf("Wrong rp attr format\n"); - exit(-1); - } catch(turn::WrongStunBufferFormatException &ex2) { - printf("Wrong stun buffer format (1)\n"); - exit(-1); - } catch(...) { - printf("Wrong something (1)\n"); - exit(-1); - } - } - if (change_ip || change_port) { - turn::StunAttrChangeRequest cra; - cra.setChangeIp(change_ip); - cra.setChangePort(change_port); - try { - req.addAttr(cra); - } catch(turn::WrongStunAttrFormatException &ex1) { - printf("Wrong cr attr format\n"); - exit(-1); - } catch(turn::WrongStunBufferFormatException &ex2) { - printf("Wrong stun buffer format (2)\n"); - exit(-1); - } catch(...) { - printf("Wrong something (2)\n"); - exit(-1); - } - } - if (padding) { - turn::StunAttrPadding pa; - pa.setPadding(1500); - try { - req.addAttr(pa); - } catch(turn::WrongStunAttrFormatException &ex1) { - printf("Wrong p attr format\n"); - exit(-1); - } catch(turn::WrongStunBufferFormatException &ex2) { - printf("Wrong stun buffer format (3)\n"); - exit(-1); - } catch(...) { - printf("Wrong something (3)\n"); - exit(-1); - } - } + if (response_port >= 0) { + turn::StunAttrResponsePort rpa; + rpa.setResponsePort((uint16_t)response_port); + try { + req.addAttr(rpa); + } catch (turn::WrongStunAttrFormatException &ex1) { + printf("Wrong rp attr format\n"); + exit(-1); + } catch (turn::WrongStunBufferFormatException &ex2) { + printf("Wrong stun buffer format (1)\n"); + exit(-1); + } catch (...) { + printf("Wrong something (1)\n"); + exit(-1); + } + } + if (change_ip || change_port) { + turn::StunAttrChangeRequest cra; + cra.setChangeIp(change_ip); + cra.setChangePort(change_port); + try { + req.addAttr(cra); + } catch (turn::WrongStunAttrFormatException &ex1) { + printf("Wrong cr attr format\n"); + exit(-1); + } catch (turn::WrongStunBufferFormatException &ex2) { + printf("Wrong stun buffer format (2)\n"); + exit(-1); + } catch (...) { + printf("Wrong something (2)\n"); + exit(-1); + } + } + if (padding) { + turn::StunAttrPadding pa; + pa.setPadding(1500); + try { + req.addAttr(pa); + } catch (turn::WrongStunAttrFormatException &ex1) { + printf("Wrong p attr format\n"); + exit(-1); + } catch (turn::WrongStunBufferFormatException &ex2) { + printf("Wrong stun buffer format (3)\n"); + exit(-1); + } catch (...) { + printf("Wrong something (3)\n"); + exit(-1); + } + } - { - int len = 0; - int slen = get_ioa_addr_len(&remote_addr); + { + int len = 0; + int slen = get_ioa_addr_len(&remote_addr); - do { - len = sendto(udp_fd, req.getRawBuffer(), req.getSize(), 0, (struct sockaddr*) &remote_addr, (socklen_t) slen); - } while (len < 0 && ((errno == EINTR) || (errno == ENOBUFS) || (errno == EAGAIN))); + do { + len = sendto(udp_fd, req.getRawBuffer(), req.getSize(), 0, (struct sockaddr *)&remote_addr, (socklen_t)slen); + } while (len < 0 && ((errno == EINTR) || (errno == ENOBUFS) || (errno == EAGAIN))); - if (len < 0) - err(-1, NULL); + if (len < 0) + err(-1, NULL); + } - } + if (addr_get_from_sock(udp_fd, &real_local_addr) < 0) { + printf("%s: Cannot get address from local socket\n", __FUNCTION__); + } else { + *port = addr_get_port(&real_local_addr); + } - if (addr_get_from_sock(udp_fd, &real_local_addr) < 0) { - printf("%s: Cannot get address from local socket\n", __FUNCTION__); - } else { - *port = addr_get_port(&real_local_addr); - } + { + if (new_udp_fd >= 0) { + close(udp_fd); + udp_fd = new_udp_fd; + new_udp_fd = -1; + } + } - { - if(new_udp_fd >= 0) { - close(udp_fd); - udp_fd = new_udp_fd; - new_udp_fd = -1; - } - } + { + int len = 0; + stun_buffer buf; + uint8_t *ptr = buf.buf; + int recvd = 0; + const int to_recv = sizeof(buf.buf); - { - int len = 0; - stun_buffer buf; - uint8_t *ptr = buf.buf; - int recvd = 0; - const int to_recv = sizeof(buf.buf); + do { + len = recv(udp_fd, ptr, to_recv - recvd, 0); + if (len > 0) { + recvd += len; + ptr += len; + break; + } + } while (len < 0 && (errno == EINTR)); - do { - len = recv(udp_fd, ptr, to_recv - recvd, 0); - if (len > 0) { - recvd += len; - ptr += len; - break; - } - } while (len < 0 && (errno == EINTR)); + if (recvd > 0) + len = recvd; + buf.len = len; - if (recvd > 0) - len = recvd; - buf.len = len; + try { + turn::StunMsgResponse res(buf.buf, sizeof(buf.buf), (size_t)buf.len, true); - try { - turn::StunMsgResponse res(buf.buf, sizeof(buf.buf), (size_t)buf.len, true); + if (res.isCommand()) { - if (res.isCommand()) { + if (res.isSuccess()) { - if(res.isSuccess()) { + if (res.isBindingResponse()) { - if (res.isBindingResponse()) { + ioa_addr reflexive_addr; + addr_set_any(&reflexive_addr); + turn::StunAttrIterator iter(res, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS); + if (!iter.eof()) { - ioa_addr reflexive_addr; - addr_set_any(&reflexive_addr); - turn::StunAttrIterator iter(res,STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS); - if (!iter.eof()) { + turn::StunAttrAddr addr(iter); + addr.getAddr(reflexive_addr); - turn::StunAttrAddr addr(iter); - addr.getAddr(reflexive_addr); + turn::StunAttrIterator iter1(res, STUN_ATTRIBUTE_OTHER_ADDRESS); + if (!iter1.eof()) { + *rfc5780 = 1; + printf("\n========================================\n"); + printf("RFC 5780 response %d\n", ++counter); + ioa_addr other_addr; + turn::StunAttrAddr addr1(iter1); + addr1.getAddr(other_addr); + turn::StunAttrIterator iter2(res, STUN_ATTRIBUTE_RESPONSE_ORIGIN); + if (!iter2.eof()) { + ioa_addr response_origin; + turn::StunAttrAddr addr2(iter2); + addr2.getAddr(response_origin); + addr_debug_print(1, &response_origin, "Response origin: "); + } + addr_debug_print(1, &other_addr, "Other addr: "); + } + addr_debug_print(1, &reflexive_addr, "UDP reflexive addr"); - turn::StunAttrIterator iter1(res,STUN_ATTRIBUTE_OTHER_ADDRESS); - if (!iter1.eof()) { - *rfc5780 = 1; - printf("\n========================================\n"); - printf("RFC 5780 response %d\n",++counter); - ioa_addr other_addr; - turn::StunAttrAddr addr1(iter1); - addr1.getAddr(other_addr); - turn::StunAttrIterator iter2(res,STUN_ATTRIBUTE_RESPONSE_ORIGIN); - if (!iter2.eof()) { - ioa_addr response_origin; - turn::StunAttrAddr addr2(iter2); - addr2.getAddr(response_origin); - addr_debug_print(1, &response_origin, "Response origin: "); - } - addr_debug_print(1, &other_addr, "Other addr: "); - } - addr_debug_print(1, &reflexive_addr, "UDP reflexive addr"); + } else { + printf("Cannot read the response\n"); + } + } else { + printf("Wrong type of response\n"); + } + } else { + int err_code = res.getError(); + std::string reason = res.getReason(); - } else { - printf("Cannot read the response\n"); - } - } else { - printf("Wrong type of response\n"); - } - } else { - int err_code = res.getError(); - std::string reason = res.getReason(); + printf("The response is an error %d (%s)\n", err_code, reason.c_str()); + } + } else { + printf("The response is not a response message\n"); + } + } catch (...) { + printf("The response is not a well formed STUN message\n"); + } + } - printf("The response is an error %d (%s)\n", err_code, reason.c_str()); - } - } else { - printf("The response is not a response message\n"); - } - } catch(...) { - printf("The response is not a well formed STUN message\n"); - } - } - - return 0; + return 0; } #else -static int run_stunclient(const char* rip, int rport, int *port, int *rfc5780, int response_port, int change_ip, int change_port, int padding) -{ +static int run_stunclient(const char *rip, int rport, int *port, int *rfc5780, int response_port, int change_ip, + int change_port, int padding) { - ioa_addr remote_addr; - int new_udp_fd = -1; - stun_buffer buf; + ioa_addr remote_addr; + int new_udp_fd = -1; + stun_buffer buf; - memset(&remote_addr, 0, sizeof(remote_addr)); - if (make_ioa_addr((const uint8_t*) rip, rport, &remote_addr) < 0) - err(-1, NULL); + memset(&remote_addr, 0, sizeof(remote_addr)); + if (make_ioa_addr((const uint8_t *)rip, rport, &remote_addr) < 0) + err(-1, NULL); - if (udp_fd < 0) { - udp_fd = socket(remote_addr.ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL); - if (udp_fd < 0) - err(-1, NULL); + if (udp_fd < 0) { + udp_fd = socket(remote_addr.ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL); + if (udp_fd < 0) + err(-1, NULL); - if (!addr_any(&real_local_addr)) { - if (addr_bind(udp_fd, &real_local_addr,0,1,UDP_SOCKET) < 0) - err(-1, NULL); - } - } + if (!addr_any(&real_local_addr)) { + if (addr_bind(udp_fd, &real_local_addr, 0, 1, UDP_SOCKET) < 0) + err(-1, NULL); + } + } - if (response_port >= 0) { + if (response_port >= 0) { - new_udp_fd = socket(remote_addr.ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL); - if (new_udp_fd < 0) - err(-1, NULL); + new_udp_fd = socket(remote_addr.ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL); + if (new_udp_fd < 0) + err(-1, NULL); - addr_set_port(&real_local_addr, response_port); + addr_set_port(&real_local_addr, response_port); - if (addr_bind(new_udp_fd, &real_local_addr,0,1,UDP_SOCKET) < 0) - err(-1, NULL); - } + if (addr_bind(new_udp_fd, &real_local_addr, 0, 1, UDP_SOCKET) < 0) + err(-1, NULL); + } - stun_prepare_binding_request(&buf); + stun_prepare_binding_request(&buf); - if (response_port >= 0) { - stun_attr_add_response_port_str((uint8_t*) (buf.buf), (size_t*) &(buf.len), (uint16_t) response_port); - } - if (change_ip || change_port) { - stun_attr_add_change_request_str((uint8_t*) buf.buf, (size_t*) &(buf.len), change_ip, change_port); - } - if (padding) { - if(stun_attr_add_padding_str((uint8_t*) buf.buf, (size_t*) &(buf.len), 1500)<0) { - printf("%s: ERROR: Cannot add padding\n",__FUNCTION__); - } - } + if (response_port >= 0) { + stun_attr_add_response_port_str((uint8_t *)(buf.buf), (size_t *)&(buf.len), (uint16_t)response_port); + } + if (change_ip || change_port) { + stun_attr_add_change_request_str((uint8_t *)buf.buf, (size_t *)&(buf.len), change_ip, change_port); + } + if (padding) { + if (stun_attr_add_padding_str((uint8_t *)buf.buf, (size_t *)&(buf.len), 1500) < 0) { + printf("%s: ERROR: Cannot add padding\n", __FUNCTION__); + } + } - { - int len = 0; - int slen = get_ioa_addr_len(&remote_addr); + { + int len = 0; + int slen = get_ioa_addr_len(&remote_addr); - do { - len = sendto(udp_fd, buf.buf, buf.len, 0, (struct sockaddr*) &remote_addr, (socklen_t) slen); - } while (len < 0 && ((errno == EINTR) || (errno == ENOBUFS) || (errno == EAGAIN))); + do { + len = sendto(udp_fd, buf.buf, buf.len, 0, (struct sockaddr *)&remote_addr, (socklen_t)slen); + } while (len < 0 && ((errno == EINTR) || (errno == ENOBUFS) || (errno == EAGAIN))); - if (len < 0) - err(-1, NULL); + if (len < 0) + err(-1, NULL); + } - } + if (addr_get_from_sock(udp_fd, &real_local_addr) < 0) { + printf("%s: Cannot get address from local socket\n", __FUNCTION__); + } else { + *port = addr_get_port(&real_local_addr); + } - if (addr_get_from_sock(udp_fd, &real_local_addr) < 0) { - printf("%s: Cannot get address from local socket\n", __FUNCTION__); - } else { - *port = addr_get_port(&real_local_addr); - } + { + if (new_udp_fd >= 0) { + socket_closesocket(udp_fd); + udp_fd = new_udp_fd; + new_udp_fd = -1; + } + } - { - if(new_udp_fd >= 0) { - socket_closesocket(udp_fd); - udp_fd = new_udp_fd; - new_udp_fd = -1; - } - } + { + int len = 0; + uint8_t *ptr = buf.buf; + int recvd = 0; + const int to_recv = sizeof(buf.buf); - { - int len = 0; - uint8_t *ptr = buf.buf; - int recvd = 0; - const int to_recv = sizeof(buf.buf); + do { + len = recv(udp_fd, ptr, to_recv - recvd, 0); + if (len > 0) { + recvd += len; + ptr += len; + break; + } + } while (len < 0 && ((errno == EINTR) || (errno == EAGAIN))); - do { - len = recv(udp_fd, ptr, to_recv - recvd, 0); - if (len > 0) { - recvd += len; - ptr += len; - break; - } - } while (len < 0 && ((errno == EINTR) || (errno == EAGAIN))); + if (recvd > 0) + len = recvd; + buf.len = len; - if (recvd > 0) - len = recvd; - buf.len = len; + if (stun_is_command_message(&buf)) { - if (stun_is_command_message(&buf)) { + if (stun_is_response(&buf)) { - if (stun_is_response(&buf)) { + if (stun_is_success_response(&buf)) { - if (stun_is_success_response(&buf)) { + if (stun_is_binding_response(&buf)) { - if (stun_is_binding_response(&buf)) { + ioa_addr reflexive_addr; + addr_set_any(&reflexive_addr); + if (stun_attr_get_first_addr(&buf, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &reflexive_addr, NULL) >= 0) { - ioa_addr reflexive_addr; - addr_set_any(&reflexive_addr); - if (stun_attr_get_first_addr(&buf, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &reflexive_addr, NULL) >= 0) { + stun_attr_ref sar = stun_attr_get_first_by_type_str(buf.buf, buf.len, STUN_ATTRIBUTE_OTHER_ADDRESS); + if (sar) { + *rfc5780 = 1; + printf("\n========================================\n"); + printf("RFC 5780 response %d\n", ++counter); + ioa_addr other_addr; + stun_attr_get_addr_str((uint8_t *)buf.buf, (size_t)buf.len, sar, &other_addr, NULL); + sar = stun_attr_get_first_by_type_str(buf.buf, buf.len, STUN_ATTRIBUTE_RESPONSE_ORIGIN); + if (sar) { + ioa_addr response_origin; + stun_attr_get_addr_str((uint8_t *)buf.buf, (size_t)buf.len, sar, &response_origin, NULL); + addr_debug_print(1, &response_origin, "Response origin: "); + } + addr_debug_print(1, &other_addr, "Other addr: "); + } + addr_debug_print(1, &reflexive_addr, "UDP reflexive addr"); - stun_attr_ref sar = stun_attr_get_first_by_type_str(buf.buf, buf.len, STUN_ATTRIBUTE_OTHER_ADDRESS); - if (sar) { - *rfc5780 = 1; - printf("\n========================================\n"); - printf("RFC 5780 response %d\n",++counter); - ioa_addr other_addr; - stun_attr_get_addr_str((uint8_t *) buf.buf, (size_t) buf.len, sar, &other_addr, NULL); - sar = stun_attr_get_first_by_type_str(buf.buf, buf.len, STUN_ATTRIBUTE_RESPONSE_ORIGIN); - if (sar) { - ioa_addr response_origin; - stun_attr_get_addr_str((uint8_t *) buf.buf, (size_t) buf.len, sar, &response_origin, NULL); - addr_debug_print(1, &response_origin, "Response origin: "); - } - addr_debug_print(1, &other_addr, "Other addr: "); - } - addr_debug_print(1, &reflexive_addr, "UDP reflexive addr"); + } else { + printf("Cannot read the response\n"); + } + } else { + printf("Wrong type of response\n"); + } + } else { + int err_code = 0; + uint8_t err_msg[1025] = "\0"; + size_t err_msg_size = sizeof(err_msg); + if (stun_is_error_response(&buf, &err_code, err_msg, err_msg_size)) { + printf("The response is an error %d (%s)\n", err_code, (char *)err_msg); + } else { + printf("The response is an unrecognized error\n"); + } + } + } else { + printf("The response is not a response message\n"); + } + } else { + printf("The response is not a STUN message\n"); + } + } - } else { - printf("Cannot read the response\n"); - } - } else { - printf("Wrong type of response\n"); - } - } else { - int err_code = 0; - uint8_t err_msg[1025] = "\0"; - size_t err_msg_size = sizeof(err_msg); - if (stun_is_error_response(&buf, &err_code, err_msg, err_msg_size)) { - printf("The response is an error %d (%s)\n", err_code, (char*) err_msg); - } else { - printf("The response is an unrecognized error\n"); - } - } - } else { - printf("The response is not a response message\n"); - } - } else { - printf("The response is not a STUN message\n"); - } - } - - return 0; + return 0; } #endif //////////////// local definitions ///////////////// -static char Usage[] = - "Usage: stunclient [options] address\n" - "Options:\n" - " -p STUN server port (Default: 3478)\n" - " -L Local address to use (optional)\n" - " -f Force RFC 5780 processing\n"; +static char Usage[] = "Usage: stunclient [options] address\n" + "Options:\n" + " -p STUN server port (Default: 3478)\n" + " -L Local address to use (optional)\n" + " -f Force RFC 5780 processing\n"; ////////////////////////////////////////////////// -int main(int argc, char **argv) -{ +int main(int argc, char **argv) { int port = DEFAULT_STUN_PORT; - char local_addr[256]="\0"; - int c=0; + char local_addr[256] = "\0"; + int c = 0; int forceRfc5780 = 0; - if (socket_init()) return -1; + if (socket_init()) + return -1; set_logfile("stdout"); set_no_stdout_log(1); set_system_parameters(0); - + memset(local_addr, 0, sizeof(local_addr)); while ((c = getopt(argc, argv, "p:L:f")) != -1) { - switch(c) { + switch (c) { case 'f': - forceRfc5780 = 1; - break; + forceRfc5780 = 1; + break; case 'p': port = atoi(optarg); break; @@ -441,32 +438,32 @@ int main(int argc, char **argv) STRCPY(local_addr, optarg); break; default: - fprintf(stderr,"%s\n", Usage); + fprintf(stderr, "%s\n", Usage); exit(1); } } - if(optind>=argc) { + if (optind >= argc) { fprintf(stderr, "%s\n", Usage); exit(-1); } addr_set_any(&real_local_addr); - if(local_addr[0]) { - if(make_ioa_addr((const uint8_t*)local_addr, 0, &real_local_addr)<0) { - err(-1,NULL); - } + if (local_addr[0]) { + if (make_ioa_addr((const uint8_t *)local_addr, 0, &real_local_addr) < 0) { + err(-1, NULL); + } } int local_port = -1; int rfc5780 = 0; - run_stunclient(argv[optind], port, &local_port, &rfc5780,-1,0,0,0); + run_stunclient(argv[optind], port, &local_port, &rfc5780, -1, 0, 0, 0); - if(rfc5780 || forceRfc5780) { - run_stunclient(argv[optind], port, &local_port, &rfc5780,local_port+1,1,1,0); - run_stunclient(argv[optind], port, &local_port, &rfc5780,-1,1,1,1); + if (rfc5780 || forceRfc5780) { + run_stunclient(argv[optind], port, &local_port, &rfc5780, local_port + 1, 1, 1, 0); + run_stunclient(argv[optind], port, &local_port, &rfc5780, -1, 1, 1, 1); } socket_closesocket(udp_fd); diff --git a/src/apps/uclient/mainuclient.c b/src/apps/uclient/mainuclient.c index cde78e5..d8bd1cc 100644 --- a/src/apps/uclient/mainuclient.c +++ b/src/apps/uclient/mainuclient.c @@ -29,13 +29,13 @@ */ #include "apputils.h" -#include "uclient.h" #include "ns_turn_utils.h" #include "session.h" #include "stun_buffer.h" +#include "uclient.h" -#include #include +#include #include #include @@ -47,28 +47,28 @@ /////////////// extern definitions ///////////////////// -int clmessage_length=100; -int do_not_use_channel=0; -int c2c=0; -int clnet_verbose=TURN_VERBOSE_NONE; -int use_tcp=0; -int use_sctp=0; -int use_secure=0; -int hang_on=0; +int clmessage_length = 100; +int do_not_use_channel = 0; +int c2c = 0; +int clnet_verbose = TURN_VERBOSE_NONE; +int use_tcp = 0; +int use_sctp = 0; +int use_secure = 0; +int hang_on = 0; ioa_addr peer_addr; int no_rtcp = 0; int default_address_family = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT; int dont_fragment = 0; -uint8_t g_uname[STUN_MAX_USERNAME_SIZE+1]; +uint8_t g_uname[STUN_MAX_USERNAME_SIZE + 1]; password_t g_upwd; -char g_auth_secret[1025]="\0"; +char g_auth_secret[1025] = "\0"; int g_use_auth_secret_with_timestamp = 0; int use_fingerprints = 1; -static char ca_cert_file[1025]=""; -static char cipher_suite[1025]=""; -char cert_file[1025]=""; -char pkey_file[1025]=""; +static char ca_cert_file[1025] = ""; +static char cipher_suite[1025] = ""; +char cert_file[1025] = ""; +char pkey_file[1025] = ""; SSL_CTX *root_tls_ctx[32]; int root_tls_ctx_num = 0; @@ -89,7 +89,7 @@ int no_permissions = 0; int extra_requests = 0; -char origin[STUN_MAX_ORIGIN_SIZE+1] = "\0"; +char origin[STUN_MAX_ORIGIN_SIZE + 1] = "\0"; band_limit_t bps = 0; @@ -99,502 +99,485 @@ int oauth = 0; oauth_key okey_array[3]; static oauth_key_data_raw okdr_array[3] = { - {"north","MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEK",0,0,"A256GCM","crinna.org"}, - {"union","MTIzNDU2Nzg5MDEyMzQ1Ngo=",0,0,"A128GCM","north.gov"}, - {"oldempire","MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIK",0,0,"A256GCM",""} -}; + {"north", "MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEK", 0, 0, "A256GCM", "crinna.org"}, + {"union", "MTIzNDU2Nzg5MDEyMzQ1Ngo=", 0, 0, "A128GCM", "north.gov"}, + {"oldempire", "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIK", 0, 0, "A256GCM", ""}}; //////////////// local definitions ///////////////// static char Usage[] = - "Usage: uclient [flags] [options] turn-server-ip-address\n" - "Flags:\n" - " -t TCP (default - UDP).\n" - " -b SCTP (default - UDP).\n" - " -T TCP relay transport (default - UDP). Implies options -t, -y, -c, and ignores \n" - " options -s, -e, -r and -g. Can be used together with -b\n" - " -P Passive TCP (RFC6062 with active peer). Implies -T.\n" - " -S Secure connection: TLS for TCP, DTLS for UDP.\n" - " -U Secure connection with eNULL cipher.\n" - " -v Verbose.\n" - " -s Use send method.\n" - " -y Use client-to-client connections.\n" - " -h Hang on indefinitely after the last sent packet.\n" - " -c No rtcp connections.\n" - " -x IPv6 relay address requested.\n" - " -X IPv4 relay address explicitly requested.\n" - " -g Include DONT_FRAGMENT option.\n" - " -D Mandatory channel padding (like in pjnath).\n" - " -N Negative tests (some limited cases only).\n" - " -R Negative protocol tests.\n" - " -O DOS attack mode (quick connect and exit).\n" - " -M ICE Mobility engaged.\n" - " -I Do not set permissions on TURN relay endpoints\n" - " (for testing the non-standard server relay functionality).\n" - " -G Generate extra requests (create permissions, channel bind).\n" - " -B Random disconnect after a few initial packets.\n" - " -Z Dual allocation (implies -c).\n" - " -J Use oAuth with default test keys kid='north', 'union' or 'oldempire'.\n" - "Options:\n" - " -l Message length (Default: 100 Bytes).\n" - " -i Certificate file (for secure connections only, optional).\n" - " -k Private key file (for secure connections only).\n" - " -E CA file for server certificate verification, \n" - " if the server certificate to be verified.\n" - " -p TURN server port (Default: 3478 unsecure, 5349 secure).\n" - " -n Number of messages to send (Default: 5).\n" - " -d Local interface device (optional).\n" - " -L Local address.\n" - " -m Number of clients (default is 1).\n" - " -e Peer address.\n" - " -r Peer port (default 3480).\n" - " -z Per-session packet interval in milliseconds (default is 20 ms).\n" - " -u STUN/TURN user name.\n" - " -w STUN/TURN user password.\n" - " -W TURN REST API \"plain text\" secret.\n" - " -C TURN REST API timestamp/username separator symbol (character). The default value is ':'.\n" - " -F Cipher suite for TLS/DTLS. Default value is DEFAULT.\n" - " -o - the ORIGIN STUN attribute value.\n" - " -a Bandwidth for the bandwidth request in ALLOCATE. The default value is zero.\n"; + "Usage: uclient [flags] [options] turn-server-ip-address\n" + "Flags:\n" + " -t TCP (default - UDP).\n" + " -b SCTP (default - UDP).\n" + " -T TCP relay transport (default - UDP). Implies options -t, -y, -c, and ignores \n" + " options -s, -e, -r and -g. Can be used together with -b\n" + " -P Passive TCP (RFC6062 with active peer). Implies -T.\n" + " -S Secure connection: TLS for TCP, DTLS for UDP.\n" + " -U Secure connection with eNULL cipher.\n" + " -v Verbose.\n" + " -s Use send method.\n" + " -y Use client-to-client connections.\n" + " -h Hang on indefinitely after the last sent packet.\n" + " -c No rtcp connections.\n" + " -x IPv6 relay address requested.\n" + " -X IPv4 relay address explicitly requested.\n" + " -g Include DONT_FRAGMENT option.\n" + " -D Mandatory channel padding (like in pjnath).\n" + " -N Negative tests (some limited cases only).\n" + " -R Negative protocol tests.\n" + " -O DOS attack mode (quick connect and exit).\n" + " -M ICE Mobility engaged.\n" + " -I Do not set permissions on TURN relay endpoints\n" + " (for testing the non-standard server relay functionality).\n" + " -G Generate extra requests (create permissions, channel bind).\n" + " -B Random disconnect after a few initial packets.\n" + " -Z Dual allocation (implies -c).\n" + " -J Use oAuth with default test keys kid='north', 'union' or 'oldempire'.\n" + "Options:\n" + " -l Message length (Default: 100 Bytes).\n" + " -i Certificate file (for secure connections only, optional).\n" + " -k Private key file (for secure connections only).\n" + " -E CA file for server certificate verification, \n" + " if the server certificate to be verified.\n" + " -p TURN server port (Default: 3478 unsecure, 5349 secure).\n" + " -n Number of messages to send (Default: 5).\n" + " -d Local interface device (optional).\n" + " -L Local address.\n" + " -m Number of clients (default is 1).\n" + " -e Peer address.\n" + " -r Peer port (default 3480).\n" + " -z Per-session packet interval in milliseconds (default is 20 ms).\n" + " -u STUN/TURN user name.\n" + " -w STUN/TURN user password.\n" + " -W TURN REST API \"plain text\" secret.\n" + " -C TURN REST API timestamp/username separator symbol (character). The default value is ':'.\n" + " -F Cipher suite for TLS/DTLS. Default value is DEFAULT.\n" + " -o - the ORIGIN STUN attribute value.\n" + " -a Bandwidth for the bandwidth request in ALLOCATE. The default value is zero.\n"; ////////////////////////////////////////////////// -int main(int argc, char **argv) -{ - int port = 0; - int messagenumber = 5; - char local_addr[256]; - int c; - int mclient = 1; - char peer_address[129] = "\0"; - int peer_port = PEER_DEFAULT_PORT; +int main(int argc, char **argv) { + int port = 0; + int messagenumber = 5; + char local_addr[256]; + int c; + int mclient = 1; + char peer_address[129] = "\0"; + int peer_port = PEER_DEFAULT_PORT; - char rest_api_separator = ':'; - int use_null_cipher=0; + char rest_api_separator = ':'; + int use_null_cipher = 0; #if defined(WINDOWS) - WORD wVersionRequested; - WSADATA wsaData; - int err; + WORD wVersionRequested; + WSADATA wsaData; + int err; - /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ - wVersionRequested = MAKEWORD(2, 2); + /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ + wVersionRequested = MAKEWORD(2, 2); - err = WSAStartup(wVersionRequested, &wsaData); - if (err != 0) { - /* Tell the user that we could not find a usable */ - /* Winsock DLL. */ - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "WSAStartup failed with error: %d\n", err); - return 1; - } + err = WSAStartup(wVersionRequested, &wsaData); + if (err != 0) { + /* Tell the user that we could not find a usable */ + /* Winsock DLL. */ + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "WSAStartup failed with error: %d\n", err); + return 1; + } #endif - set_logfile("stdout"); - set_no_stdout_log(1); + set_logfile("stdout"); + set_no_stdout_log(1); - set_execdir(); + set_execdir(); - set_system_parameters(0); + set_system_parameters(0); - memset(local_addr, 0, sizeof(local_addr)); + memset(local_addr, 0, sizeof(local_addr)); - while ((c = getopt(argc, argv, "a:d:p:l:n:L:m:e:r:u:w:i:k:z:W:C:E:F:o:bZvsyhcxXgtTSAPDNOUMRIGBJ")) != -1) { - switch (c){ - case 'J': { + while ((c = getopt(argc, argv, "a:d:p:l:n:L:m:e:r:u:w:i:k:z:W:C:E:F:o:bZvsyhcxXgtTSAPDNOUMRIGBJ")) != -1) { + switch (c) { + case 'J': { - oauth = 1; + oauth = 1; - oauth_key_data okd_array[3]; - convert_oauth_key_data_raw(&okdr_array[0], &okd_array[0]); - convert_oauth_key_data_raw(&okdr_array[1], &okd_array[1]); - convert_oauth_key_data_raw(&okdr_array[2], &okd_array[2]); + oauth_key_data okd_array[3]; + convert_oauth_key_data_raw(&okdr_array[0], &okd_array[0]); + convert_oauth_key_data_raw(&okdr_array[1], &okd_array[1]); + convert_oauth_key_data_raw(&okdr_array[2], &okd_array[2]); - char err_msg[1025] = "\0"; - size_t err_msg_size = sizeof(err_msg) - 1; + char err_msg[1025] = "\0"; + size_t err_msg_size = sizeof(err_msg) - 1; - if (convert_oauth_key_data(&okd_array[0], &okey_array[0], err_msg, err_msg_size) < 0) { - fprintf(stderr, "%s\n", err_msg); - exit(-1); - } + if (convert_oauth_key_data(&okd_array[0], &okey_array[0], err_msg, err_msg_size) < 0) { + fprintf(stderr, "%s\n", err_msg); + exit(-1); + } - if (convert_oauth_key_data(&okd_array[1], &okey_array[1], err_msg, err_msg_size) < 0) { - fprintf(stderr, "%s\n", err_msg); - exit(-1); - } + if (convert_oauth_key_data(&okd_array[1], &okey_array[1], err_msg, err_msg_size) < 0) { + fprintf(stderr, "%s\n", err_msg); + exit(-1); + } - if (convert_oauth_key_data(&okd_array[2], &okey_array[2], err_msg, err_msg_size) < 0) { - fprintf(stderr, "%s\n", err_msg); - exit(-1); - } - } - break; - case 'a': - bps = (band_limit_t)strtoul(optarg,NULL,10); - break; - case 'o': - STRCPY(origin,optarg); - break; - case 'B': - random_disconnect = 1; - break; - case 'G': - extra_requests = 1; - break; - case 'F': - STRCPY(cipher_suite,optarg); - break; - case 'I': - no_permissions = 1; - break; - case 'M': - mobility = 1; - break; - case 'E': - { - char* fn = find_config_file(optarg,1); - if(!fn) { - fprintf(stderr,"ERROR: file %s not found\n",optarg); - exit(-1); - } - STRCPY(ca_cert_file,fn); - } - break; - case 'O': - dos = 1; - break; - case 'C': - rest_api_separator=*optarg; - break; - case 'D': - mandatory_channel_padding = 1; - break; - case 'N': - negative_test = 1; - break; - case 'R': - negative_protocol_test = 1; - break; - case 'z': - RTP_PACKET_INTERVAL = atoi(optarg); - break; - case 'Z': - dual_allocation = 1; - break; - case 'u': - STRCPY(g_uname, optarg); - break; - case 'w': - STRCPY(g_upwd, optarg); - break; - case 'g': - dont_fragment = 1; - break; - case 'd': - STRCPY(client_ifname, optarg); - break; - case 'x': - default_address_family = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; - break; - case 'X': - default_address_family = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4; - break; - case 'l': - clmessage_length = atoi(optarg); - break; - case 's': - do_not_use_channel = 1; - break; - case 'n': - messagenumber = atoi(optarg); - break; - case 'p': - port = atoi(optarg); - break; - case 'L': - STRCPY(local_addr, optarg); - break; - case 'e': - STRCPY(peer_address, optarg); - break; - case 'r': - peer_port = atoi(optarg); - break; - case 'v': - clnet_verbose = TURN_VERBOSE_NORMAL; - break; - case 'h': - hang_on = 1; - break; - case 'c': - no_rtcp = 1; - break; - case 'm': - mclient = atoi(optarg); - break; - case 'y': - c2c = 1; - break; - case 't': - use_tcp = 1; - break; - case 'b': - use_sctp = 1; - use_tcp = 1; - break; - case 'P': - passive_tcp = 1; - /* implies 'T': */ - /* no break */ - /* Falls through. */ - case 'T': - relay_transport = STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE; - break; - case 'U': - use_null_cipher = 1; - /* implies 'S' */ - /* no break */ - /* Falls through. */ - case 'S': - use_secure = 1; - break; - case 'W': - g_use_auth_secret_with_timestamp = 1; - STRCPY(g_auth_secret,optarg); - break; - case 'i': - { - char* fn = find_config_file(optarg,1); - if(!fn) { - fprintf(stderr,"ERROR: file %s not found\n",optarg); - exit(-1); - } - STRCPY(cert_file,fn); - free(fn); - } - break; - case 'k': - { - char* fn = find_config_file(optarg,1); - if(!fn) { - fprintf(stderr,"ERROR: file %s not found\n",optarg); - exit(-1); - } - STRCPY(pkey_file,fn); - free(fn); - } - break; - default: - fprintf(stderr, "%s\n", Usage); - exit(1); - } - } + if (convert_oauth_key_data(&okd_array[2], &okey_array[2], err_msg, err_msg_size) < 0) { + fprintf(stderr, "%s\n", err_msg); + exit(-1); + } + } break; + case 'a': + bps = (band_limit_t)strtoul(optarg, NULL, 10); + break; + case 'o': + STRCPY(origin, optarg); + break; + case 'B': + random_disconnect = 1; + break; + case 'G': + extra_requests = 1; + break; + case 'F': + STRCPY(cipher_suite, optarg); + break; + case 'I': + no_permissions = 1; + break; + case 'M': + mobility = 1; + break; + case 'E': { + char *fn = find_config_file(optarg, 1); + if (!fn) { + fprintf(stderr, "ERROR: file %s not found\n", optarg); + exit(-1); + } + STRCPY(ca_cert_file, fn); + } break; + case 'O': + dos = 1; + break; + case 'C': + rest_api_separator = *optarg; + break; + case 'D': + mandatory_channel_padding = 1; + break; + case 'N': + negative_test = 1; + break; + case 'R': + negative_protocol_test = 1; + break; + case 'z': + RTP_PACKET_INTERVAL = atoi(optarg); + break; + case 'Z': + dual_allocation = 1; + break; + case 'u': + STRCPY(g_uname, optarg); + break; + case 'w': + STRCPY(g_upwd, optarg); + break; + case 'g': + dont_fragment = 1; + break; + case 'd': + STRCPY(client_ifname, optarg); + break; + case 'x': + default_address_family = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; + break; + case 'X': + default_address_family = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4; + break; + case 'l': + clmessage_length = atoi(optarg); + break; + case 's': + do_not_use_channel = 1; + break; + case 'n': + messagenumber = atoi(optarg); + break; + case 'p': + port = atoi(optarg); + break; + case 'L': + STRCPY(local_addr, optarg); + break; + case 'e': + STRCPY(peer_address, optarg); + break; + case 'r': + peer_port = atoi(optarg); + break; + case 'v': + clnet_verbose = TURN_VERBOSE_NORMAL; + break; + case 'h': + hang_on = 1; + break; + case 'c': + no_rtcp = 1; + break; + case 'm': + mclient = atoi(optarg); + break; + case 'y': + c2c = 1; + break; + case 't': + use_tcp = 1; + break; + case 'b': + use_sctp = 1; + use_tcp = 1; + break; + case 'P': + passive_tcp = 1; + /* implies 'T': */ + /* no break */ + /* Falls through. */ + case 'T': + relay_transport = STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE; + break; + case 'U': + use_null_cipher = 1; + /* implies 'S' */ + /* no break */ + /* Falls through. */ + case 'S': + use_secure = 1; + break; + case 'W': + g_use_auth_secret_with_timestamp = 1; + STRCPY(g_auth_secret, optarg); + break; + case 'i': { + char *fn = find_config_file(optarg, 1); + if (!fn) { + fprintf(stderr, "ERROR: file %s not found\n", optarg); + exit(-1); + } + STRCPY(cert_file, fn); + free(fn); + } break; + case 'k': { + char *fn = find_config_file(optarg, 1); + if (!fn) { + fprintf(stderr, "ERROR: file %s not found\n", optarg); + exit(-1); + } + STRCPY(pkey_file, fn); + free(fn); + } break; + default: + fprintf(stderr, "%s\n", Usage); + exit(1); + } + } - if(dual_allocation) { - no_rtcp = 1; - } + if (dual_allocation) { + no_rtcp = 1; + } - if(g_use_auth_secret_with_timestamp) { + if (g_use_auth_secret_with_timestamp) { - { - char new_uname[1025]; - const unsigned long exp_time = 3600 * 24; /* one day */ - if(g_uname[0]) { - snprintf(new_uname,sizeof(new_uname),"%lu%c%s",(unsigned long)time(NULL) + exp_time,rest_api_separator, (char*)g_uname); - } else { - snprintf(new_uname,sizeof(new_uname),"%lu", (unsigned long)time(NULL) + exp_time); - } - STRCPY(g_uname,new_uname); - } - { - uint8_t hmac[MAXSHASIZE]; - unsigned int hmac_len; + { + char new_uname[1025]; + const unsigned long exp_time = 3600 * 24; /* one day */ + if (g_uname[0]) { + snprintf(new_uname, sizeof(new_uname), "%lu%c%s", (unsigned long)time(NULL) + exp_time, rest_api_separator, + (char *)g_uname); + } else { + snprintf(new_uname, sizeof(new_uname), "%lu", (unsigned long)time(NULL) + exp_time); + } + STRCPY(g_uname, new_uname); + } + { + uint8_t hmac[MAXSHASIZE]; + unsigned int hmac_len; - switch(shatype) { - case SHATYPE_SHA256: - hmac_len = SHA256SIZEBYTES; - break; - case SHATYPE_SHA384: - hmac_len = SHA384SIZEBYTES; - break; - case SHATYPE_SHA512: - hmac_len = SHA512SIZEBYTES; - break; - default: - hmac_len = SHA1SIZEBYTES; - }; + switch (shatype) { + case SHATYPE_SHA256: + hmac_len = SHA256SIZEBYTES; + break; + case SHATYPE_SHA384: + hmac_len = SHA384SIZEBYTES; + break; + case SHATYPE_SHA512: + hmac_len = SHA512SIZEBYTES; + break; + default: + hmac_len = SHA1SIZEBYTES; + }; - hmac[0]=0; + hmac[0] = 0; - if(stun_calculate_hmac(g_uname, strlen((char*)g_uname), (uint8_t*)g_auth_secret, strlen(g_auth_secret), hmac, &hmac_len, shatype)>=0) { - size_t pwd_length = 0; - char *pwd = base64_encode(hmac,hmac_len,&pwd_length); + if (stun_calculate_hmac(g_uname, strlen((char *)g_uname), (uint8_t *)g_auth_secret, strlen(g_auth_secret), hmac, + &hmac_len, shatype) >= 0) { + size_t pwd_length = 0; + char *pwd = base64_encode(hmac, hmac_len, &pwd_length); - if(pwd) { - if(pwd_length>0) { - memcpy(g_upwd,pwd,pwd_length); - g_upwd[pwd_length]=0; - } - } - free(pwd); - } - } - } + if (pwd) { + if (pwd_length > 0) { + memcpy(g_upwd, pwd, pwd_length); + g_upwd[pwd_length] = 0; + } + } + free(pwd); + } + } + } - if(is_TCP_relay()) { - dont_fragment = 0; - no_rtcp = 1; - c2c = 1; - use_tcp = 1; - do_not_use_channel = 1; - } + if (is_TCP_relay()) { + dont_fragment = 0; + no_rtcp = 1; + c2c = 1; + use_tcp = 1; + do_not_use_channel = 1; + } - if(port == 0) { - if(use_secure) - port = DEFAULT_STUN_TLS_PORT; - else - port = DEFAULT_STUN_PORT; - } + if (port == 0) { + if (use_secure) + port = DEFAULT_STUN_TLS_PORT; + else + port = DEFAULT_STUN_PORT; + } - if (clmessage_length < (int) sizeof(message_info)) - clmessage_length = (int) sizeof(message_info); + if (clmessage_length < (int)sizeof(message_info)) + clmessage_length = (int)sizeof(message_info); - const int max_header = 100; - if(clmessage_length > (int)(STUN_BUFFER_SIZE-max_header)) { - fprintf(stderr,"Message length was corrected to %d\n",(STUN_BUFFER_SIZE-max_header)); - clmessage_length = (int)(STUN_BUFFER_SIZE-max_header); - } + const int max_header = 100; + if (clmessage_length > (int)(STUN_BUFFER_SIZE - max_header)) { + fprintf(stderr, "Message length was corrected to %d\n", (STUN_BUFFER_SIZE - max_header)); + clmessage_length = (int)(STUN_BUFFER_SIZE - max_header); + } - if (optind >= argc) { - fprintf(stderr, "%s\n", Usage); - exit(-1); - } + if (optind >= argc) { + fprintf(stderr, "%s\n", Usage); + exit(-1); + } - if (!c2c) { - if(!peer_address[0]) { - fprintf(stderr,"Either -e peer_address or -y must be specified\n"); - return -1; - } + if (!c2c) { + if (!peer_address[0]) { + fprintf(stderr, "Either -e peer_address or -y must be specified\n"); + return -1; + } - if (make_ioa_addr((const uint8_t*) peer_address, peer_port, &peer_addr) < 0) { - return -1; - } + if (make_ioa_addr((const uint8_t *)peer_address, peer_port, &peer_addr) < 0) { + return -1; + } - if(peer_addr.ss.sa_family == AF_INET6) { - default_address_family = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; - } else if(peer_addr.ss.sa_family == AF_INET) { - default_address_family = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4; - } + if (peer_addr.ss.sa_family == AF_INET6) { + default_address_family = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; + } else if (peer_addr.ss.sa_family == AF_INET) { + default_address_family = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4; + } + } - } + /* SSL Init ==>> */ - /* SSL Init ==>> */ + if (use_secure) { - if(use_secure) { + SSL_load_error_strings(); + OpenSSL_add_ssl_algorithms(); - SSL_load_error_strings(); - OpenSSL_add_ssl_algorithms(); + const char *csuite = "ALL"; //"AES256-SHA" "DH" + if (use_null_cipher) + csuite = "eNULL"; + else if (cipher_suite[0]) + csuite = cipher_suite; - const char *csuite = "ALL"; //"AES256-SHA" "DH" - if(use_null_cipher) - csuite = "eNULL"; - else if(cipher_suite[0]) - csuite=cipher_suite; - - if(use_tcp) { + if (use_tcp) { #if OPENSSL_VERSION_NUMBER < 0x10100000L - #if TLSv1_2_SUPPORTED - root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLSv1_2_client_method()); - #elif TLSv1_1_SUPPORTED - root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLSv1_1_client_method()); - #else - root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLSv1_client_method()); - #endif - SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); -#else // OPENSSL_VERSION_NUMBER >= 0x10100000L - root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLS_client_method()); - SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); +#if TLSv1_2_SUPPORTED + root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLSv1_2_client_method()); +#elif TLSv1_1_SUPPORTED + root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLSv1_1_client_method()); +#else + root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLSv1_client_method()); #endif - root_tls_ctx_num++; - } else { + SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); +#else // OPENSSL_VERSION_NUMBER >= 0x10100000L + root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLS_client_method()); + SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); +#endif + root_tls_ctx_num++; + } else { #if !DTLS_SUPPORTED - fprintf(stderr,"ERROR: DTLS is not supported.\n"); - exit(-1); + fprintf(stderr, "ERROR: DTLS is not supported.\n"); + exit(-1); #else #if OPENSSL_VERSION_NUMBER < 0x10100000L - if(OPENSSL_VERSION_NUMBER < 0x10000000L) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: OpenSSL version is rather old, DTLS may not be working correctly.\n"); - } - #if DTLSv1_2_SUPPORTED - root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(DTLSv1_2_client_method()); - #else - root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(DTLSv1_client_method()); - #endif - SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); + if (OPENSSL_VERSION_NUMBER < 0x10000000L) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, + "WARNING: OpenSSL version is rather old, DTLS may not be working correctly.\n"); + } +#if DTLSv1_2_SUPPORTED + root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(DTLSv1_2_client_method()); +#else + root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(DTLSv1_client_method()); +#endif + SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); #else // OPENSSL_VERSION_NUMBER >= 0x10100000L - root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(DTLS_client_method()); - SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); + root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(DTLS_client_method()); + SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); #endif #endif - root_tls_ctx_num++; - } - } + root_tls_ctx_num++; + } + } - int use_cert = 0; - int use_ca_cert = 0; - if(cert_file[0] && pkey_file[0]) - { - use_cert = 1; - } - if(ca_cert_file[0]) - { - use_ca_cert = 1; - } + int use_cert = 0; + int use_ca_cert = 0; + if (cert_file[0] && pkey_file[0]) { + use_cert = 1; + } + if (ca_cert_file[0]) { + use_ca_cert = 1; + } - if(use_cert) - { - int sslind = 0; - for(sslind = 0; sslind #include +#include #include "ns_turn_ioaddr.h" #include "ns_turn_utils.h" -#include "stun_buffer.h" #include "apputils.h" +#include "stun_buffer.h" #include "ns_turn_openssl.h" @@ -48,29 +48,24 @@ extern "C" { ///////// types //////////// -enum _UR_STATE { - UR_STATE_UNKNOWN=0, - UR_STATE_READY, - UR_STATE_DONE -}; +enum _UR_STATE { UR_STATE_UNKNOWN = 0, UR_STATE_READY, UR_STATE_DONE }; typedef enum _UR_STATE UR_STATE; //////////////// session info ////////////////////// -typedef struct -{ - /* RFC 6062 */ - uint32_t cid; - ioa_addr tcp_data_local_addr; - ioa_socket_raw tcp_data_fd; - SSL *tcp_data_ssl; - int tcp_data_bound; +typedef struct { + /* RFC 6062 */ + uint32_t cid; + ioa_addr tcp_data_local_addr; + ioa_socket_raw tcp_data_fd; + SSL *tcp_data_ssl; + int tcp_data_bound; } app_tcp_conn_info; typedef struct { ioa_addr local_addr; - char lsaddr[129]; + char lsaddr[129]; ioa_addr remote_addr; char rsaddr[129]; char ifname[129]; @@ -79,11 +74,11 @@ typedef struct { ioa_socket_raw fd; SSL *ssl; int broken; - uint8_t nonce[STUN_MAX_NONCE_SIZE+1]; - uint8_t realm[STUN_MAX_REALM_SIZE+1]; + uint8_t nonce[STUN_MAX_NONCE_SIZE + 1]; + uint8_t realm[STUN_MAX_REALM_SIZE + 1]; /* oAuth */ int oauth; - uint8_t server_name[STUN_MAX_SERVER_NAME_SIZE+1]; + uint8_t server_name[STUN_MAX_SERVER_NAME_SIZE + 1]; hmackey_t key; int key_set; int cok; @@ -108,14 +103,14 @@ typedef struct { stun_buffer out_buffer; uint32_t refresh_time; uint32_t finished_time; - //Msg counters: + // Msg counters: int tot_msgnum; int wmsgnum; int rmsgnum; int recvmsgnum; uint32_t recvtimems; uint32_t to_send_timems; - //Statistics: + // Statistics: size_t loss; uint64_t latency; uint64_t jitter; @@ -124,8 +119,8 @@ typedef struct { /////////////////////////////////////////////////////// typedef struct _message_info { - int msgnum; - uint64_t mstime; + int msgnum; + uint64_t mstime; } message_info; /////////////////////////////////////////////////////////////////////////////// diff --git a/src/apps/uclient/startuclient.c b/src/apps/uclient/startuclient.c index 820b8eb..71705cd 100644 --- a/src/apps/uclient/startuclient.c +++ b/src/apps/uclient/startuclient.c @@ -33,11 +33,11 @@ #endif #include "apputils.h" -#include "ns_turn_utils.h" -#include "startuclient.h" #include "ns_turn_msg.h" -#include "uclient.h" +#include "ns_turn_utils.h" #include "session.h" +#include "startuclient.h" +#include "uclient.h" ///////////////////////////////////////// @@ -57,1580 +57,1543 @@ static const size_t kALPNProtosLen = sizeof(kALPNProtos) - 1; ///////////////////////////////////////// -int rare_event(void) -{ - if(dos) - return (((unsigned long)turn_random()) %1000 == 777); - return 0; +int rare_event(void) { + if (dos) + return (((unsigned long)turn_random()) % 1000 == 777); + return 0; } -int not_rare_event(void) -{ - if(dos) - return ((((unsigned long)turn_random()) %1000) < 200); - return 0; +int not_rare_event(void) { + if (dos) + return ((((unsigned long)turn_random()) % 1000) < 200); + return 0; } static int get_allocate_address_family(ioa_addr *relay_addr) { - if(relay_addr->ss.sa_family == AF_INET) - return STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT; - else if(relay_addr->ss.sa_family == AF_INET6) - return STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; - else - return STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_INVALID; + if (relay_addr->ss.sa_family == AF_INET) + return STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT; + else if (relay_addr->ss.sa_family == AF_INET6) + return STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; + else + return STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_INVALID; } ///////////////////////////////////////// -static SSL* tls_connect(ioa_socket_raw fd, ioa_addr *remote_addr, int *try_again, int connect_cycle) -{ +static SSL *tls_connect(ioa_socket_raw fd, ioa_addr *remote_addr, int *try_again, int connect_cycle) { - int ctxtype = (int)(((unsigned long)turn_random())%root_tls_ctx_num); + int ctxtype = (int)(((unsigned long)turn_random()) % root_tls_ctx_num); - SSL *ssl; + SSL *ssl; - ssl = SSL_new(root_tls_ctx[ctxtype]); + ssl = SSL_new(root_tls_ctx[ctxtype]); #if ALPN_SUPPORTED - SSL_set_alpn_protos(ssl, kALPNProtos, kALPNProtosLen); + SSL_set_alpn_protos(ssl, kALPNProtos, kALPNProtosLen); #endif - if(use_tcp) { - SSL_set_fd(ssl, fd); - } else { + if (use_tcp) { + SSL_set_fd(ssl, fd); + } else { #if !DTLS_SUPPORTED - UNUSED_ARG(remote_addr); - fprintf(stderr,"ERROR: DTLS is not supported.\n"); - exit(-1); + UNUSED_ARG(remote_addr); + fprintf(stderr, "ERROR: DTLS is not supported.\n"); + exit(-1); #else - /* Create BIO, connect and set to already connected */ - BIO *bio = BIO_new_dgram(fd, BIO_CLOSE); - //bio = BIO_new_socket(fd, BIO_CLOSE); + /* Create BIO, connect and set to already connected */ + BIO *bio = BIO_new_dgram(fd, BIO_CLOSE); + // bio = BIO_new_socket(fd, BIO_CLOSE); - BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &remote_addr->ss); + BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &remote_addr->ss); - SSL_set_bio(ssl, bio, bio); + SSL_set_bio(ssl, bio, bio); - { - struct timeval timeout; - /* Set and activate timeouts */ - timeout.tv_sec = DTLS_MAX_CONNECT_TIMEOUT; - timeout.tv_usec = 0; - BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); - } + { + struct timeval timeout; + /* Set and activate timeouts */ + timeout.tv_sec = DTLS_MAX_CONNECT_TIMEOUT; + timeout.tv_usec = 0; + BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); + } - set_mtu_df(ssl, fd, remote_addr->ss.sa_family, SOSO_MTU, !use_tcp, clnet_verbose); + set_mtu_df(ssl, fd, remote_addr->ss.sa_family, SOSO_MTU, !use_tcp, clnet_verbose); #endif - } + } - SSL_set_max_cert_list(ssl, 655350); + SSL_set_max_cert_list(ssl, 655350); - if (clnet_verbose) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "call SSL_connect...\n"); + if (clnet_verbose) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "call SSL_connect...\n"); - int rc = 0; + int rc = 0; - do { - do { - rc = SSL_connect(ssl); - } while (rc < 0 && errno == EINTR); - int orig_errno = errno; - if (rc > 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s: client session connected with cipher %s, method=%s\n",__FUNCTION__, - SSL_get_cipher(ssl),turn_get_ssl_method(ssl,NULL)); + do { + do { + rc = SSL_connect(ssl); + } while (rc < 0 && errno == EINTR); + int orig_errno = errno; + if (rc > 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: client session connected with cipher %s, method=%s\n", __FUNCTION__, + SSL_get_cipher(ssl), turn_get_ssl_method(ssl, NULL)); #if (OPENSSL_VERSION_NUMBER >= 0x30000000L) - if(clnet_verbose && SSL_get1_peer_certificate(ssl)) { + if (clnet_verbose && SSL_get1_peer_certificate(ssl)) { #else - if(clnet_verbose && SSL_get_peer_certificate(ssl)) { + if (clnet_verbose && SSL_get_peer_certificate(ssl)) { #endif - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "------------------------------------------------------------\n"); - X509_NAME_print_ex_fp(stdout, X509_get_subject_name(SSL_get_peer_certificate(ssl)), 1, - XN_FLAG_MULTILINE); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n\n Cipher: %s\n", SSL_CIPHER_get_name(SSL_get_current_cipher(ssl))); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n------------------------------------------------------------\n\n"); - } - break; - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: cannot connect: rc=%d, ctx=%d\n", - __FUNCTION__,rc,ctxtype); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "------------------------------------------------------------\n"); + X509_NAME_print_ex_fp(stdout, X509_get_subject_name(SSL_get_peer_certificate(ssl)), 1, XN_FLAG_MULTILINE); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n\n Cipher: %s\n", SSL_CIPHER_get_name(SSL_get_current_cipher(ssl))); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n------------------------------------------------------------\n\n"); + } + break; + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: cannot connect: rc=%d, ctx=%d\n", __FUNCTION__, rc, ctxtype); - switch (SSL_get_error(ssl, rc)) { - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - if(!dos) usleep(1000); - continue; - default: { - char buf[1025]; - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "errno=%d, err=%d, %s (%d)\n",orig_errno, - (int)ERR_get_error(), ERR_error_string(ERR_get_error(), buf), (int)SSL_get_error(ssl, rc)); - if(connect_cycleis_peer && (*local_address == 0)) { + + if (remote_addr.ss.sa_family == AF_INET6) { + if (make_ioa_addr((const uint8_t *)"::1", 0, &local_addr) < 0) { + socket_closesocket(clnet_fd); + return -1; + } + } else { + if (make_ioa_addr((const uint8_t *)"127.0.0.1", 0, &local_addr) < 0) { + socket_closesocket(clnet_fd); + return -1; + } + } + + addr_bind(clnet_fd, &local_addr, 0, 1, get_socket_type()); + + } else if (strlen(local_address) > 0) { + + if (make_ioa_addr((const uint8_t *)local_address, 0, &local_addr) < 0) { + socket_closesocket(clnet_fd); + return -1; + } + + addr_bind(clnet_fd, &local_addr, 0, 1, get_socket_type()); + } + + if (clnet_info->is_peer) { + ; + } else if (socket_connect(clnet_fd, &remote_addr, &connect_err) > 0) + goto start_socket; + + if (clnet_info) { + addr_cpy(&(clnet_info->remote_addr), &remote_addr); + addr_cpy(&(clnet_info->local_addr), &local_addr); + clnet_info->fd = clnet_fd; + addr_get_from_sock(clnet_fd, &(clnet_info->local_addr)); + STRCPY(clnet_info->lsaddr, local_address); + STRCPY(clnet_info->rsaddr, remote_address); + STRCPY(clnet_info->ifname, (const char *)ifname); + } + + if (use_secure) { + int try_again = 0; + clnet_info->ssl = tls_connect(clnet_info->fd, &remote_addr, &try_again, connect_cycle++); + if (!clnet_info->ssl) { + if (try_again) { + goto start_socket; + } + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: cannot SSL connect to remote addr\n", __FUNCTION__); + exit(-1); + } + } + + if (verbose && clnet_info) { + addr_debug_print(verbose, &(clnet_info->local_addr), "Connected from"); + addr_debug_print(verbose, &remote_addr, "Connected to"); + } + + if (!dos) + usleep(500); + + return 0; +} + +int read_mobility_ticket(app_ur_conn_info *clnet_info, stun_buffer *message) { + int ret = 0; + if (clnet_info && message) { + stun_attr_ref s_mobile_id_sar = stun_attr_get_first_by_type(message, STUN_ATTRIBUTE_MOBILITY_TICKET); + if (s_mobile_id_sar) { + int smid_len = stun_attr_get_len(s_mobile_id_sar); + if (smid_len > 0 && (((size_t)smid_len) < sizeof(clnet_info->s_mobile_id))) { + const uint8_t *smid_val = stun_attr_get_value(s_mobile_id_sar); + if (smid_val) { + memcpy(clnet_info->s_mobile_id, smid_val, (size_t)smid_len); + clnet_info->s_mobile_id[smid_len] = 0; + if (clnet_verbose) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: smid=%s\n", __FUNCTION__, clnet_info->s_mobile_id); + } + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: smid_len=%d\n", __FUNCTION__, smid_len); + ret = -1; + } + } + } + return ret; +} + +void add_origin(stun_buffer *message) { + if (message && origin[0]) { + const char *some_origin = "https://carleon.gov:443"; + stun_attr_add(message, STUN_ATTRIBUTE_ORIGIN, some_origin, strlen(some_origin)); + stun_attr_add(message, STUN_ATTRIBUTE_ORIGIN, origin, strlen(origin)); + some_origin = "ftp://uffrith.net"; + stun_attr_add(message, STUN_ATTRIBUTE_ORIGIN, some_origin, strlen(some_origin)); + } +} + +static int clnet_allocate(int verbose, app_ur_conn_info *clnet_info, ioa_addr *relay_addr, int af, char *turn_addr, + uint16_t *turn_port) { + + int af_cycle = 0; + int reopen_socket = 0; + + int allocate_finished; + + stun_buffer request_message, response_message; + +beg_allocate: + + allocate_finished = 0; + + while (!allocate_finished && af_cycle++ < 32) { + + int allocate_sent = 0; + + if (reopen_socket && !use_tcp) { + socket_closesocket(clnet_info->fd); + clnet_info->fd = -1; + if (clnet_connect(addr_get_port(&(clnet_info->remote_addr)), clnet_info->rsaddr, (uint8_t *)clnet_info->ifname, + clnet_info->lsaddr, verbose, clnet_info) < 0) { + exit(-1); + } + reopen_socket = 0; + } + + int af4 = dual_allocation || (af == STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4); + int af6 = dual_allocation || (af == STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6); + + uint64_t reservation_token = 0; + char *rt = NULL; + int ep = !no_rtcp && !dual_allocation; + + if (!no_rtcp) { + if (!never_allocate_rtcp && allocate_rtcp) { + reservation_token = ioa_ntoh64(current_reservation_token); + rt = (char *)(&reservation_token); + } + } + + if (is_TCP_relay()) { + ep = -1; + } else if (rt) { + ep = -1; + } else if (!ep) { + ep = (((uint8_t)turn_random()) % 2); + ep = ep - 1; + } + + if (!dos) + stun_set_allocate_request(&request_message, UCLIENT_SESSION_LIFETIME, af4, af6, relay_transport, mobility, rt, + ep); + else + stun_set_allocate_request(&request_message, UCLIENT_SESSION_LIFETIME / 3, af4, af6, relay_transport, mobility, rt, + ep); + + if (bps) + stun_attr_add_bandwidth_str(request_message.buf, (size_t *)(&(request_message.len)), bps); + + if (dont_fragment) + stun_attr_add(&request_message, STUN_ATTRIBUTE_DONT_FRAGMENT, NULL, 0); + + add_origin(&request_message); + + if (add_integrity(clnet_info, &request_message) < 0) + return -1; + + stun_attr_add_fingerprint_str(request_message.buf, (size_t *)&(request_message.len)); + + while (!allocate_sent) { + + int len = send_buffer(clnet_info, &request_message, 0, 0); + + if (len > 0) { + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "allocate sent\n"); + } + allocate_sent = 1; + } else { + perror("send"); + exit(1); + } + } + + ////////////<<==allocate send + + if (not_rare_event()) + return 0; + + ////////allocate response==>> + { + int allocate_received = 0; + while (!allocate_received) { + + int len = recv_buffer(clnet_info, &response_message, 1, 0, NULL, &request_message); + + if (len > 0) { + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "allocate response received: \n"); + } + response_message.len = len; + int err_code = 0; + uint8_t err_msg[129]; + if (stun_is_success_response(&response_message)) { + allocate_received = 1; + allocate_finished = 1; + + if (clnet_info->nonce[0]) { + if (check_integrity(clnet_info, &response_message) < 0) + return -1; + } + + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "success\n"); + } + { + int found = 0; + + stun_attr_ref sar = stun_attr_get_first(&response_message); + while (sar) { + + int attr_type = stun_attr_get_type(sar); + if (attr_type == STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS) { + + if (stun_attr_get_addr(&response_message, sar, relay_addr, NULL) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: !!!: relay addr cannot be received (1)\n", __FUNCTION__); + return -1; + } else { + if (verbose) { + ioa_addr raddr; + memcpy(&raddr, relay_addr, sizeof(ioa_addr)); + addr_debug_print(verbose, &raddr, "Received relay addr"); + } + + if (!addr_any(relay_addr)) { + if (relay_addr->ss.sa_family == AF_INET) { + if (default_address_family != STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6) { + found = 1; + addr_cpy(&(clnet_info->relay_addr), relay_addr); + break; + } + } + if (relay_addr->ss.sa_family == AF_INET6) { + if (default_address_family == STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6) { + found = 1; + addr_cpy(&(clnet_info->relay_addr), relay_addr); + break; + } + } + } + } + } + + sar = stun_attr_get_next(&response_message, sar); + } + + if (!found) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: !!!: relay addr cannot be received (2)\n", __FUNCTION__); + return -1; + } + } + + stun_attr_ref rt_sar = stun_attr_get_first_by_type(&response_message, STUN_ATTRIBUTE_RESERVATION_TOKEN); + uint64_t rtv = stun_attr_get_reservation_token_value(rt_sar); + current_reservation_token = rtv; + if (verbose) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: rtv=%llu\n", __FUNCTION__, (long long unsigned int)rtv); + + read_mobility_ticket(clnet_info, &response_message); + + } else if (stun_is_challenge_response_str(response_message.buf, (size_t)response_message.len, &err_code, + err_msg, sizeof(err_msg), clnet_info->realm, clnet_info->nonce, + clnet_info->server_name, &(clnet_info->oauth))) { + goto beg_allocate; + } else if (stun_is_error_response(&response_message, &err_code, err_msg, sizeof(err_msg))) { + + allocate_received = 1; + + if (err_code == 300) { + + if (clnet_info->nonce[0]) { + if (check_integrity(clnet_info, &response_message) < 0) + return -1; + } + + ioa_addr alternate_server; + if (stun_attr_get_first_addr(&response_message, STUN_ATTRIBUTE_ALTERNATE_SERVER, &alternate_server, + NULL) == -1) { + // error + } else if (turn_addr && turn_port) { + addr_to_string_no_port(&alternate_server, (uint8_t *)turn_addr); + *turn_port = (uint16_t)addr_get_port(&alternate_server); + } + } + + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "error %d (%s)\n", err_code, (char *)err_msg); + if (err_code != 437) { + allocate_finished = 1; + current_reservation_token = 0; + return -1; + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "trying allocate again %d...\n", err_code); + sleep(1); + reopen_socket = 1; + } + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "unknown allocate response\n"); + /* Try again ? */ + } + } else { + perror("recv"); + exit(-1); + break; + } + } + } + } + ////////////<<== allocate response received + + if (rare_event()) + return 0; + + if (!allocate_finished) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot complete Allocation\n"); + exit(-1); + } + + allocate_rtcp = !allocate_rtcp; + + if (1) { + + af_cycle = 0; + + if (clnet_info->s_mobile_id[0]) { + + int fd = clnet_info->fd; + SSL *ssl = clnet_info->ssl; + + int close_now = (int)(turn_random() % 2); + + if (close_now) { + int close_socket = (int)(turn_random() % 2); + if (ssl && !close_socket) { + SSL_shutdown(ssl); + SSL_free(ssl); + fd = -1; + } else if (fd >= 0) { + close(fd); + fd = -1; + ssl = NULL; + } + } + + app_ur_conn_info ci; + memcpy(&ci, clnet_info, sizeof(ci)); + ci.fd = -1; + ci.ssl = NULL; + clnet_info->fd = -1; + clnet_info->ssl = NULL; + // Reopen: + if (clnet_connect(addr_get_port(&(ci.remote_addr)), ci.rsaddr, (unsigned char *)ci.ifname, ci.lsaddr, + clnet_verbose, clnet_info) < 0) { + exit(-1); + } + + if (ssl) { + SSL_shutdown(ssl); + SSL_free(ssl); + } else if (fd >= 0) { + close(fd); + } + } + + beg_refresh: + + if (af_cycle++ > 32) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot complete Refresh\n"); + exit(-1); + } + + //==>>refresh request, for an example only: + { + int refresh_sent = 0; + + stun_init_request(STUN_METHOD_REFRESH, &request_message); + uint32_t lt = htonl(UCLIENT_SESSION_LIFETIME); + stun_attr_add(&request_message, STUN_ATTRIBUTE_LIFETIME, (const char *)<, 4); + + if (clnet_info->s_mobile_id[0]) { + stun_attr_add(&request_message, STUN_ATTRIBUTE_MOBILITY_TICKET, (const char *)clnet_info->s_mobile_id, + strlen(clnet_info->s_mobile_id)); + } + + if (dual_allocation && !mobility) { + int t = ((uint8_t)turn_random()) % 3; + if (t) { + uint8_t field[4]; + field[0] = (t == 1) ? (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4 + : (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; + field[1] = 0; + field[2] = 0; + field[3] = 0; + stun_attr_add(&request_message, STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY, (const char *)field, 4); + } + } + + add_origin(&request_message); + + if (add_integrity(clnet_info, &request_message) < 0) + return -1; + + stun_attr_add_fingerprint_str(request_message.buf, (size_t *)&(request_message.len)); + + while (!refresh_sent) { + + int len = send_buffer(clnet_info, &request_message, 0, 0); + + if (len > 0) { + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "refresh sent\n"); + } + refresh_sent = 1; + + if (clnet_info->s_mobile_id[0]) { + usleep(10000); + send_buffer(clnet_info, &request_message, 0, 0); + } + } else { + perror("send"); + exit(1); + } + } + } + + if (not_rare_event()) + return 0; + + ////////refresh response==>> + { + int refresh_received = 0; + while (!refresh_received) { + + int len = recv_buffer(clnet_info, &response_message, 1, 0, NULL, &request_message); + + if (clnet_info->s_mobile_id[0]) { + len = recv_buffer(clnet_info, &response_message, 1, 0, NULL, &request_message); + } + + if (len > 0) { + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "refresh response received: \n"); + } + response_message.len = len; + int err_code = 0; + uint8_t err_msg[129]; + if (stun_is_success_response(&response_message)) { + read_mobility_ticket(clnet_info, &response_message); + refresh_received = 1; + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "success\n"); + } + } else if (stun_is_challenge_response_str(response_message.buf, (size_t)response_message.len, &err_code, + err_msg, sizeof(err_msg), clnet_info->realm, clnet_info->nonce, + clnet_info->server_name, &(clnet_info->oauth))) { + goto beg_refresh; + } else if (stun_is_error_response(&response_message, &err_code, err_msg, sizeof(err_msg))) { + refresh_received = 1; + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "error %d (%s)\n", err_code, (char *)err_msg); + return -1; + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "unknown refresh response\n"); + /* Try again ? */ + } + } else { + perror("recv"); + exit(-1); + break; + } + } + } + } + + return 0; +} + +static int turn_channel_bind(int verbose, uint16_t *chn, app_ur_conn_info *clnet_info, ioa_addr *peer_addr) { + + stun_buffer request_message, response_message; + +beg_bind : + { - if (addr_connect(clnet_fd, remote_addr, connect_err) < 0) { - if(*connect_err == EINPROGRESS) - return 0; - if (*connect_err == EADDRINUSE) - return +1; - perror("connect"); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: cannot connect to remote addr: %d\n", __FUNCTION__,*connect_err); - exit(-1); - } + int cb_sent = 0; - return 0; + if (negative_test) { + *chn = stun_set_channel_bind_request(&request_message, peer_addr, (uint16_t)turn_random()); + } else { + *chn = stun_set_channel_bind_request(&request_message, peer_addr, *chn); + } + + add_origin(&request_message); + + if (add_integrity(clnet_info, &request_message) < 0) + return -1; + + stun_attr_add_fingerprint_str(request_message.buf, (size_t *)&(request_message.len)); + + while (!cb_sent) { + + int len = send_buffer(clnet_info, &request_message, 0, 0); + if (len > 0) { + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "channel bind sent\n"); + } + cb_sent = 1; + } else { + perror("send"); + exit(1); + } + } } -static int clnet_connect(uint16_t clnet_remote_port, const char *remote_address, - const unsigned char* ifname, const char *local_address, int verbose, - app_ur_conn_info *clnet_info) { + ////////////<<==channel bind send - ioa_addr local_addr; - evutil_socket_t clnet_fd; - int connect_err; - int connect_cycle = 0; + if (not_rare_event()) + return 0; - ioa_addr remote_addr; + ////////channel bind response==>> - start_socket: + { + int cb_received = 0; + while (!cb_received) { - clnet_fd = -1; - connect_err = 0; + int len = recv_buffer(clnet_info, &response_message, 1, 0, NULL, &request_message); + if (len > 0) { + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "cb response received: \n"); + } + int err_code = 0; + uint8_t err_msg[129]; + if (stun_is_success_response(&response_message)) { - memset(&remote_addr, 0, sizeof(ioa_addr)); - if (make_ioa_addr((const uint8_t*) remote_address, clnet_remote_port, - &remote_addr) < 0) - return -1; + cb_received = 1; - memset(&local_addr, 0, sizeof(ioa_addr)); + if (clnet_info->nonce[0]) { + if (check_integrity(clnet_info, &response_message) < 0) + return -1; + } - clnet_fd = socket(remote_addr.ss.sa_family, - use_sctp ? SCTP_CLIENT_STREAM_SOCKET_TYPE : (use_tcp ? CLIENT_STREAM_SOCKET_TYPE : CLIENT_DGRAM_SOCKET_TYPE), - use_sctp ? SCTP_CLIENT_STREAM_SOCKET_PROTOCOL : (use_tcp ? CLIENT_STREAM_SOCKET_PROTOCOL : CLIENT_DGRAM_SOCKET_PROTOCOL)); - if (clnet_fd < 0) { - perror("socket"); - exit(-1); - } + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "success: 0x%x\n", (int)(*chn)); + } + } else if (stun_is_challenge_response_str(response_message.buf, (size_t)response_message.len, &err_code, + err_msg, sizeof(err_msg), clnet_info->realm, clnet_info->nonce, + clnet_info->server_name, &(clnet_info->oauth))) { + goto beg_bind; + } else if (stun_is_error_response(&response_message, &err_code, err_msg, sizeof(err_msg))) { + cb_received = 1; + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "channel bind: error %d (%s)\n", err_code, (char *)err_msg); + return -1; + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "unknown channel bind response\n"); + /* Try again ? */ + } + } else { + perror("recv"); + exit(-1); + break; + } + } + } - if (sock_bind_to_device(clnet_fd, ifname) < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "Cannot bind client socket to device %s\n", ifname); - } - - set_sock_buf_size(clnet_fd, UR_CLIENT_SOCK_BUF_SIZE); - - set_raw_socket_tos(clnet_fd, remote_addr.ss.sa_family, 0x22); - set_raw_socket_ttl(clnet_fd, remote_addr.ss.sa_family, 47); - - if(clnet_info->is_peer && (*local_address==0)) { - - if(remote_addr.ss.sa_family == AF_INET6) { - if (make_ioa_addr((const uint8_t*) "::1", 0, &local_addr) < 0) { - socket_closesocket(clnet_fd); - return -1; - } - } else { - if (make_ioa_addr((const uint8_t*) "127.0.0.1", 0, &local_addr) < 0) { - socket_closesocket(clnet_fd); - return -1; - } - } - - addr_bind(clnet_fd, &local_addr, 0, 1, get_socket_type()); - - } else if (strlen(local_address) > 0) { - - if (make_ioa_addr((const uint8_t*) local_address, 0, - &local_addr) < 0) { - socket_closesocket(clnet_fd); - return -1; - } - - addr_bind(clnet_fd, &local_addr,0,1,get_socket_type()); - } - - if(clnet_info->is_peer) { - ; - } else if(socket_connect(clnet_fd, &remote_addr, &connect_err)>0) - goto start_socket; - - if (clnet_info) { - addr_cpy(&(clnet_info->remote_addr), &remote_addr); - addr_cpy(&(clnet_info->local_addr), &local_addr); - clnet_info->fd = clnet_fd; - addr_get_from_sock(clnet_fd, &(clnet_info->local_addr)); - STRCPY(clnet_info->lsaddr,local_address); - STRCPY(clnet_info->rsaddr,remote_address); - STRCPY(clnet_info->ifname,(const char*)ifname); - } - - if (use_secure) { - int try_again = 0; - clnet_info->ssl = tls_connect(clnet_info->fd, &remote_addr,&try_again,connect_cycle++); - if (!clnet_info->ssl) { - if(try_again) { - goto start_socket; - } - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: cannot SSL connect to remote addr\n", __FUNCTION__); - exit(-1); - } - } - - if(verbose && clnet_info) { - addr_debug_print(verbose, &(clnet_info->local_addr), "Connected from"); - addr_debug_print(verbose, &remote_addr, "Connected to"); - } - - if(!dos) usleep(500); - - return 0; + return 0; } -int read_mobility_ticket(app_ur_conn_info *clnet_info, stun_buffer *message) +static int turn_create_permission(int verbose, app_ur_conn_info *clnet_info, ioa_addr *peer_addr, int addrnum) { + + if (no_permissions || (addrnum < 1)) + return 0; + + char saddr[129] = "\0"; + if (verbose) { + addr_to_string(peer_addr, (uint8_t *)saddr); + } + + stun_buffer request_message, response_message; + +beg_cp : + { - int ret = 0; - if(clnet_info && message) { - stun_attr_ref s_mobile_id_sar = stun_attr_get_first_by_type(message, STUN_ATTRIBUTE_MOBILITY_TICKET); - if(s_mobile_id_sar) { - int smid_len = stun_attr_get_len(s_mobile_id_sar); - if(smid_len>0 && (((size_t)smid_len)s_mobile_id))) { - const uint8_t* smid_val = stun_attr_get_value(s_mobile_id_sar); - if(smid_val) { - memcpy(clnet_info->s_mobile_id, smid_val, (size_t)smid_len); - clnet_info->s_mobile_id[smid_len] = 0; - if (clnet_verbose) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: smid=%s\n", __FUNCTION__, clnet_info->s_mobile_id); - } - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: ERROR: smid_len=%d\n", __FUNCTION__, smid_len); - ret = -1; - } - } - } - return ret; + int cp_sent = 0; + + stun_init_request(STUN_METHOD_CREATE_PERMISSION, &request_message); + { + int addrindex; + for (addrindex = 0; addrindex < addrnum; ++addrindex) { + stun_attr_add_addr(&request_message, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, peer_addr + addrindex); + } + } + + add_origin(&request_message); + + if (add_integrity(clnet_info, &request_message) < 0) + return -1; + + stun_attr_add_fingerprint_str(request_message.buf, (size_t *)&(request_message.len)); + + while (!cp_sent) { + + int len = send_buffer(clnet_info, &request_message, 0, 0); + + if (len > 0) { + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "create perm sent: %s\n", saddr); + } + cp_sent = 1; + } else { + perror("send"); + exit(1); + } + } } -void add_origin(stun_buffer *message) -{ - if(message && origin[0]) { - const char* some_origin = "https://carleon.gov:443"; - stun_attr_add(message, STUN_ATTRIBUTE_ORIGIN, some_origin, strlen(some_origin)); - stun_attr_add(message, STUN_ATTRIBUTE_ORIGIN, origin, strlen(origin)); - some_origin = "ftp://uffrith.net"; - stun_attr_add(message, STUN_ATTRIBUTE_ORIGIN, some_origin, strlen(some_origin)); - } + ////////////<<==create permission send + + if (not_rare_event()) + return 0; + + ////////create permission response==>> + + { + int cp_received = 0; + while (!cp_received) { + + int len = recv_buffer(clnet_info, &response_message, 1, 0, NULL, &request_message); + if (len > 0) { + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "cp response received: \n"); + } + int err_code = 0; + uint8_t err_msg[129]; + if (stun_is_success_response(&response_message)) { + + cp_received = 1; + + if (clnet_info->nonce[0]) { + if (check_integrity(clnet_info, &response_message) < 0) + return -1; + } + + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "success\n"); + } + } else if (stun_is_challenge_response_str(response_message.buf, (size_t)response_message.len, &err_code, + err_msg, sizeof(err_msg), clnet_info->realm, clnet_info->nonce, + clnet_info->server_name, &(clnet_info->oauth))) { + goto beg_cp; + } else if (stun_is_error_response(&response_message, &err_code, err_msg, sizeof(err_msg))) { + cp_received = 1; + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "create permission error %d (%s)\n", err_code, (char *)err_msg); + return -1; + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "unknown create permission response\n"); + /* Try again ? */ + } + } else { + perror("recv"); + exit(-1); + } + } + } + + return 0; } -static int clnet_allocate(int verbose, - app_ur_conn_info *clnet_info, - ioa_addr *relay_addr, - int af, - char *turn_addr, uint16_t *turn_port) { - - int af_cycle = 0; - int reopen_socket = 0; - - int allocate_finished; - - stun_buffer request_message, response_message; - - beg_allocate: - - allocate_finished=0; - - while (!allocate_finished && af_cycle++ < 32) { - - int allocate_sent = 0; - - if(reopen_socket && !use_tcp) { - socket_closesocket(clnet_info->fd); - clnet_info->fd = -1; - if (clnet_connect(addr_get_port(&(clnet_info->remote_addr)), clnet_info->rsaddr, (uint8_t*)clnet_info->ifname, clnet_info->lsaddr, - verbose, clnet_info) < 0) { - exit(-1); - } - reopen_socket = 0; - } - - int af4 = dual_allocation || (af == STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4); - int af6 = dual_allocation || (af == STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6); - - uint64_t reservation_token = 0; - char* rt = NULL; - int ep = !no_rtcp && !dual_allocation; - - if(!no_rtcp) { - if (!never_allocate_rtcp && allocate_rtcp) { - reservation_token = ioa_ntoh64(current_reservation_token); - rt = (char*) (&reservation_token); - } - } - - if(is_TCP_relay()) { - ep = -1; - } else if(rt) { - ep = -1; - } else if(!ep) { - ep = (((uint8_t)turn_random()) % 2); - ep = ep-1; - } - - if(!dos) - stun_set_allocate_request(&request_message, UCLIENT_SESSION_LIFETIME, af4, af6, relay_transport, mobility, rt, ep); - else - stun_set_allocate_request(&request_message, UCLIENT_SESSION_LIFETIME/3, af4, af6, relay_transport, mobility, rt, ep); - - if(bps) - stun_attr_add_bandwidth_str(request_message.buf, (size_t*)(&(request_message.len)), bps); - - if(dont_fragment) - stun_attr_add(&request_message, STUN_ATTRIBUTE_DONT_FRAGMENT, NULL, 0); - - add_origin(&request_message); - - if(add_integrity(clnet_info, &request_message)<0) return -1; - - stun_attr_add_fingerprint_str(request_message.buf,(size_t*)&(request_message.len)); - - while (!allocate_sent) { - - int len = send_buffer(clnet_info, &request_message,0,0); - - if (len > 0) { - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "allocate sent\n"); - } - allocate_sent = 1; - } else { - perror("send"); - exit(1); - } - } - - ////////////<<==allocate send - - if(not_rare_event()) return 0; - - ////////allocate response==>> - { - int allocate_received = 0; - while (!allocate_received) { - - int len = recv_buffer(clnet_info, &response_message, 1, 0, NULL, &request_message); - - if (len > 0) { - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "allocate response received: \n"); - } - response_message.len = len; - int err_code = 0; - uint8_t err_msg[129]; - if (stun_is_success_response(&response_message)) { - allocate_received = 1; - allocate_finished = 1; - - if(clnet_info->nonce[0]) { - if(check_integrity(clnet_info, &response_message)<0) - return -1; - } - - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "success\n"); - } - { - int found = 0; - - stun_attr_ref sar = stun_attr_get_first(&response_message); - while (sar) { - - int attr_type = stun_attr_get_type(sar); - if(attr_type == STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS) { - - if (stun_attr_get_addr(&response_message, sar, relay_addr, NULL) < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: !!!: relay addr cannot be received (1)\n", - __FUNCTION__); - return -1; - } else { - if (verbose) { - ioa_addr raddr; - memcpy(&raddr, relay_addr,sizeof(ioa_addr)); - addr_debug_print(verbose, &raddr,"Received relay addr"); - } - - if(!addr_any(relay_addr)) { - if(relay_addr->ss.sa_family == AF_INET) { - if(default_address_family != STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6) { - found = 1; - addr_cpy(&(clnet_info->relay_addr),relay_addr); - break; - } - } - if(relay_addr->ss.sa_family == AF_INET6) { - if(default_address_family == STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6) { - found = 1; - addr_cpy(&(clnet_info->relay_addr),relay_addr); - break; - } - } - } - } - } - - sar = stun_attr_get_next(&response_message,sar); - } - - if(!found) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: !!!: relay addr cannot be received (2)\n", - __FUNCTION__); - return -1; - } - } - - stun_attr_ref rt_sar = stun_attr_get_first_by_type( - &response_message, STUN_ATTRIBUTE_RESERVATION_TOKEN); - uint64_t rtv = stun_attr_get_reservation_token_value(rt_sar); - current_reservation_token = rtv; - if (verbose) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: rtv=%llu\n", __FUNCTION__, (long long unsigned int)rtv); - - read_mobility_ticket(clnet_info, &response_message); - - } else if (stun_is_challenge_response_str(response_message.buf, (size_t)response_message.len, - &err_code,err_msg,sizeof(err_msg), - clnet_info->realm,clnet_info->nonce, - clnet_info->server_name, &(clnet_info->oauth))) { - goto beg_allocate; - } else if (stun_is_error_response(&response_message, &err_code,err_msg,sizeof(err_msg))) { - - allocate_received = 1; - - if(err_code == 300) { - - if(clnet_info->nonce[0]) { - if(check_integrity(clnet_info, &response_message)<0) - return -1; - } - - ioa_addr alternate_server; - if(stun_attr_get_first_addr(&response_message, STUN_ATTRIBUTE_ALTERNATE_SERVER, &alternate_server, NULL)==-1) { - //error - } else if(turn_addr && turn_port){ - addr_to_string_no_port(&alternate_server, (uint8_t*)turn_addr); - *turn_port = (uint16_t)addr_get_port(&alternate_server); - } - - } - - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "error %d (%s)\n", - err_code,(char*)err_msg); - if (err_code != 437) { - allocate_finished = 1; - current_reservation_token = 0; - return -1; - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "trying allocate again %d...\n", err_code); - sleep(1); - reopen_socket = 1; - } - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "unknown allocate response\n"); - /* Try again ? */ - } - } else { - perror("recv"); - exit(-1); - break; - } - } - } - } - ////////////<<== allocate response received - - if(rare_event()) return 0; - - if(!allocate_finished) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Cannot complete Allocation\n"); - exit(-1); - } - - allocate_rtcp = !allocate_rtcp; - - if (1) { - - af_cycle = 0; - - if(clnet_info->s_mobile_id[0]) { - - int fd = clnet_info->fd; - SSL* ssl = clnet_info->ssl; - - int close_now = (int)(turn_random()%2); - - if(close_now) { - int close_socket = (int)(turn_random()%2); - if(ssl && !close_socket) { - SSL_shutdown(ssl); - SSL_free(ssl); - fd = -1; - } else if(fd>=0) { - close(fd); - fd = -1; - ssl = NULL; - } - } - - app_ur_conn_info ci; - memcpy(&ci,clnet_info,sizeof(ci)); - ci.fd = -1; - ci.ssl = NULL; - clnet_info->fd = -1; - clnet_info->ssl = NULL; - //Reopen: - if(clnet_connect(addr_get_port(&(ci.remote_addr)), ci.rsaddr, - (unsigned char*)ci.ifname, ci.lsaddr, clnet_verbose, - clnet_info)<0) { - exit(-1); - } - - if(ssl) { - SSL_shutdown(ssl); - SSL_free(ssl); - } else if(fd>=0) { - close(fd); - } - } - - beg_refresh: - - if(af_cycle++>32) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "Cannot complete Refresh\n"); - exit(-1); - } - - //==>>refresh request, for an example only: - { - int refresh_sent = 0; - - stun_init_request(STUN_METHOD_REFRESH, &request_message); - uint32_t lt = htonl(UCLIENT_SESSION_LIFETIME); - stun_attr_add(&request_message, STUN_ATTRIBUTE_LIFETIME, (const char*) <, 4); - - if(clnet_info->s_mobile_id[0]) { - stun_attr_add(&request_message, STUN_ATTRIBUTE_MOBILITY_TICKET, (const char*)clnet_info->s_mobile_id, strlen(clnet_info->s_mobile_id)); - } - - if(dual_allocation && !mobility) { - int t = ((uint8_t)turn_random())%3; - if(t) { - uint8_t field[4]; - field[0] = (t==1) ? (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4 : (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; - field[1]=0; - field[2]=0; - field[3]=0; - stun_attr_add(&request_message, STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY, (const char*) field, 4); - } - } - - add_origin(&request_message); - - if(add_integrity(clnet_info, &request_message)<0) return -1; - - stun_attr_add_fingerprint_str(request_message.buf,(size_t*)&(request_message.len)); - - while (!refresh_sent) { - - int len = send_buffer(clnet_info, &request_message, 0,0); - - if (len > 0) { - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "refresh sent\n"); - } - refresh_sent = 1; - - if(clnet_info->s_mobile_id[0]) { - usleep(10000); - send_buffer(clnet_info, &request_message, 0,0); - } - } else { - perror("send"); - exit(1); - } - } - } - - if(not_rare_event()) return 0; - - ////////refresh response==>> - { - int refresh_received = 0; - while (!refresh_received) { - - int len = recv_buffer(clnet_info, &response_message, 1, 0, NULL, &request_message); - - if(clnet_info->s_mobile_id[0]) { - len = recv_buffer(clnet_info, &response_message, 1, 0, NULL, &request_message); - } - - if (len > 0) { - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "refresh response received: \n"); - } - response_message.len = len; - int err_code = 0; - uint8_t err_msg[129]; - if (stun_is_success_response(&response_message)) { - read_mobility_ticket(clnet_info, &response_message); - refresh_received = 1; - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "success\n"); - } - } else if (stun_is_challenge_response_str(response_message.buf, (size_t)response_message.len, - &err_code,err_msg,sizeof(err_msg), - clnet_info->realm,clnet_info->nonce, - clnet_info->server_name, &(clnet_info->oauth))) { - goto beg_refresh; - } else if (stun_is_error_response(&response_message, &err_code,err_msg,sizeof(err_msg))) { - refresh_received = 1; - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "error %d (%s)\n", - err_code,(char*)err_msg); - return -1; - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "unknown refresh response\n"); - /* Try again ? */ - } - } else { - perror("recv"); - exit(-1); - break; - } - } - } - } - - return 0; +int start_connection(uint16_t clnet_remote_port0, const char *remote_address0, const unsigned char *ifname, + const char *local_address, int verbose, app_ur_conn_info *clnet_info_probe, + app_ur_conn_info *clnet_info, uint16_t *chn, app_ur_conn_info *clnet_info_rtcp, + uint16_t *chn_rtcp) { + + ioa_addr relay_addr; + ioa_addr relay_addr_rtcp; + ioa_addr peer_addr_rtcp; + + addr_cpy(&peer_addr_rtcp, &peer_addr); + addr_set_port(&peer_addr_rtcp, addr_get_port(&peer_addr_rtcp) + 1); + + /* Probe: */ + + if (clnet_connect(clnet_remote_port0, remote_address0, ifname, local_address, verbose, clnet_info_probe) < 0) { + exit(-1); + } + + uint16_t clnet_remote_port = clnet_remote_port0; + char remote_address[1025]; + STRCPY(remote_address, remote_address0); + + clnet_allocate(verbose, clnet_info_probe, &relay_addr, default_address_family, remote_address, &clnet_remote_port); + + /* Real: */ + + *chn = 0; + if (chn_rtcp) + *chn_rtcp = 0; + + if (clnet_connect(clnet_remote_port, remote_address, ifname, local_address, verbose, clnet_info) < 0) { + exit(-1); + } + + if (!no_rtcp) { + if (clnet_connect(clnet_remote_port, remote_address, ifname, local_address, verbose, clnet_info_rtcp) < 0) { + exit(-1); + } + } + + int af = default_address_family ? default_address_family : get_allocate_address_family(&peer_addr); + if (clnet_allocate(verbose, clnet_info, &relay_addr, af, NULL, NULL) < 0) { + exit(-1); + } + + if (rare_event()) + return 0; + + if (!no_rtcp) { + af = default_address_family ? default_address_family : get_allocate_address_family(&peer_addr_rtcp); + if (clnet_allocate(verbose, clnet_info_rtcp, &relay_addr_rtcp, af, NULL, NULL) < 0) { + exit(-1); + } + if (rare_event()) + return 0; + } + + if (!dos) { + if (!do_not_use_channel) { + /* These multiple "channel bind" requests are here only because + * we are playing with the TURN server trying to screw it */ + if (turn_channel_bind(verbose, chn, clnet_info, &peer_addr_rtcp) < 0) { + exit(-1); + } + if (rare_event()) + return 0; + + if (turn_channel_bind(verbose, chn, clnet_info, &peer_addr_rtcp) < 0) { + exit(-1); + } + if (rare_event()) + return 0; + *chn = 0; + if (turn_channel_bind(verbose, chn, clnet_info, &peer_addr) < 0) { + exit(-1); + } + + if (rare_event()) + return 0; + if (turn_channel_bind(verbose, chn, clnet_info, &peer_addr) < 0) { + exit(-1); + } + if (rare_event()) + return 0; + + if (extra_requests) { + const char *sarbaddr = "164.156.178.190"; + if (turn_random() % 2 == 0) + sarbaddr = "2001::172"; + ioa_addr arbaddr; + make_ioa_addr((const uint8_t *)sarbaddr, 333, &arbaddr); + int i; + int maxi = (unsigned short)turn_random() % EXTRA_CREATE_PERMS; + for (i = 0; i < maxi; i++) { + uint16_t chni = 0; + int port = (unsigned short)turn_random(); + if (port < 1024) + port += 1024; + addr_set_port(&arbaddr, port); + uint8_t *u = (uint8_t *)&(arbaddr.s4.sin_addr); + u[(unsigned short)turn_random() % 4] = u[(unsigned short)turn_random() % 4] + 1; + // char sss[128]; + // addr_to_string(&arbaddr,(uint8_t*)sss); + // printf("%s: 111.111: %s\n",__FUNCTION__,sss); + turn_channel_bind(verbose, &chni, clnet_info, &arbaddr); + } + } + + if (!no_rtcp) { + if (turn_channel_bind(verbose, chn_rtcp, clnet_info_rtcp, &peer_addr_rtcp) < 0) { + exit(-1); + } + } + if (rare_event()) + return 0; + + if (extra_requests) { + const char *sarbaddr = "64.56.78.90"; + if (turn_random() % 2 == 0) + sarbaddr = "2001::172"; + ioa_addr arbaddr[EXTRA_CREATE_PERMS]; + make_ioa_addr((const uint8_t *)sarbaddr, 333, &arbaddr[0]); + int i; + int maxi = (unsigned short)turn_random() % EXTRA_CREATE_PERMS; + for (i = 0; i < maxi; i++) { + if (i > 0) + addr_cpy(&arbaddr[i], &arbaddr[0]); + addr_set_port(&arbaddr[i], (unsigned short)turn_random()); + uint8_t *u = (uint8_t *)&(arbaddr[i].s4.sin_addr); + u[(unsigned short)turn_random() % 4] = u[(unsigned short)turn_random() % 4] + 1; + // char sss[128]; + // addr_to_string(&arbaddr[i],(uint8_t*)sss); + // printf("%s: 111.111: %s\n",__FUNCTION__,sss); + } + turn_create_permission(verbose, clnet_info, arbaddr, maxi); + } + } else { + + int before = (turn_random() % 2 == 0); + + if (before) { + if (turn_create_permission(verbose, clnet_info, &peer_addr, 1) < 0) { + exit(-1); + } + if (rare_event()) + return 0; + if (turn_create_permission(verbose, clnet_info, &peer_addr_rtcp, 1) < 0) { + exit(-1); + } + if (rare_event()) + return 0; + } + + if (extra_requests) { + const char *sarbaddr = "64.56.78.90"; + if (turn_random() % 2 == 0) + sarbaddr = "2001::172"; + ioa_addr arbaddr[EXTRA_CREATE_PERMS]; + make_ioa_addr((const uint8_t *)sarbaddr, 333, &arbaddr[0]); + int i; + int maxi = (unsigned short)turn_random() % EXTRA_CREATE_PERMS; + for (i = 0; i < maxi; i++) { + if (i > 0) + addr_cpy(&arbaddr[i], &arbaddr[0]); + addr_set_port(&arbaddr[i], (unsigned short)turn_random()); + uint8_t *u = (uint8_t *)&(arbaddr[i].s4.sin_addr); + u[(unsigned short)turn_random() % 4] = u[(unsigned short)turn_random() % 4] + 1; + // char sss[128]; + // addr_to_string(&arbaddr,(uint8_t*)sss); + // printf("%s: 111.111: %s\n",__FUNCTION__,sss); + } + turn_create_permission(verbose, clnet_info, arbaddr, maxi); + } + + if (!before) { + if (turn_create_permission(verbose, clnet_info, &peer_addr, 1) < 0) { + exit(-1); + } + if (rare_event()) + return 0; + if (turn_create_permission(verbose, clnet_info, &peer_addr_rtcp, 1) < 0) { + exit(-1); + } + if (rare_event()) + return 0; + } + + if (!no_rtcp) { + if (turn_create_permission(verbose, clnet_info_rtcp, &peer_addr_rtcp, 1) < 0) { + exit(-1); + } + if (rare_event()) + return 0; + if (turn_create_permission(verbose, clnet_info_rtcp, &peer_addr, 1) < 0) { + exit(-1); + } + if (rare_event()) + return 0; + } + } + } + + addr_cpy(&(clnet_info->peer_addr), &peer_addr); + if (!no_rtcp) + addr_cpy(&(clnet_info_rtcp->peer_addr), &peer_addr_rtcp); + + return 0; } -static int turn_channel_bind(int verbose, uint16_t *chn, - app_ur_conn_info *clnet_info, ioa_addr *peer_addr) { - - stun_buffer request_message, response_message; - - beg_bind: - - { - int cb_sent = 0; - - if(negative_test) { - *chn = stun_set_channel_bind_request(&request_message, peer_addr, (uint16_t)turn_random()); - } else { - *chn = stun_set_channel_bind_request(&request_message, peer_addr, *chn); - } - - add_origin(&request_message); - - if(add_integrity(clnet_info, &request_message)<0) return -1; - - stun_attr_add_fingerprint_str(request_message.buf,(size_t*)&(request_message.len)); - - while (!cb_sent) { - - int len = send_buffer(clnet_info, &request_message, 0,0); - if (len > 0) { - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "channel bind sent\n"); - } - cb_sent = 1; - } else { - perror("send"); - exit(1); - } - } - } - - ////////////<<==channel bind send - - if(not_rare_event()) return 0; - - ////////channel bind response==>> - - { - int cb_received = 0; - while (!cb_received) { - - int len = recv_buffer(clnet_info, &response_message, 1, 0, NULL, &request_message); - if (len > 0) { - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "cb response received: \n"); - } - int err_code = 0; - uint8_t err_msg[129]; - if (stun_is_success_response(&response_message)) { - - cb_received = 1; - - if(clnet_info->nonce[0]) { - if(check_integrity(clnet_info, &response_message)<0) - return -1; - } - - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "success: 0x%x\n", - (int) (*chn)); - } - } else if (stun_is_challenge_response_str(response_message.buf, (size_t)response_message.len, - &err_code,err_msg,sizeof(err_msg), - clnet_info->realm,clnet_info->nonce, - clnet_info->server_name, &(clnet_info->oauth))) { - goto beg_bind; - } else if (stun_is_error_response(&response_message, &err_code,err_msg,sizeof(err_msg))) { - cb_received = 1; - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "channel bind: error %d (%s)\n", - err_code,(char*)err_msg); - return -1; - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "unknown channel bind response\n"); - /* Try again ? */ - } - } else { - perror("recv"); - exit(-1); - break; - } - } - } - - return 0; -} - -static int turn_create_permission(int verbose, app_ur_conn_info *clnet_info, - ioa_addr *peer_addr, int addrnum) -{ - - if(no_permissions || (addrnum<1)) - return 0; - - char saddr[129]="\0"; - if (verbose) { - addr_to_string(peer_addr,(uint8_t*)saddr); - } - - stun_buffer request_message, response_message; - - beg_cp: - - { - int cp_sent = 0; - - stun_init_request(STUN_METHOD_CREATE_PERMISSION, &request_message); - { - int addrindex; - for(addrindex=0;addrindex 0) { - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "create perm sent: %s\n",saddr); - } - cp_sent = 1; - } else { - perror("send"); - exit(1); - } - } - } - - ////////////<<==create permission send - - if(not_rare_event()) return 0; - - ////////create permission response==>> - - { - int cp_received = 0; - while (!cp_received) { - - int len = recv_buffer(clnet_info, &response_message, 1, 0, NULL, &request_message); - if (len > 0) { - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "cp response received: \n"); - } - int err_code = 0; - uint8_t err_msg[129]; - if (stun_is_success_response(&response_message)) { - - cp_received = 1; - - if(clnet_info->nonce[0]) { - if(check_integrity(clnet_info, &response_message)<0) - return -1; - } - - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "success\n"); - } - } else if (stun_is_challenge_response_str(response_message.buf, (size_t)response_message.len, - &err_code,err_msg,sizeof(err_msg), - clnet_info->realm,clnet_info->nonce, - clnet_info->server_name, &(clnet_info->oauth))) { - goto beg_cp; - } else if (stun_is_error_response(&response_message, &err_code,err_msg,sizeof(err_msg))) { - cp_received = 1; - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "create permission error %d (%s)\n", - err_code,(char*)err_msg); - return -1; - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "unknown create permission response\n"); - /* Try again ? */ - } - } else { - perror("recv"); - exit(-1); - } - } - } - - return 0; -} - -int start_connection(uint16_t clnet_remote_port0, - const char *remote_address0, - const unsigned char* ifname, const char *local_address, - int verbose, - app_ur_conn_info *clnet_info_probe, - app_ur_conn_info *clnet_info, - uint16_t *chn, - app_ur_conn_info *clnet_info_rtcp, - uint16_t *chn_rtcp) { - - ioa_addr relay_addr; - ioa_addr relay_addr_rtcp; - ioa_addr peer_addr_rtcp; - - addr_cpy(&peer_addr_rtcp,&peer_addr); - addr_set_port(&peer_addr_rtcp,addr_get_port(&peer_addr_rtcp)+1); - - /* Probe: */ - - if (clnet_connect(clnet_remote_port0, remote_address0, ifname, local_address, - verbose, clnet_info_probe) < 0) { - exit(-1); - } - - uint16_t clnet_remote_port = clnet_remote_port0; - char remote_address[1025]; - STRCPY(remote_address,remote_address0); - - clnet_allocate(verbose, clnet_info_probe, &relay_addr, default_address_family, remote_address, &clnet_remote_port); - - /* Real: */ - - *chn = 0; - if(chn_rtcp) *chn_rtcp=0; - - if (clnet_connect(clnet_remote_port, remote_address, ifname, local_address, - verbose, clnet_info) < 0) { - exit(-1); - } - - if(!no_rtcp) { - if (clnet_connect(clnet_remote_port, remote_address, ifname, local_address, - verbose, clnet_info_rtcp) < 0) { - exit(-1); - } - } - - int af = default_address_family ? default_address_family : get_allocate_address_family(&peer_addr); - if (clnet_allocate(verbose, clnet_info, &relay_addr, af, NULL,NULL) < 0) { - exit(-1); - } - - if(rare_event()) return 0; - - if(!no_rtcp) { - af = default_address_family ? default_address_family : get_allocate_address_family(&peer_addr_rtcp); - if (clnet_allocate(verbose, clnet_info_rtcp, &relay_addr_rtcp, af,NULL,NULL) < 0) { - exit(-1); - } - if(rare_event()) return 0; - } - - if (!dos) { - if (!do_not_use_channel) { - /* These multiple "channel bind" requests are here only because - * we are playing with the TURN server trying to screw it */ - if (turn_channel_bind(verbose, chn, clnet_info, &peer_addr_rtcp) - < 0) { - exit(-1); - } - if(rare_event()) return 0; - - if (turn_channel_bind(verbose, chn, clnet_info, &peer_addr_rtcp) - < 0) { - exit(-1); - } - if(rare_event()) return 0; - *chn = 0; - if (turn_channel_bind(verbose, chn, clnet_info, &peer_addr) < 0) { - exit(-1); - } - - if(rare_event()) return 0; - if (turn_channel_bind(verbose, chn, clnet_info, &peer_addr) < 0) { - exit(-1); - } - if(rare_event()) return 0; - - if(extra_requests) { - const char *sarbaddr = "164.156.178.190"; - if(turn_random() % 2 == 0) - sarbaddr = "2001::172"; - ioa_addr arbaddr; - make_ioa_addr((const uint8_t*)sarbaddr, 333, &arbaddr); - int i; - int maxi = (unsigned short)turn_random() % EXTRA_CREATE_PERMS; - for(i=0;i0) - addr_cpy(&arbaddr[i],&arbaddr[0]); - addr_set_port(&arbaddr[i], (unsigned short)turn_random()); - uint8_t *u=(uint8_t*)&(arbaddr[i].s4.sin_addr); - u[(unsigned short)turn_random()%4] = u[(unsigned short)turn_random()%4] + 1; - //char sss[128]; - //addr_to_string(&arbaddr[i],(uint8_t*)sss); - //printf("%s: 111.111: %s\n",__FUNCTION__,sss); - } - turn_create_permission(verbose, clnet_info, arbaddr, maxi); - } - } else { - - int before=(turn_random()%2 == 0); - - if(before) { - if (turn_create_permission(verbose, clnet_info, &peer_addr, 1) < 0) { - exit(-1); - } - if(rare_event()) return 0; - if (turn_create_permission(verbose, clnet_info, &peer_addr_rtcp, 1) - < 0) { - exit(-1); - } - if(rare_event()) return 0; - } - - if(extra_requests) { - const char *sarbaddr = "64.56.78.90"; - if(turn_random() % 2 == 0) - sarbaddr = "2001::172"; - ioa_addr arbaddr[EXTRA_CREATE_PERMS]; - make_ioa_addr((const uint8_t*)sarbaddr, 333, &arbaddr[0]); - int i; - int maxi = (unsigned short)turn_random() % EXTRA_CREATE_PERMS; - for(i=0;i0) - addr_cpy(&arbaddr[i],&arbaddr[0]); - addr_set_port(&arbaddr[i], (unsigned short)turn_random()); - uint8_t *u=(uint8_t*)&(arbaddr[i].s4.sin_addr); - u[(unsigned short)turn_random()%4] = u[(unsigned short)turn_random()%4] + 1; - //char sss[128]; - //addr_to_string(&arbaddr,(uint8_t*)sss); - //printf("%s: 111.111: %s\n",__FUNCTION__,sss); - } - turn_create_permission(verbose, clnet_info, arbaddr, maxi); - } - - if(!before) { - if (turn_create_permission(verbose, clnet_info, &peer_addr, 1) < 0) { - exit(-1); - } - if(rare_event()) return 0; - if (turn_create_permission(verbose, clnet_info, &peer_addr_rtcp, 1) - < 0) { - exit(-1); - } - if(rare_event()) return 0; - } - - if (!no_rtcp) { - if (turn_create_permission(verbose, clnet_info_rtcp, - &peer_addr_rtcp, 1) < 0) { - exit(-1); - } - if(rare_event()) return 0; - if (turn_create_permission(verbose, clnet_info_rtcp, &peer_addr, 1) - < 0) { - exit(-1); - } - if(rare_event()) return 0; - } - } - } - - addr_cpy(&(clnet_info->peer_addr), &peer_addr); - if(!no_rtcp) - addr_cpy(&(clnet_info_rtcp->peer_addr), &peer_addr_rtcp); - - return 0; -} - - -int start_c2c_connection(uint16_t clnet_remote_port0, - const char *remote_address0, const unsigned char* ifname, - const char *local_address, int verbose, - app_ur_conn_info *clnet_info_probe, - app_ur_conn_info *clnet_info1, - uint16_t *chn1, app_ur_conn_info *clnet_info1_rtcp, - uint16_t *chn1_rtcp, - app_ur_conn_info *clnet_info2, uint16_t *chn2, - app_ur_conn_info *clnet_info2_rtcp, - uint16_t *chn2_rtcp) { - - ioa_addr relay_addr1; - ioa_addr relay_addr1_rtcp; - - ioa_addr relay_addr2; - ioa_addr relay_addr2_rtcp; - - *chn1 = 0; - *chn2 = 0; - if(chn1_rtcp) *chn1_rtcp=0; - if(chn2_rtcp) *chn2_rtcp=0; - - /* Probe: */ - - if (clnet_connect(clnet_remote_port0, remote_address0, ifname, local_address, - verbose, clnet_info_probe) < 0) { - exit(-1); - } - - uint16_t clnet_remote_port = clnet_remote_port0; - char remote_address[1025]; - STRCPY(remote_address,remote_address0); - - clnet_allocate(verbose, clnet_info_probe, &relay_addr1, default_address_family, remote_address, &clnet_remote_port); - - if(rare_event()) return 0; - - /* Real: */ - - if (clnet_connect(clnet_remote_port, remote_address, ifname, local_address, - verbose, clnet_info1) < 0) { - exit(-1); - } - - if(!no_rtcp) - if (clnet_connect(clnet_remote_port, remote_address, ifname, local_address, - verbose, clnet_info1_rtcp) < 0) { - exit(-1); - } - - if(passive_tcp) - clnet_info2->is_peer = 1; - - if (clnet_connect(clnet_remote_port, remote_address, ifname, local_address, - verbose, clnet_info2) < 0) { - exit(-1); - } - - if(!no_rtcp) - if (clnet_connect(clnet_remote_port, remote_address, ifname, local_address, - verbose, clnet_info2_rtcp) < 0) { - exit(-1); - } - - if(!no_rtcp) { - - if (clnet_allocate(verbose, clnet_info1, &relay_addr1, default_address_family,NULL,NULL) - < 0) { - exit(-1); - } - - if(rare_event()) return 0; - - if (clnet_allocate(verbose, clnet_info1_rtcp, - &relay_addr1_rtcp, default_address_family,NULL,NULL) < 0) { - exit(-1); - } - - if(rare_event()) return 0; - - if (clnet_allocate(verbose, clnet_info2, &relay_addr2, default_address_family,NULL,NULL) - < 0) { - exit(-1); - } - - if(rare_event()) return 0; - - if (clnet_allocate(verbose, clnet_info2_rtcp, - &relay_addr2_rtcp, default_address_family,NULL,NULL) < 0) { - exit(-1); - } - - if(rare_event()) return 0; - } else { - - if (clnet_allocate(verbose, clnet_info1, &relay_addr1, default_address_family,NULL,NULL) - < 0) { - exit(-1); - } - if(rare_event()) return 0; - if(!(clnet_info2->is_peer)) { - if (clnet_allocate(verbose, clnet_info2, &relay_addr2, default_address_family,NULL,NULL) < 0) { - exit(-1); - } - if(rare_event()) return 0; - } else { - addr_cpy(&(clnet_info2->remote_addr),&relay_addr1); - addr_cpy(&relay_addr2,&(clnet_info2->local_addr)); - } - } - - if (!do_not_use_channel) { - if (turn_channel_bind(verbose, chn1, clnet_info1, &relay_addr2) < 0) { - exit(-1); - } - - if(extra_requests) { - const char *sarbaddr = "164.156.178.190"; - if(turn_random() % 2 == 0) - sarbaddr = "2001::172"; - ioa_addr arbaddr; - make_ioa_addr((const uint8_t*)sarbaddr, 333, &arbaddr); - int i; - int maxi = (unsigned short)turn_random() % EXTRA_CREATE_PERMS; - for(i=0;i0) - addr_cpy(&arbaddr[i],&arbaddr[0]); - addr_set_port(&arbaddr[i], (unsigned short)turn_random()); - uint8_t *u=(uint8_t*)&(arbaddr[i].s4.sin_addr); - u[(unsigned short)turn_random()%4] = u[(unsigned short)turn_random()%4] + 1; - //char sss[128]; - //addr_to_string(&arbaddr[i],(uint8_t*)sss); - //printf("%s: 111.111: %s\n",__FUNCTION__,sss); - } - turn_create_permission(verbose, clnet_info1, arbaddr, maxi); - } - - if(!no_rtcp) - if (turn_channel_bind(verbose, chn1_rtcp, clnet_info1_rtcp, - &relay_addr2_rtcp) < 0) { - exit(-1); - } - if(rare_event()) return 0; - if (turn_channel_bind(verbose, chn2, clnet_info2, &relay_addr1) < 0) { - exit(-1); - } - if(rare_event()) return 0; - if(!no_rtcp) - if (turn_channel_bind(verbose, chn2_rtcp, clnet_info2_rtcp, - &relay_addr1_rtcp) < 0) { - exit(-1); - } - if(rare_event()) return 0; - } else { - - if (turn_create_permission(verbose, clnet_info1, &relay_addr2, 1) < 0) { - exit(-1); - } - - if(extra_requests) { - const char *sarbaddr = "64.56.78.90"; - if(turn_random() % 2 == 0) - sarbaddr = "2001::172"; - ioa_addr arbaddr; - make_ioa_addr((const uint8_t*)sarbaddr, 333, &arbaddr); - int i; - int maxi = (unsigned short)turn_random() % EXTRA_CREATE_PERMS; - for(i=0;iis_peer)) { - if (turn_create_permission(verbose, clnet_info2, &relay_addr1, 1) < 0) { - exit(-1); - } - if(rare_event()) return 0; - } - if (!no_rtcp) - if (turn_create_permission(verbose, clnet_info2_rtcp, &relay_addr1_rtcp, 1) < 0) { - exit(-1); - } - if(rare_event()) return 0; - } - - addr_cpy(&(clnet_info1->peer_addr), &relay_addr2); - if(!no_rtcp) - addr_cpy(&(clnet_info1_rtcp->peer_addr), &relay_addr2_rtcp); - addr_cpy(&(clnet_info2->peer_addr), &relay_addr1); - if(!no_rtcp) - addr_cpy(&(clnet_info2_rtcp->peer_addr), &relay_addr1_rtcp); - - return 0; +int start_c2c_connection(uint16_t clnet_remote_port0, const char *remote_address0, const unsigned char *ifname, + const char *local_address, int verbose, app_ur_conn_info *clnet_info_probe, + app_ur_conn_info *clnet_info1, uint16_t *chn1, app_ur_conn_info *clnet_info1_rtcp, + uint16_t *chn1_rtcp, app_ur_conn_info *clnet_info2, uint16_t *chn2, + app_ur_conn_info *clnet_info2_rtcp, uint16_t *chn2_rtcp) { + + ioa_addr relay_addr1; + ioa_addr relay_addr1_rtcp; + + ioa_addr relay_addr2; + ioa_addr relay_addr2_rtcp; + + *chn1 = 0; + *chn2 = 0; + if (chn1_rtcp) + *chn1_rtcp = 0; + if (chn2_rtcp) + *chn2_rtcp = 0; + + /* Probe: */ + + if (clnet_connect(clnet_remote_port0, remote_address0, ifname, local_address, verbose, clnet_info_probe) < 0) { + exit(-1); + } + + uint16_t clnet_remote_port = clnet_remote_port0; + char remote_address[1025]; + STRCPY(remote_address, remote_address0); + + clnet_allocate(verbose, clnet_info_probe, &relay_addr1, default_address_family, remote_address, &clnet_remote_port); + + if (rare_event()) + return 0; + + /* Real: */ + + if (clnet_connect(clnet_remote_port, remote_address, ifname, local_address, verbose, clnet_info1) < 0) { + exit(-1); + } + + if (!no_rtcp) + if (clnet_connect(clnet_remote_port, remote_address, ifname, local_address, verbose, clnet_info1_rtcp) < 0) { + exit(-1); + } + + if (passive_tcp) + clnet_info2->is_peer = 1; + + if (clnet_connect(clnet_remote_port, remote_address, ifname, local_address, verbose, clnet_info2) < 0) { + exit(-1); + } + + if (!no_rtcp) + if (clnet_connect(clnet_remote_port, remote_address, ifname, local_address, verbose, clnet_info2_rtcp) < 0) { + exit(-1); + } + + if (!no_rtcp) { + + if (clnet_allocate(verbose, clnet_info1, &relay_addr1, default_address_family, NULL, NULL) < 0) { + exit(-1); + } + + if (rare_event()) + return 0; + + if (clnet_allocate(verbose, clnet_info1_rtcp, &relay_addr1_rtcp, default_address_family, NULL, NULL) < 0) { + exit(-1); + } + + if (rare_event()) + return 0; + + if (clnet_allocate(verbose, clnet_info2, &relay_addr2, default_address_family, NULL, NULL) < 0) { + exit(-1); + } + + if (rare_event()) + return 0; + + if (clnet_allocate(verbose, clnet_info2_rtcp, &relay_addr2_rtcp, default_address_family, NULL, NULL) < 0) { + exit(-1); + } + + if (rare_event()) + return 0; + } else { + + if (clnet_allocate(verbose, clnet_info1, &relay_addr1, default_address_family, NULL, NULL) < 0) { + exit(-1); + } + if (rare_event()) + return 0; + if (!(clnet_info2->is_peer)) { + if (clnet_allocate(verbose, clnet_info2, &relay_addr2, default_address_family, NULL, NULL) < 0) { + exit(-1); + } + if (rare_event()) + return 0; + } else { + addr_cpy(&(clnet_info2->remote_addr), &relay_addr1); + addr_cpy(&relay_addr2, &(clnet_info2->local_addr)); + } + } + + if (!do_not_use_channel) { + if (turn_channel_bind(verbose, chn1, clnet_info1, &relay_addr2) < 0) { + exit(-1); + } + + if (extra_requests) { + const char *sarbaddr = "164.156.178.190"; + if (turn_random() % 2 == 0) + sarbaddr = "2001::172"; + ioa_addr arbaddr; + make_ioa_addr((const uint8_t *)sarbaddr, 333, &arbaddr); + int i; + int maxi = (unsigned short)turn_random() % EXTRA_CREATE_PERMS; + for (i = 0; i < maxi; i++) { + uint16_t chni = 0; + int port = (unsigned short)turn_random(); + if (port < 1024) + port += 1024; + addr_set_port(&arbaddr, port); + uint8_t *u = (uint8_t *)&(arbaddr.s4.sin_addr); + u[(unsigned short)turn_random() % 4] = u[(unsigned short)turn_random() % 4] + 1; + // char sss[128]; + // addr_to_string(&arbaddr,(uint8_t*)sss); + // printf("%s: 111.111: %s\n",__FUNCTION__,sss); + turn_channel_bind(verbose, &chni, clnet_info1, &arbaddr); + } + } + + if (rare_event()) + return 0; + + if (extra_requests) { + const char *sarbaddr = "64.56.78.90"; + if (turn_random() % 2 == 0) + sarbaddr = "2001::172"; + ioa_addr arbaddr[EXTRA_CREATE_PERMS]; + make_ioa_addr((const uint8_t *)sarbaddr, 333, &arbaddr[0]); + int i; + int maxi = (unsigned short)turn_random() % EXTRA_CREATE_PERMS; + for (i = 0; i < maxi; i++) { + if (i > 0) + addr_cpy(&arbaddr[i], &arbaddr[0]); + addr_set_port(&arbaddr[i], (unsigned short)turn_random()); + uint8_t *u = (uint8_t *)&(arbaddr[i].s4.sin_addr); + u[(unsigned short)turn_random() % 4] = u[(unsigned short)turn_random() % 4] + 1; + // char sss[128]; + // addr_to_string(&arbaddr[i],(uint8_t*)sss); + // printf("%s: 111.111: %s\n",__FUNCTION__,sss); + } + turn_create_permission(verbose, clnet_info1, arbaddr, maxi); + } + + if (!no_rtcp) + if (turn_channel_bind(verbose, chn1_rtcp, clnet_info1_rtcp, &relay_addr2_rtcp) < 0) { + exit(-1); + } + if (rare_event()) + return 0; + if (turn_channel_bind(verbose, chn2, clnet_info2, &relay_addr1) < 0) { + exit(-1); + } + if (rare_event()) + return 0; + if (!no_rtcp) + if (turn_channel_bind(verbose, chn2_rtcp, clnet_info2_rtcp, &relay_addr1_rtcp) < 0) { + exit(-1); + } + if (rare_event()) + return 0; + } else { + + if (turn_create_permission(verbose, clnet_info1, &relay_addr2, 1) < 0) { + exit(-1); + } + + if (extra_requests) { + const char *sarbaddr = "64.56.78.90"; + if (turn_random() % 2 == 0) + sarbaddr = "2001::172"; + ioa_addr arbaddr; + make_ioa_addr((const uint8_t *)sarbaddr, 333, &arbaddr); + int i; + int maxi = (unsigned short)turn_random() % EXTRA_CREATE_PERMS; + for (i = 0; i < maxi; i++) { + addr_set_port(&arbaddr, (unsigned short)turn_random()); + uint8_t *u = (uint8_t *)&(arbaddr.s4.sin_addr); + u[(unsigned short)turn_random() % 4] = u[(unsigned short)turn_random() % 4] + 1; + // char sss[128]; + // addr_to_string(&arbaddr,(uint8_t*)sss); + // printf("%s: 111.111: %s\n",__FUNCTION__,sss); + turn_create_permission(verbose, clnet_info1, &arbaddr, 1); + } + } + + if (rare_event()) + return 0; + if (!no_rtcp) + if (turn_create_permission(verbose, clnet_info1_rtcp, &relay_addr2_rtcp, 1) < 0) { + exit(-1); + } + if (rare_event()) + return 0; + if (!(clnet_info2->is_peer)) { + if (turn_create_permission(verbose, clnet_info2, &relay_addr1, 1) < 0) { + exit(-1); + } + if (rare_event()) + return 0; + } + if (!no_rtcp) + if (turn_create_permission(verbose, clnet_info2_rtcp, &relay_addr1_rtcp, 1) < 0) { + exit(-1); + } + if (rare_event()) + return 0; + } + + addr_cpy(&(clnet_info1->peer_addr), &relay_addr2); + if (!no_rtcp) + addr_cpy(&(clnet_info1_rtcp->peer_addr), &relay_addr2_rtcp); + addr_cpy(&(clnet_info2->peer_addr), &relay_addr1); + if (!no_rtcp) + addr_cpy(&(clnet_info2_rtcp->peer_addr), &relay_addr1_rtcp); + + return 0; } //////////// RFC 6062 /////////////// int turn_tcp_connect(int verbose, app_ur_conn_info *clnet_info, ioa_addr *peer_addr) { - { - int cp_sent = 0; + { + int cp_sent = 0; - stun_buffer message; + stun_buffer message; - stun_init_request(STUN_METHOD_CONNECT, &message); - stun_attr_add_addr(&message, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, peer_addr); + stun_init_request(STUN_METHOD_CONNECT, &message); + stun_attr_add_addr(&message, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, peer_addr); - add_origin(&message); + add_origin(&message); - if(add_integrity(clnet_info, &message)<0) return -1; + if (add_integrity(clnet_info, &message) < 0) + return -1; - stun_attr_add_fingerprint_str(message.buf,(size_t*)&(message.len)); + stun_attr_add_fingerprint_str(message.buf, (size_t *)&(message.len)); - while (!cp_sent) { + while (!cp_sent) { - int len = send_buffer(clnet_info, &message, 0,0); + int len = send_buffer(clnet_info, &message, 0, 0); - if (len > 0) { - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "tcp connect sent\n"); - } - cp_sent = 1; - } else { - perror("send"); - exit(1); - } - } - } + if (len > 0) { + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "tcp connect sent\n"); + } + cp_sent = 1; + } else { + perror("send"); + exit(1); + } + } + } - ////////////<<==connect send + ////////////<<==connect send - return 0; + return 0; } static int turn_tcp_connection_bind(int verbose, app_ur_conn_info *clnet_info, app_tcp_conn_info *atc, int errorOK) { - stun_buffer request_message, response_message; + stun_buffer request_message, response_message; - beg_cb: +beg_cb : - { - int cb_sent = 0; +{ + int cb_sent = 0; - uint32_t cid = atc->cid; + uint32_t cid = atc->cid; - stun_init_request(STUN_METHOD_CONNECTION_BIND, &request_message); + stun_init_request(STUN_METHOD_CONNECTION_BIND, &request_message); - stun_attr_add(&request_message, STUN_ATTRIBUTE_CONNECTION_ID, (const char*)&cid,4); + stun_attr_add(&request_message, STUN_ATTRIBUTE_CONNECTION_ID, (const char *)&cid, 4); - add_origin(&request_message); + add_origin(&request_message); - if(add_integrity(clnet_info, &request_message)<0) return -1; + if (add_integrity(clnet_info, &request_message) < 0) + return -1; - stun_attr_add_fingerprint_str(request_message.buf,(size_t*)&(request_message.len)); + stun_attr_add_fingerprint_str(request_message.buf, (size_t *)&(request_message.len)); - while (!cb_sent) { + while (!cb_sent) { - int len = send_buffer(clnet_info, &request_message, 1, atc); + int len = send_buffer(clnet_info, &request_message, 1, atc); - if (len > 0) { - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "connection bind sent\n"); - } - cb_sent = 1; - } else { - if(errorOK) - return 0; - perror("send"); - exit(1); - } - } - } - - ////////////<<==connection bind send - - if(not_rare_event()) return 0; - - ////////connection bind response==>> - - { - int cb_received = 0; - while (!cb_received) { - - int len = recv_buffer(clnet_info, &response_message, 1, 1, atc, &request_message); - if (len > 0) { - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "connect bind response received: \n"); - } - int err_code = 0; - uint8_t err_msg[129]; - if (stun_is_success_response(&response_message)) { - - if(clnet_info->nonce[0]) { - if(check_integrity(clnet_info, &response_message)<0) - return -1; - } - - if(stun_get_method(&response_message)!=STUN_METHOD_CONNECTION_BIND) - continue; - cb_received = 1; - if (verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "success\n"); - } - atc->tcp_data_bound = 1; - } else if (stun_is_challenge_response_str(response_message.buf, (size_t)response_message.len, - &err_code,err_msg,sizeof(err_msg), - clnet_info->realm,clnet_info->nonce, - clnet_info->server_name, &(clnet_info->oauth))) { - goto beg_cb; - } else if (stun_is_error_response(&response_message, &err_code,err_msg,sizeof(err_msg))) { - cb_received = 1; - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "connection bind error %d (%s)\n", - err_code,(char*)err_msg); - return -1; - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "unknown connection bind response\n"); - /* Try again ? */ - } - } else { - if(errorOK) - return 0; - perror("recv"); - exit(-1); - } - } - } - - return 0; + if (len > 0) { + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "connection bind sent\n"); + } + cb_sent = 1; + } else { + if (errorOK) + return 0; + perror("send"); + exit(1); + } + } } -void tcp_data_connect(app_ur_session *elem, uint32_t cid) -{ - int clnet_fd; - int connect_cycle = 0; + ////////////<<==connection bind send - again: + if (not_rare_event()) + return 0; - clnet_fd = socket(elem->pinfo.remote_addr.ss.sa_family, CLIENT_STREAM_SOCKET_TYPE, CLIENT_STREAM_SOCKET_PROTOCOL); - if (clnet_fd < 0) { - perror("socket"); - exit(-1); - } + ////////connection bind response==>> - if (sock_bind_to_device(clnet_fd, client_ifname) < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "Cannot bind client socket to device %s\n", client_ifname); - } - set_sock_buf_size(clnet_fd, (UR_CLIENT_SOCK_BUF_SIZE<<2)); + { + int cb_received = 0; + while (!cb_received) { - ++elem->pinfo.tcp_conn_number; - int i = (int)(elem->pinfo.tcp_conn_number-1); - elem->pinfo.tcp_conn=(app_tcp_conn_info**)realloc(elem->pinfo.tcp_conn,elem->pinfo.tcp_conn_number*sizeof(app_tcp_conn_info*)); - elem->pinfo.tcp_conn[i]=(app_tcp_conn_info*)calloc(sizeof(app_tcp_conn_info), 1); + int len = recv_buffer(clnet_info, &response_message, 1, 1, atc, &request_message); + if (len > 0) { + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "connect bind response received: \n"); + } + int err_code = 0; + uint8_t err_msg[129]; + if (stun_is_success_response(&response_message)) { - elem->pinfo.tcp_conn[i]->tcp_data_fd = clnet_fd; - elem->pinfo.tcp_conn[i]->cid = cid; + if (clnet_info->nonce[0]) { + if (check_integrity(clnet_info, &response_message) < 0) + return -1; + } - addr_cpy(&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr),&(elem->pinfo.local_addr)); + if (stun_get_method(&response_message) != STUN_METHOD_CONNECTION_BIND) + continue; + cb_received = 1; + if (verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "success\n"); + } + atc->tcp_data_bound = 1; + } else if (stun_is_challenge_response_str(response_message.buf, (size_t)response_message.len, &err_code, + err_msg, sizeof(err_msg), clnet_info->realm, clnet_info->nonce, + clnet_info->server_name, &(clnet_info->oauth))) { + goto beg_cb; + } else if (stun_is_error_response(&response_message, &err_code, err_msg, sizeof(err_msg))) { + cb_received = 1; + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "connection bind error %d (%s)\n", err_code, (char *)err_msg); + return -1; + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "unknown connection bind response\n"); + /* Try again ? */ + } + } else { + if (errorOK) + return 0; + perror("recv"); + exit(-1); + } + } + } - addr_set_port(&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr),0); + return 0; +} - addr_bind(clnet_fd, &(elem->pinfo.tcp_conn[i]->tcp_data_local_addr), 1, 1, TCP_SOCKET); +void tcp_data_connect(app_ur_session *elem, uint32_t cid) { + int clnet_fd; + int connect_cycle = 0; - addr_get_from_sock(clnet_fd,&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr)); +again: - { - int cycle = 0; - while(cycle++<1024) { - int err = 0; - if (addr_connect(clnet_fd, &(elem->pinfo.remote_addr),&err) < 0) { - if(err == EADDRINUSE) { - socket_closesocket(clnet_fd); - clnet_fd = socket(elem->pinfo.remote_addr.ss.sa_family, CLIENT_STREAM_SOCKET_TYPE, CLIENT_STREAM_SOCKET_PROTOCOL); - if (clnet_fd < 0) { - perror("socket"); - exit(-1); - } - if (sock_bind_to_device(clnet_fd, client_ifname) < 0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "Cannot bind client socket to device %s\n", client_ifname); - } - set_sock_buf_size(clnet_fd, UR_CLIENT_SOCK_BUF_SIZE<<2); + clnet_fd = socket(elem->pinfo.remote_addr.ss.sa_family, CLIENT_STREAM_SOCKET_TYPE, CLIENT_STREAM_SOCKET_PROTOCOL); + if (clnet_fd < 0) { + perror("socket"); + exit(-1); + } - elem->pinfo.tcp_conn[i]->tcp_data_fd = clnet_fd; + if (sock_bind_to_device(clnet_fd, client_ifname) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Cannot bind client socket to device %s\n", client_ifname); + } + set_sock_buf_size(clnet_fd, (UR_CLIENT_SOCK_BUF_SIZE << 2)); - addr_cpy(&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr),&(elem->pinfo.local_addr)); + ++elem->pinfo.tcp_conn_number; + int i = (int)(elem->pinfo.tcp_conn_number - 1); + elem->pinfo.tcp_conn = + (app_tcp_conn_info **)realloc(elem->pinfo.tcp_conn, elem->pinfo.tcp_conn_number * sizeof(app_tcp_conn_info *)); + elem->pinfo.tcp_conn[i] = (app_tcp_conn_info *)calloc(sizeof(app_tcp_conn_info), 1); - addr_set_port(&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr),0); + elem->pinfo.tcp_conn[i]->tcp_data_fd = clnet_fd; + elem->pinfo.tcp_conn[i]->cid = cid; - addr_bind(clnet_fd, &(elem->pinfo.tcp_conn[i]->tcp_data_local_addr),1,1,TCP_SOCKET); + addr_cpy(&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr), &(elem->pinfo.local_addr)); - addr_get_from_sock(clnet_fd,&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr)); + addr_set_port(&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr), 0); - continue; + addr_bind(clnet_fd, &(elem->pinfo.tcp_conn[i]->tcp_data_local_addr), 1, 1, TCP_SOCKET); - } else { - perror("connect"); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: cannot connect to remote addr\n", __FUNCTION__); - exit(-1); - } - } else { - break; - } - } - } + addr_get_from_sock(clnet_fd, &(elem->pinfo.tcp_conn[i]->tcp_data_local_addr)); - if(use_secure) { - int try_again = 0; - elem->pinfo.tcp_conn[i]->tcp_data_ssl = tls_connect(elem->pinfo.tcp_conn[i]->tcp_data_fd, &(elem->pinfo.remote_addr),&try_again, connect_cycle++); - if(!(elem->pinfo.tcp_conn[i]->tcp_data_ssl)) { - if(try_again) { - --elem->pinfo.tcp_conn_number; - goto again; - } - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: cannot SSL connect to remote addr\n", __FUNCTION__); - exit(-1); - } - } + { + int cycle = 0; + while (cycle++ < 1024) { + int err = 0; + if (addr_connect(clnet_fd, &(elem->pinfo.remote_addr), &err) < 0) { + if (err == EADDRINUSE) { + socket_closesocket(clnet_fd); + clnet_fd = + socket(elem->pinfo.remote_addr.ss.sa_family, CLIENT_STREAM_SOCKET_TYPE, CLIENT_STREAM_SOCKET_PROTOCOL); + if (clnet_fd < 0) { + perror("socket"); + exit(-1); + } + if (sock_bind_to_device(clnet_fd, client_ifname) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Cannot bind client socket to device %s\n", client_ifname); + } + set_sock_buf_size(clnet_fd, UR_CLIENT_SOCK_BUF_SIZE << 2); - if(turn_tcp_connection_bind(clnet_verbose, &(elem->pinfo), elem->pinfo.tcp_conn[i],0)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: cannot BIND to tcp connection\n", __FUNCTION__); - } else { + elem->pinfo.tcp_conn[i]->tcp_data_fd = clnet_fd; - socket_set_nonblocking(clnet_fd); + addr_cpy(&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr), &(elem->pinfo.local_addr)); - struct event* ev = event_new(client_event_base,clnet_fd, - EV_READ|EV_PERSIST,client_input_handler, - elem); + addr_set_port(&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr), 0); - event_add(ev,NULL); + addr_bind(clnet_fd, &(elem->pinfo.tcp_conn[i]->tcp_data_local_addr), 1, 1, TCP_SOCKET); - elem->input_tcp_data_ev = ev; + addr_get_from_sock(clnet_fd, &(elem->pinfo.tcp_conn[i]->tcp_data_local_addr)); - addr_debug_print(clnet_verbose, &(elem->pinfo.remote_addr), "TCP data network connected to"); - } + continue; + + } else { + perror("connect"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: cannot connect to remote addr\n", __FUNCTION__); + exit(-1); + } + } else { + break; + } + } + } + + if (use_secure) { + int try_again = 0; + elem->pinfo.tcp_conn[i]->tcp_data_ssl = + tls_connect(elem->pinfo.tcp_conn[i]->tcp_data_fd, &(elem->pinfo.remote_addr), &try_again, connect_cycle++); + if (!(elem->pinfo.tcp_conn[i]->tcp_data_ssl)) { + if (try_again) { + --elem->pinfo.tcp_conn_number; + goto again; + } + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: cannot SSL connect to remote addr\n", __FUNCTION__); + exit(-1); + } + } + + if (turn_tcp_connection_bind(clnet_verbose, &(elem->pinfo), elem->pinfo.tcp_conn[i], 0) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: cannot BIND to tcp connection\n", __FUNCTION__); + } else { + + socket_set_nonblocking(clnet_fd); + + struct event *ev = event_new(client_event_base, clnet_fd, EV_READ | EV_PERSIST, client_input_handler, elem); + + event_add(ev, NULL); + + elem->input_tcp_data_ev = ev; + + addr_debug_print(clnet_verbose, &(elem->pinfo.remote_addr), "TCP data network connected to"); + } } ///////////////////////////////////////////////// diff --git a/src/apps/uclient/startuclient.h b/src/apps/uclient/startuclient.h index f04e00d..2265d37 100644 --- a/src/apps/uclient/startuclient.h +++ b/src/apps/uclient/startuclient.h @@ -45,29 +45,16 @@ int not_rare_event(void); void add_origin(stun_buffer *message); -int start_c2c_connection(uint16_t clnet_remote_port, - const char *remote_address, - const unsigned char* ifname, const char *local_address, - int verbose, - app_ur_conn_info *clnet_info_probe, - app_ur_conn_info *clnet_info1, - uint16_t *chn1, - app_ur_conn_info *clnet_info1_rtcp, - uint16_t *chn1_rtcp, - app_ur_conn_info *clnet_info2, - uint16_t *chn2, - app_ur_conn_info *clnet_info2_rtcp, - uint16_t *chn2_rtcp); +int start_c2c_connection(uint16_t clnet_remote_port, const char *remote_address, const unsigned char *ifname, + const char *local_address, int verbose, app_ur_conn_info *clnet_info_probe, + app_ur_conn_info *clnet_info1, uint16_t *chn1, app_ur_conn_info *clnet_info1_rtcp, + uint16_t *chn1_rtcp, app_ur_conn_info *clnet_info2, uint16_t *chn2, + app_ur_conn_info *clnet_info2_rtcp, uint16_t *chn2_rtcp); -int start_connection(uint16_t clnet_remote_port, - const char *remote_address, - const unsigned char* ifname, const char *local_address, - int verbose, - app_ur_conn_info *clnet_info_probe, - app_ur_conn_info *clnet_info, - uint16_t *chn, - app_ur_conn_info *clnet_info_rtcp, - uint16_t *chn_rtcp); +int start_connection(uint16_t clnet_remote_port, const char *remote_address, const unsigned char *ifname, + const char *local_address, int verbose, app_ur_conn_info *clnet_info_probe, + app_ur_conn_info *clnet_info, uint16_t *chn, app_ur_conn_info *clnet_info_rtcp, + uint16_t *chn_rtcp); int turn_tcp_connect(int verbose, app_ur_conn_info *clnet_info, ioa_addr *peer_addr); @@ -84,4 +71,3 @@ int read_mobility_ticket(app_ur_conn_info *clnet_info, stun_buffer *message); #endif #endif //__STARTCLIENT_TURN__ - diff --git a/src/apps/uclient/uclient.c b/src/apps/uclient/uclient.c index 3e49786..3c83c0a 100644 --- a/src/apps/uclient/uclient.c +++ b/src/apps/uclient/uclient.c @@ -28,31 +28,31 @@ * SUCH DAMAGE. */ -#include "apputils.h" #include "uclient.h" -#include "startuclient.h" +#include "apputils.h" #include "ns_turn_utils.h" #include "session.h" +#include "startuclient.h" #if defined(__linux__) -#include #include +#include #endif #include -static int verbose_packets=0; +static int verbose_packets = 0; static size_t current_clients_number = 0; -static int start_full_timer=0; -static uint32_t tot_messages=0; -static uint32_t tot_send_messages=0; +static int start_full_timer = 0; +static uint32_t tot_messages = 0; +static uint32_t tot_send_messages = 0; static uint64_t tot_send_bytes = 0; -static uint32_t tot_recv_messages=0; +static uint32_t tot_recv_messages = 0; static uint64_t tot_recv_bytes = 0; static uint64_t tot_send_dropped = 0; -struct event_base* client_event_base=NULL; +struct event_base *client_event_base = NULL; static int client_write(app_ur_session *elem); static int client_shutdown(app_ur_session *elem); @@ -60,12 +60,12 @@ static int client_shutdown(app_ur_session *elem); static uint64_t current_time = 0; static uint64_t current_mstime = 0; -static char buffer_to_send[65536]="\0"; +static char buffer_to_send[65536] = "\0"; static int total_clients = 0; /* Patch for unlimited number of clients provided by ucudbm@gmail.com */ -static app_ur_session** elems = NULL; +static app_ur_session **elems = NULL; #define SLEEP_INTERVAL (234) @@ -73,9 +73,7 @@ static app_ur_session** elems = NULL; int RTP_PACKET_INTERVAL = 20; -static inline int64_t time_minus(uint64_t t1, uint64_t t2) { - return ( (int64_t)t1 - (int64_t)t2 ); -} +static inline int64_t time_minus(uint64_t t1, uint64_t t2) { return ((int64_t)t1 - (int64_t)t2); } static uint64_t total_loss = 0; static uint64_t total_jitter = 0; @@ -86,1639 +84,1570 @@ static uint64_t max_latency = 0; static uint64_t min_jitter = 0xFFFFFFFF; static uint64_t max_jitter = 0; - static int show_statistics = 0; /////////////////////////////////////////////////////////////////////////////// static void __turn_getMSTime(void) { static uint64_t start_sec = 0; - struct timespec tp={0,0}; + struct timespec tp = {0, 0}; #if defined(CLOCK_REALTIME) clock_gettime(CLOCK_REALTIME, &tp); #else tp.tv_sec = time(NULL); #endif - if(!start_sec) + if (!start_sec) start_sec = tp.tv_sec; - if(current_time != (uint64_t)((uint64_t)(tp.tv_sec)-start_sec)) + if (current_time != (uint64_t)((uint64_t)(tp.tv_sec) - start_sec)) show_statistics = 1; - current_time = (uint64_t)((uint64_t)(tp.tv_sec)-start_sec); - current_mstime = (uint64_t)((current_time * 1000) + (tp.tv_nsec/1000000)); + current_time = (uint64_t)((uint64_t)(tp.tv_sec) - start_sec); + current_mstime = (uint64_t)((current_time * 1000) + (tp.tv_nsec / 1000000)); } //////////////////////////////////////////////////////////////////// -static int refresh_channel(app_ur_session* elem, uint16_t method, uint32_t lt); +static int refresh_channel(app_ur_session *elem, uint16_t method, uint32_t lt); //////////////////////// SS //////////////////////////////////////// -static app_ur_session* init_app_session(app_ur_session *ss) { - if(ss) { +static app_ur_session *init_app_session(app_ur_session *ss) { + if (ss) { memset(ss, 0, sizeof(app_ur_session)); - ss->pinfo.fd=-1; + ss->pinfo.fd = -1; } return ss; } -static app_ur_session* create_new_ss(void) -{ - ++current_clients_number; - return init_app_session((app_ur_session*) malloc(sizeof(app_ur_session))); +static app_ur_session *create_new_ss(void) { + ++current_clients_number; + return init_app_session((app_ur_session *)malloc(sizeof(app_ur_session))); } -static void uc_delete_session_elem_data(app_ur_session* cdi) { - if(cdi) { +static void uc_delete_session_elem_data(app_ur_session *cdi) { + if (cdi) { EVENT_DEL(cdi->input_ev); EVENT_DEL(cdi->input_tcp_data_ev); - if(cdi->pinfo.tcp_conn) { + if (cdi->pinfo.tcp_conn) { int i = 0; - for(i=0;i<(int)(cdi->pinfo.tcp_conn_number);++i) { - if(cdi->pinfo.tcp_conn[i]) { - if(cdi->pinfo.tcp_conn[i]->tcp_data_ssl && !(cdi->pinfo.broken)) { - if(!(SSL_get_shutdown(cdi->pinfo.tcp_conn[i]->tcp_data_ssl) & SSL_SENT_SHUTDOWN)) { - SSL_set_shutdown(cdi->pinfo.tcp_conn[i]->tcp_data_ssl, SSL_RECEIVED_SHUTDOWN); - SSL_shutdown(cdi->pinfo.tcp_conn[i]->tcp_data_ssl); - } - if(cdi->pinfo.tcp_conn[i]->tcp_data_ssl) { - SSL_free(cdi->pinfo.tcp_conn[i]->tcp_data_ssl); - } - if(cdi->pinfo.tcp_conn[i]->tcp_data_fd>=0) { - socket_closesocket(cdi->pinfo.tcp_conn[i]->tcp_data_fd); - cdi->pinfo.tcp_conn[i]->tcp_data_fd=-1; - } - free(cdi->pinfo.tcp_conn[i]); - cdi->pinfo.tcp_conn[i]=NULL; - } - } + for (i = 0; i < (int)(cdi->pinfo.tcp_conn_number); ++i) { + if (cdi->pinfo.tcp_conn[i]) { + if (cdi->pinfo.tcp_conn[i]->tcp_data_ssl && !(cdi->pinfo.broken)) { + if (!(SSL_get_shutdown(cdi->pinfo.tcp_conn[i]->tcp_data_ssl) & SSL_SENT_SHUTDOWN)) { + SSL_set_shutdown(cdi->pinfo.tcp_conn[i]->tcp_data_ssl, SSL_RECEIVED_SHUTDOWN); + SSL_shutdown(cdi->pinfo.tcp_conn[i]->tcp_data_ssl); + } + if (cdi->pinfo.tcp_conn[i]->tcp_data_ssl) { + SSL_free(cdi->pinfo.tcp_conn[i]->tcp_data_ssl); + } + if (cdi->pinfo.tcp_conn[i]->tcp_data_fd >= 0) { + socket_closesocket(cdi->pinfo.tcp_conn[i]->tcp_data_fd); + cdi->pinfo.tcp_conn[i]->tcp_data_fd = -1; + } + free(cdi->pinfo.tcp_conn[i]); + cdi->pinfo.tcp_conn[i] = NULL; + } + } } - cdi->pinfo.tcp_conn_number=0; - if(cdi->pinfo.tcp_conn) { - free(cdi->pinfo.tcp_conn); - cdi->pinfo.tcp_conn=NULL; + cdi->pinfo.tcp_conn_number = 0; + if (cdi->pinfo.tcp_conn) { + free(cdi->pinfo.tcp_conn); + cdi->pinfo.tcp_conn = NULL; } } - if(cdi->pinfo.ssl && !(cdi->pinfo.broken)) { - if(!(SSL_get_shutdown(cdi->pinfo.ssl) & SSL_SENT_SHUTDOWN)) { - SSL_set_shutdown(cdi->pinfo.ssl, SSL_RECEIVED_SHUTDOWN); - SSL_shutdown(cdi->pinfo.ssl); - } + if (cdi->pinfo.ssl && !(cdi->pinfo.broken)) { + if (!(SSL_get_shutdown(cdi->pinfo.ssl) & SSL_SENT_SHUTDOWN)) { + SSL_set_shutdown(cdi->pinfo.ssl, SSL_RECEIVED_SHUTDOWN); + SSL_shutdown(cdi->pinfo.ssl); + } } - if(cdi->pinfo.ssl) { - SSL_free(cdi->pinfo.ssl); + if (cdi->pinfo.ssl) { + SSL_free(cdi->pinfo.ssl); } - if(cdi->pinfo.fd>=0) { - socket_closesocket(cdi->pinfo.fd); + if (cdi->pinfo.fd >= 0) { + socket_closesocket(cdi->pinfo.fd); } - cdi->pinfo.fd=-1; + cdi->pinfo.fd = -1; } } -static int remove_all_from_ss(app_ur_session* ss) -{ - if (ss) { - uc_delete_session_elem_data(ss); +static int remove_all_from_ss(app_ur_session *ss) { + if (ss) { + uc_delete_session_elem_data(ss); - --current_clients_number; - } + --current_clients_number; + } - return 0; + return 0; } /////////////////////////////////////////////////////////////////////////////// -int send_buffer(app_ur_conn_info *clnet_info, stun_buffer* message, int data_connection, app_tcp_conn_info *atc) -{ +int send_buffer(app_ur_conn_info *clnet_info, stun_buffer *message, int data_connection, app_tcp_conn_info *atc) { - int rc = 0; - int ret = -1; + int rc = 0; + int ret = -1; - char *buffer = (char*) (message->buf); + char *buffer = (char *)(message->buf); - if(negative_protocol_test && (message->len>0)) { - if(turn_random()%10 == 0) { - int np = (int)((unsigned long)turn_random()%10); - while(np-->0) { - int pos = (int)((unsigned long)turn_random()%(unsigned long)message->len); - int val = (int)((unsigned long)turn_random()%256); - message->buf[pos]=(uint8_t)val; - } - } - } + if (negative_protocol_test && (message->len > 0)) { + if (turn_random() % 10 == 0) { + int np = (int)((unsigned long)turn_random() % 10); + while (np-- > 0) { + int pos = (int)((unsigned long)turn_random() % (unsigned long)message->len); + int val = (int)((unsigned long)turn_random() % 256); + message->buf[pos] = (uint8_t)val; + } + } + } - SSL *ssl = clnet_info->ssl; - ioa_socket_raw fd = clnet_info->fd; + SSL *ssl = clnet_info->ssl; + ioa_socket_raw fd = clnet_info->fd; - if(data_connection) { - if(atc) { - ssl = atc->tcp_data_ssl; - fd = atc->tcp_data_fd; - } else if(is_TCP_relay()){ - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "trying to send tcp data buffer over unready connection: size=%d\n",(int)(message->len)); - return -1; - } - } + if (data_connection) { + if (atc) { + ssl = atc->tcp_data_ssl; + fd = atc->tcp_data_fd; + } else if (is_TCP_relay()) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "trying to send tcp data buffer over unready connection: size=%d\n", + (int)(message->len)); + return -1; + } + } - if (ssl) { + if (ssl) { - int message_sent = 0; - while (!message_sent) { + int message_sent = 0; + while (!message_sent) { - if (SSL_get_shutdown(ssl)) { - return -1; - } + if (SSL_get_shutdown(ssl)) { + return -1; + } - int len = 0; - do { - len = SSL_write(ssl, buffer, (int)message->len); - } while (len < 0 && ((errno == EINTR) || (errno == ENOBUFS))); + int len = 0; + do { + len = SSL_write(ssl, buffer, (int)message->len); + } while (len < 0 && ((errno == EINTR) || (errno == ENOBUFS))); - if(len == (int)message->len) { - if (clnet_verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "buffer sent: size=%d\n",len); - } + if (len == (int)message->len) { + if (clnet_verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "buffer sent: size=%d\n", len); + } - message_sent = 1; - ret = len; - } else { - switch (SSL_get_error(ssl, len)){ - case SSL_ERROR_NONE: - /* Try again ? */ - break; - case SSL_ERROR_WANT_WRITE: - /* Just try again later */ - break; - case SSL_ERROR_WANT_READ: - /* continue with reading */ - break; - case SSL_ERROR_ZERO_RETURN: - /* Try again */ - break; - case SSL_ERROR_SYSCALL: - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Socket write error 111.666: \n"); - if (handle_socket_error()) - break; - /* Falls through. */ - case SSL_ERROR_SSL: - { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SSL write error: \n"); - char buf[1024]; - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s (%d)\n", - ERR_error_string(ERR_get_error(),buf), - SSL_get_error(ssl, len)); - } - /* Falls through. */ - default: - clnet_info->broken = 1; - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Unexpected error while writing!\n"); - return -1; - } - } - } + message_sent = 1; + ret = len; + } else { + switch (SSL_get_error(ssl, len)) { + case SSL_ERROR_NONE: + /* Try again ? */ + break; + case SSL_ERROR_WANT_WRITE: + /* Just try again later */ + break; + case SSL_ERROR_WANT_READ: + /* continue with reading */ + break; + case SSL_ERROR_ZERO_RETURN: + /* Try again */ + break; + case SSL_ERROR_SYSCALL: + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Socket write error 111.666: \n"); + if (handle_socket_error()) + break; + /* Falls through. */ + case SSL_ERROR_SSL: { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SSL write error: \n"); + char buf[1024]; + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s (%d)\n", ERR_error_string(ERR_get_error(), buf), + SSL_get_error(ssl, len)); + } + /* Falls through. */ + default: + clnet_info->broken = 1; + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Unexpected error while writing!\n"); + return -1; + } + } + } - } else if (fd >= 0) { + } else if (fd >= 0) { - size_t left = (size_t) (message->len); + size_t left = (size_t)(message->len); - while (left > 0) { - do { - rc = send(fd, buffer, left, 0); - } while (rc <= 0 && ((errno == EINTR) || (errno == ENOBUFS) || (errno == EAGAIN))); - if (rc > 0) { - left -= (size_t) rc; - buffer += rc; - } else { - tot_send_dropped+=1; - break; - } - } + while (left > 0) { + do { + rc = send(fd, buffer, left, 0); + } while (rc <= 0 && ((errno == EINTR) || (errno == ENOBUFS) || (errno == EAGAIN))); + if (rc > 0) { + left -= (size_t)rc; + buffer += rc; + } else { + tot_send_dropped += 1; + break; + } + } - if (left > 0) - return -1; + if (left > 0) + return -1; - ret = (int) message->len; - } + ret = (int)message->len; + } - return ret; + return ret; } static int wait_fd(int fd, unsigned int cycle) { - if(fd>=(int)FD_SETSIZE) { - return 1; - } else { - fd_set fds; - FD_ZERO(&fds); - FD_SET(fd,&fds); + if (fd >= (int)FD_SETSIZE) { + return 1; + } else { + fd_set fds; + FD_ZERO(&fds); + FD_SET(fd, &fds); - if(dos && cycle==0) - return 0; + if (dos && cycle == 0) + return 0; - struct timeval start_time; - struct timeval ctime; - gettimeofday(&start_time,NULL); + struct timeval start_time; + struct timeval ctime; + gettimeofday(&start_time, NULL); - ctime.tv_sec = start_time.tv_sec; - ctime.tv_usec = start_time.tv_usec; + ctime.tv_sec = start_time.tv_sec; + ctime.tv_usec = start_time.tv_usec; - int rc = 0; + int rc = 0; - do { - struct timeval timeout = {0,0}; - if(cycle == 0) { - timeout.tv_usec = 500000; - } else { + do { + struct timeval timeout = {0, 0}; + if (cycle == 0) { + timeout.tv_usec = 500000; + } else { - timeout.tv_sec = 1; - while(--cycle) timeout.tv_sec = timeout.tv_sec + timeout.tv_sec; + timeout.tv_sec = 1; + while (--cycle) + timeout.tv_sec = timeout.tv_sec + timeout.tv_sec; - if(ctime.tv_sec > start_time.tv_sec) { - if(ctime.tv_sec >= start_time.tv_sec + timeout.tv_sec) { - break; - } else { - timeout.tv_sec -= (ctime.tv_sec - start_time.tv_sec); - } - } - } - rc = select(fd+1,&fds,NULL,NULL,&timeout); - if((rc<0) && (errno == EINTR)) { - gettimeofday(&ctime,NULL); - } else { - break; - } - } while(1); + if (ctime.tv_sec > start_time.tv_sec) { + if (ctime.tv_sec >= start_time.tv_sec + timeout.tv_sec) { + break; + } else { + timeout.tv_sec -= (ctime.tv_sec - start_time.tv_sec); + } + } + } + rc = select(fd + 1, &fds, NULL, NULL, &timeout); + if ((rc < 0) && (errno == EINTR)) { + gettimeofday(&ctime, NULL); + } else { + break; + } + } while (1); - return rc; - } + return rc; + } } -int recv_buffer(app_ur_conn_info *clnet_info, stun_buffer* message, int sync, int data_connection, app_tcp_conn_info *atc, stun_buffer* request_message) { +int recv_buffer(app_ur_conn_info *clnet_info, stun_buffer *message, int sync, int data_connection, + app_tcp_conn_info *atc, stun_buffer *request_message) { - int rc = 0; + int rc = 0; - stun_tid tid; - uint16_t method = 0; + stun_tid tid; + uint16_t method = 0; - if(request_message) { - stun_tid_from_message(request_message, &tid); - method = stun_get_method(request_message); - } + if (request_message) { + stun_tid_from_message(request_message, &tid); + method = stun_get_method(request_message); + } - ioa_socket_raw fd = clnet_info->fd; - if (atc) - fd = atc->tcp_data_fd; + ioa_socket_raw fd = clnet_info->fd; + if (atc) + fd = atc->tcp_data_fd; - SSL* ssl = clnet_info->ssl; - if (atc) - ssl = atc->tcp_data_ssl; + SSL *ssl = clnet_info->ssl; + if (atc) + ssl = atc->tcp_data_ssl; - recv_again: +recv_again: - if(!use_tcp && sync && request_message && (fd>=0)) { + if (!use_tcp && sync && request_message && (fd >= 0)) { - unsigned int cycle = 0; - while(cycle < MAX_LISTENING_CYCLE_NUMBER) { - int serc = wait_fd(fd,cycle); - if(serc>0) - break; - if(serc<0) { - return -1; - } - if(send_buffer(clnet_info, request_message, data_connection, atc)<=0) - return -1; - ++cycle; - } - } + unsigned int cycle = 0; + while (cycle < MAX_LISTENING_CYCLE_NUMBER) { + int serc = wait_fd(fd, cycle); + if (serc > 0) + break; + if (serc < 0) { + return -1; + } + if (send_buffer(clnet_info, request_message, data_connection, atc) <= 0) + return -1; + ++cycle; + } + } - if (!use_secure && !use_tcp && fd >= 0) { + if (!use_secure && !use_tcp && fd >= 0) { - /* Plain UDP */ + /* Plain UDP */ - do { - rc = recv(fd, message->buf, sizeof(message->buf) - 1, 0); - if (rc < 0 && errno == EAGAIN && sync) - errno = EINTR; - } while (rc < 0 && (errno == EINTR)); + do { + rc = recv(fd, message->buf, sizeof(message->buf) - 1, 0); + if (rc < 0 && errno == EAGAIN && sync) + errno = EINTR; + } while (rc < 0 && (errno == EINTR)); - if (rc < 0) { - return -1; - } + if (rc < 0) { + return -1; + } - message->len = rc; + message->len = rc; - } else if (use_secure && !use_tcp && ssl && !(clnet_info->broken)) { + } else if (use_secure && !use_tcp && ssl && !(clnet_info->broken)) { - /* DTLS */ + /* DTLS */ - int message_received = 0; - int cycle = 0; - while (!message_received && cycle++ < 100) { + int message_received = 0; + int cycle = 0; + while (!message_received && cycle++ < 100) { - if (SSL_get_shutdown(ssl)) - return -1; + if (SSL_get_shutdown(ssl)) + return -1; - rc = 0; - do { - rc = SSL_read(ssl, message->buf, sizeof(message->buf) - 1); - if (rc < 0 && errno == EAGAIN && sync) - continue; - } while (rc < 0 && (errno == EINTR)); + rc = 0; + do { + rc = SSL_read(ssl, message->buf, sizeof(message->buf) - 1); + if (rc < 0 && errno == EAGAIN && sync) + continue; + } while (rc < 0 && (errno == EINTR)); - if (rc > 0) { + if (rc > 0) { - if (clnet_verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "response received: size=%d\n", rc); - } - message->len = rc; - message_received = 1; + if (clnet_verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "response received: size=%d\n", rc); + } + message->len = rc; + message_received = 1; - } else { + } else { - int sslerr = SSL_get_error(ssl, rc); + int sslerr = SSL_get_error(ssl, rc); - switch (sslerr) { - case SSL_ERROR_NONE: - /* Try again ? */ - break; - case SSL_ERROR_WANT_WRITE: - /* Just try again later */ - break; - case SSL_ERROR_WANT_READ: - /* continue with reading */ - break; - case SSL_ERROR_ZERO_RETURN: - /* Try again */ - break; - case SSL_ERROR_SYSCALL: - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "Socket read error 111.999: \n"); - if (handle_socket_error()) - break; - /* Falls through. */ - case SSL_ERROR_SSL: { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SSL write error: \n"); - char buf[1024]; - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s (%d)\n", - ERR_error_string(ERR_get_error(), buf), - SSL_get_error(ssl, rc)); - } - /* Falls through. */ - default: - clnet_info->broken = 1; - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "Unexpected error while reading: rc=%d, sslerr=%d\n", - rc, sslerr); - return -1; - } + switch (sslerr) { + case SSL_ERROR_NONE: + /* Try again ? */ + break; + case SSL_ERROR_WANT_WRITE: + /* Just try again later */ + break; + case SSL_ERROR_WANT_READ: + /* continue with reading */ + break; + case SSL_ERROR_ZERO_RETURN: + /* Try again */ + break; + case SSL_ERROR_SYSCALL: + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Socket read error 111.999: \n"); + if (handle_socket_error()) + break; + /* Falls through. */ + case SSL_ERROR_SSL: { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SSL write error: \n"); + char buf[1024]; + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s (%d)\n", ERR_error_string(ERR_get_error(), buf), + SSL_get_error(ssl, rc)); + } + /* Falls through. */ + default: + clnet_info->broken = 1; + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Unexpected error while reading: rc=%d, sslerr=%d\n", rc, sslerr); + return -1; + } - if (!sync) - break; - } - } + if (!sync) + break; + } + } - } else if (use_secure && use_tcp && ssl && !(clnet_info->broken)) { + } else if (use_secure && use_tcp && ssl && !(clnet_info->broken)) { - /* TLS*/ + /* TLS*/ - int message_received = 0; - int cycle = 0; - while (!message_received && cycle++ < 100) { + int message_received = 0; + int cycle = 0; + while (!message_received && cycle++ < 100) { - if (SSL_get_shutdown(ssl)) - return -1; - rc = 0; - do { - rc = SSL_read(ssl, message->buf, sizeof(message->buf) - 1); - if (rc < 0 && errno == EAGAIN && sync) - continue; - } while (rc < 0 && (errno == EINTR)); + if (SSL_get_shutdown(ssl)) + return -1; + rc = 0; + do { + rc = SSL_read(ssl, message->buf, sizeof(message->buf) - 1); + if (rc < 0 && errno == EAGAIN && sync) + continue; + } while (rc < 0 && (errno == EINTR)); - if (rc > 0) { + if (rc > 0) { - if (clnet_verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "response received: size=%d\n", rc); - } - message->len = rc; - message_received = 1; + if (clnet_verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "response received: size=%d\n", rc); + } + message->len = rc; + message_received = 1; - } else { + } else { - int sslerr = SSL_get_error(ssl, rc); + int sslerr = SSL_get_error(ssl, rc); - switch (sslerr) { - case SSL_ERROR_NONE: - /* Try again ? */ - break; - case SSL_ERROR_WANT_WRITE: - /* Just try again later */ - break; - case SSL_ERROR_WANT_READ: - /* continue with reading */ - break; - case SSL_ERROR_ZERO_RETURN: - /* Try again */ - break; - case SSL_ERROR_SYSCALL: - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "Socket read error 111.999: \n"); - if (handle_socket_error()) - break; - /* Falls through. */ - case SSL_ERROR_SSL: { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SSL write error: \n"); - char buf[1024]; - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s (%d)\n", - ERR_error_string(ERR_get_error(), buf), - SSL_get_error(ssl, rc)); - } - /* Falls through. */ - default: - clnet_info->broken = 1; - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "Unexpected error while reading: rc=%d, sslerr=%d\n", - rc, sslerr); - return -1; - } + switch (sslerr) { + case SSL_ERROR_NONE: + /* Try again ? */ + break; + case SSL_ERROR_WANT_WRITE: + /* Just try again later */ + break; + case SSL_ERROR_WANT_READ: + /* continue with reading */ + break; + case SSL_ERROR_ZERO_RETURN: + /* Try again */ + break; + case SSL_ERROR_SYSCALL: + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Socket read error 111.999: \n"); + if (handle_socket_error()) + break; + /* Falls through. */ + case SSL_ERROR_SSL: { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SSL write error: \n"); + char buf[1024]; + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s (%d)\n", ERR_error_string(ERR_get_error(), buf), + SSL_get_error(ssl, rc)); + } + /* Falls through. */ + default: + clnet_info->broken = 1; + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Unexpected error while reading: rc=%d, sslerr=%d\n", rc, sslerr); + return -1; + } - if (!sync) - break; - } - } + if (!sync) + break; + } + } - } else if (!use_secure && use_tcp && fd >= 0) { + } else if (!use_secure && use_tcp && fd >= 0) { - /* Plain TCP */ + /* Plain TCP */ - do { - rc = recv(fd, message->buf, sizeof(message->buf) - 1, MSG_PEEK); - if ((rc < 0) && (errno == EAGAIN) && sync) { - errno = EINTR; - } - } while (rc < 0 && (errno == EINTR)); + do { + rc = recv(fd, message->buf, sizeof(message->buf) - 1, MSG_PEEK); + if ((rc < 0) && (errno == EAGAIN) && sync) { + errno = EINTR; + } + } while (rc < 0 && (errno == EINTR)); - if (rc > 0) { - int mlen = rc; - size_t app_msg_len = (size_t) rc; - if (!atc) { - mlen = stun_get_message_len_str(message->buf, rc, 1, - &app_msg_len); - } else { - if (!sync) - mlen = clmessage_length; + if (rc > 0) { + int mlen = rc; + size_t app_msg_len = (size_t)rc; + if (!atc) { + mlen = stun_get_message_len_str(message->buf, rc, 1, &app_msg_len); + } else { + if (!sync) + mlen = clmessage_length; - if (mlen > clmessage_length) - mlen = clmessage_length; + if (mlen > clmessage_length) + mlen = clmessage_length; - app_msg_len = (size_t) mlen; - } + app_msg_len = (size_t)mlen; + } - if (mlen > 0) { + if (mlen > 0) { - int rcr = 0; - int rsf = 0; - int cycle = 0; - while (rsf < mlen && cycle++ < 128) { - do { - rcr = recv(fd, message->buf + rsf, - (size_t) mlen - (size_t) rsf, 0); - if (rcr < 0 && errno == EAGAIN && sync) - errno = EINTR; - } while (rcr < 0 && (errno == EINTR)); + int rcr = 0; + int rsf = 0; + int cycle = 0; + while (rsf < mlen && cycle++ < 128) { + do { + rcr = recv(fd, message->buf + rsf, (size_t)mlen - (size_t)rsf, 0); + if (rcr < 0 && errno == EAGAIN && sync) + errno = EINTR; + } while (rcr < 0 && (errno == EINTR)); - if (rcr > 0) - rsf += rcr; + if (rcr > 0) + rsf += rcr; + } - } + if (rsf < 1) + return -1; - if (rsf < 1) - return -1; + if (rsf < (int)app_msg_len) { + if ((size_t)(app_msg_len / (size_t)rsf) * ((size_t)(rsf)) != app_msg_len) { + return -1; + } + } - if (rsf < (int) app_msg_len) { - if ((size_t) (app_msg_len / (size_t) rsf) * ((size_t) (rsf)) - != app_msg_len) { - return -1; - } - } + message->len = app_msg_len; - message->len = app_msg_len; + rc = app_msg_len; - rc = app_msg_len; + } else { + rc = 0; + } + } + } - } else { - rc = 0; - } - } - } + if (rc > 0) { + if (request_message) { - if(rc>0) { - if(request_message) { + stun_tid recv_tid; + uint16_t recv_method = 0; - stun_tid recv_tid; - uint16_t recv_method = 0; + stun_tid_from_message(message, &recv_tid); + recv_method = stun_get_method(message); - stun_tid_from_message(message, &recv_tid); - recv_method = stun_get_method(message); + if (method != recv_method) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Received wrong response method: 0x%x, expected 0x%x; trying again...\n", + (unsigned int)recv_method, (unsigned int)method); + goto recv_again; + } - if(method != recv_method) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Received wrong response method: 0x%x, expected 0x%x; trying again...\n",(unsigned int)recv_method,(unsigned int)method); - goto recv_again; - } + if (memcmp(tid.tsx_id, recv_tid.tsx_id, STUN_TID_SIZE)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Received wrong response tid; trying again...\n"); + goto recv_again; + } + } + } - if(memcmp(tid.tsx_id,recv_tid.tsx_id,STUN_TID_SIZE)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Received wrong response tid; trying again...\n"); - goto recv_again; - } - } - } - - return rc; + return rc; } static int client_read(app_ur_session *elem, int is_tcp_data, app_tcp_conn_info *atc) { - if (!elem) - return -1; + if (!elem) + return -1; - if (elem->state != UR_STATE_READY) - return -1; + if (elem->state != UR_STATE_READY) + return -1; - elem->ctime = current_time; + elem->ctime = current_time; - app_ur_conn_info *clnet_info = &(elem->pinfo); - int err_code = 0; - uint8_t err_msg[129]; - int rc = 0; - int applen = 0; + app_ur_conn_info *clnet_info = &(elem->pinfo); + int err_code = 0; + uint8_t err_msg[129]; + int rc = 0; + int applen = 0; - if (clnet_verbose && verbose_packets) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "before read ...\n"); - } + if (clnet_verbose && verbose_packets) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "before read ...\n"); + } - rc = recv_buffer(clnet_info, &(elem->in_buffer), 0, is_tcp_data, atc, NULL); + rc = recv_buffer(clnet_info, &(elem->in_buffer), 0, is_tcp_data, atc, NULL); - if (clnet_verbose && verbose_packets) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "read %d bytes\n", (int) rc); - } + if (clnet_verbose && verbose_packets) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "read %d bytes\n", (int)rc); + } - if (rc > 0) { + if (rc > 0) { - elem->in_buffer.len = rc; + elem->in_buffer.len = rc; - uint16_t chnumber = 0; + uint16_t chnumber = 0; - message_info mi; - int miset=0; - size_t buffers = 1; + message_info mi; + int miset = 0; + size_t buffers = 1; - if(is_tcp_data) { - if ((int)elem->in_buffer.len == clmessage_length) { - memcpy(&mi, (elem->in_buffer.buf), sizeof(message_info)); - miset=1; - } else { - /* TODO: make a more clean fix */ - buffers=(int)elem->in_buffer.len / clmessage_length; - } - } else if (stun_is_indication(&(elem->in_buffer))) { + if (is_tcp_data) { + if ((int)elem->in_buffer.len == clmessage_length) { + memcpy(&mi, (elem->in_buffer.buf), sizeof(message_info)); + miset = 1; + } else { + /* TODO: make a more clean fix */ + buffers = (int)elem->in_buffer.len / clmessage_length; + } + } else if (stun_is_indication(&(elem->in_buffer))) { - uint16_t method = stun_get_method(&elem->in_buffer); + uint16_t method = stun_get_method(&elem->in_buffer); - if((method == STUN_METHOD_CONNECTION_ATTEMPT)&& is_TCP_relay()) { - stun_attr_ref sar = stun_attr_get_first(&(elem->in_buffer)); - uint32_t cid = 0; - while(sar) { - int attr_type = stun_attr_get_type(sar); - if(attr_type == STUN_ATTRIBUTE_CONNECTION_ID) { - cid = *((const uint32_t*)stun_attr_get_value(sar)); - break; - } - sar = stun_attr_get_next_str(elem->in_buffer.buf,elem->in_buffer.len,sar); - } - if(negative_test) { - tcp_data_connect(elem,(uint64_t)turn_random()); - } else { - /* positive test */ - tcp_data_connect(elem,cid); - } - return rc; - } else if (method != STUN_METHOD_DATA) { - TURN_LOG_FUNC( - TURN_LOG_LEVEL_INFO, - "ERROR: received indication message has wrong method: 0x%x\n", - (int) method); - return rc; - } else { + if ((method == STUN_METHOD_CONNECTION_ATTEMPT) && is_TCP_relay()) { + stun_attr_ref sar = stun_attr_get_first(&(elem->in_buffer)); + uint32_t cid = 0; + while (sar) { + int attr_type = stun_attr_get_type(sar); + if (attr_type == STUN_ATTRIBUTE_CONNECTION_ID) { + cid = *((const uint32_t *)stun_attr_get_value(sar)); + break; + } + sar = stun_attr_get_next_str(elem->in_buffer.buf, elem->in_buffer.len, sar); + } + if (negative_test) { + tcp_data_connect(elem, (uint64_t)turn_random()); + } else { + /* positive test */ + tcp_data_connect(elem, cid); + } + return rc; + } else if (method != STUN_METHOD_DATA) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ERROR: received indication message has wrong method: 0x%x\n", (int)method); + return rc; + } else { - stun_attr_ref sar = stun_attr_get_first_by_type(&(elem->in_buffer), STUN_ATTRIBUTE_DATA); - if (!sar) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ERROR: received DATA message has no data, size=%d\n", rc); - return rc; - } + stun_attr_ref sar = stun_attr_get_first_by_type(&(elem->in_buffer), STUN_ATTRIBUTE_DATA); + if (!sar) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ERROR: received DATA message has no data, size=%d\n", rc); + return rc; + } - int rlen = stun_attr_get_len(sar); - applen = rlen; - if (rlen != clmessage_length) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ERROR: received DATA message has wrong len: %d, must be %d\n", rlen, clmessage_length); - tot_recv_bytes += applen; - return rc; - } + int rlen = stun_attr_get_len(sar); + applen = rlen; + if (rlen != clmessage_length) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ERROR: received DATA message has wrong len: %d, must be %d\n", rlen, + clmessage_length); + tot_recv_bytes += applen; + return rc; + } - const uint8_t* data = stun_attr_get_value(sar); + const uint8_t *data = stun_attr_get_value(sar); - memcpy(&mi, data, sizeof(message_info)); - miset=1; - } + memcpy(&mi, data, sizeof(message_info)); + miset = 1; + } - } else if (stun_is_success_response(&(elem->in_buffer))) { + } else if (stun_is_success_response(&(elem->in_buffer))) { - if(elem->pinfo.nonce[0]) { - if(check_integrity(&(elem->pinfo), &(elem->in_buffer))<0) - return -1; - } + if (elem->pinfo.nonce[0]) { + if (check_integrity(&(elem->pinfo), &(elem->in_buffer)) < 0) + return -1; + } - if(is_TCP_relay() && (stun_get_method(&(elem->in_buffer)) == STUN_METHOD_CONNECT)) { - stun_attr_ref sar = stun_attr_get_first(&(elem->in_buffer)); - uint32_t cid = 0; - while(sar) { - int attr_type = stun_attr_get_type(sar); - if(attr_type == STUN_ATTRIBUTE_CONNECTION_ID) { - cid = *((const uint32_t*)stun_attr_get_value(sar)); - break; - } - sar = stun_attr_get_next_str(elem->in_buffer.buf,elem->in_buffer.len,sar); - } - tcp_data_connect(elem,cid); - } + if (is_TCP_relay() && (stun_get_method(&(elem->in_buffer)) == STUN_METHOD_CONNECT)) { + stun_attr_ref sar = stun_attr_get_first(&(elem->in_buffer)); + uint32_t cid = 0; + while (sar) { + int attr_type = stun_attr_get_type(sar); + if (attr_type == STUN_ATTRIBUTE_CONNECTION_ID) { + cid = *((const uint32_t *)stun_attr_get_value(sar)); + break; + } + sar = stun_attr_get_next_str(elem->in_buffer.buf, elem->in_buffer.len, sar); + } + tcp_data_connect(elem, cid); + } - return rc; - } else if (stun_is_challenge_response_str(elem->in_buffer.buf, (size_t)elem->in_buffer.len, - &err_code,err_msg,sizeof(err_msg), - clnet_info->realm,clnet_info->nonce, - clnet_info->server_name, &(clnet_info->oauth))) { - if(is_TCP_relay() && (stun_get_method(&(elem->in_buffer)) == STUN_METHOD_CONNECT)) { - turn_tcp_connect(clnet_verbose, &(elem->pinfo), &(elem->pinfo.peer_addr)); - } else if(stun_get_method(&(elem->in_buffer)) == STUN_METHOD_REFRESH) { - refresh_channel(elem, stun_get_method(&elem->in_buffer),600); - } - return rc; - } else if (stun_is_error_response(&(elem->in_buffer), NULL,NULL,0)) { - return rc; - } else if (stun_is_channel_message(&(elem->in_buffer), &chnumber, use_tcp)) { - if (elem->chnum != chnumber) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "ERROR: received message has wrong channel: %d\n", - (int) chnumber); - return rc; - } + return rc; + } else if (stun_is_challenge_response_str(elem->in_buffer.buf, (size_t)elem->in_buffer.len, &err_code, err_msg, + sizeof(err_msg), clnet_info->realm, clnet_info->nonce, + clnet_info->server_name, &(clnet_info->oauth))) { + if (is_TCP_relay() && (stun_get_method(&(elem->in_buffer)) == STUN_METHOD_CONNECT)) { + turn_tcp_connect(clnet_verbose, &(elem->pinfo), &(elem->pinfo.peer_addr)); + } else if (stun_get_method(&(elem->in_buffer)) == STUN_METHOD_REFRESH) { + refresh_channel(elem, stun_get_method(&elem->in_buffer), 600); + } + return rc; + } else if (stun_is_error_response(&(elem->in_buffer), NULL, NULL, 0)) { + return rc; + } else if (stun_is_channel_message(&(elem->in_buffer), &chnumber, use_tcp)) { + if (elem->chnum != chnumber) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ERROR: received message has wrong channel: %d\n", (int)chnumber); + return rc; + } - if (elem->in_buffer.len >= 4) { - if (((int)(elem->in_buffer.len-4) < clmessage_length) || - ((int)(elem->in_buffer.len-4) > clmessage_length + 3)) { - TURN_LOG_FUNC( - TURN_LOG_LEVEL_INFO, - "ERROR: received buffer have wrong length: %d, must be %d, len=%d\n", - rc, clmessage_length + 4,(int)elem->in_buffer.len); - return rc; - } + if (elem->in_buffer.len >= 4) { + if (((int)(elem->in_buffer.len - 4) < clmessage_length) || + ((int)(elem->in_buffer.len - 4) > clmessage_length + 3)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ERROR: received buffer have wrong length: %d, must be %d, len=%d\n", rc, + clmessage_length + 4, (int)elem->in_buffer.len); + return rc; + } - memcpy(&mi, elem->in_buffer.buf + 4, sizeof(message_info)); - miset=1; - applen = elem->in_buffer.len -4; - } - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "ERROR: Unknown message received of size: %d\n",(int)(elem->in_buffer.len)); - return rc; - } + memcpy(&mi, elem->in_buffer.buf + 4, sizeof(message_info)); + miset = 1; + applen = elem->in_buffer.len - 4; + } + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ERROR: Unknown message received of size: %d\n", (int)(elem->in_buffer.len)); + return rc; + } - if(miset) { - /* - printf("%s: 111.111: msgnum=%d, rmsgnum=%d, sent=%lu, recv=%lu\n",__FUNCTION__, - mi->msgnum,elem->recvmsgnum,(unsigned long)mi->mstime,(unsigned long)current_mstime); - */ - if(mi.msgnum != elem->recvmsgnum+1) - ++(elem->loss); - else { - uint64_t clatency = (uint64_t)time_minus(current_mstime,mi.mstime); - if(clatency>max_latency) - max_latency = clatency; - if(clatencylatency += clatency; - if(elem->rmsgnum>0) { - uint64_t cjitter = abs((int)(current_mstime-elem->recvtimems)-RTP_PACKET_INTERVAL); - - if(cjitter>max_jitter) - max_jitter = cjitter; - if(cjitterjitter += cjitter; - } - } + if (miset) { + /* + printf("%s: 111.111: msgnum=%d, rmsgnum=%d, sent=%lu, recv=%lu\n",__FUNCTION__, + mi->msgnum,elem->recvmsgnum,(unsigned long)mi->mstime,(unsigned long)current_mstime); + */ + if (mi.msgnum != elem->recvmsgnum + 1) + ++(elem->loss); + else { + uint64_t clatency = (uint64_t)time_minus(current_mstime, mi.mstime); + if (clatency > max_latency) + max_latency = clatency; + if (clatency < min_latency) + min_latency = clatency; + elem->latency += clatency; + if (elem->rmsgnum > 0) { + uint64_t cjitter = abs((int)(current_mstime - elem->recvtimems) - RTP_PACKET_INTERVAL); - elem->recvmsgnum = mi.msgnum; - } + if (cjitter > max_jitter) + max_jitter = cjitter; + if (cjitter < min_jitter) + min_jitter = cjitter; - elem->rmsgnum+=buffers; - tot_recv_messages+=buffers; - if(applen > 0) - tot_recv_bytes += applen; - else - tot_recv_bytes += elem->in_buffer.len; - elem->recvtimems=current_mstime; - elem->wait_cycles = 0; + elem->jitter += cjitter; + } + } - } else if(rc == 0) { - return 0; - } else { - return -1; - } + elem->recvmsgnum = mi.msgnum; + } - return rc; + elem->rmsgnum += buffers; + tot_recv_messages += buffers; + if (applen > 0) + tot_recv_bytes += applen; + else + tot_recv_bytes += elem->in_buffer.len; + elem->recvtimems = current_mstime; + elem->wait_cycles = 0; + + } else if (rc == 0) { + return 0; + } else { + return -1; + } + + return rc; } static int client_shutdown(app_ur_session *elem) { - if(!elem) return -1; + if (!elem) + return -1; - elem->state=UR_STATE_DONE; + elem->state = UR_STATE_DONE; - elem->ctime=current_time; + elem->ctime = current_time; remove_all_from_ss(elem); - + if (clnet_verbose) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"done, connection 0x%lx closed.\n",(long)elem); - + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "done, connection 0x%lx closed.\n", (long)elem); + return 0; } static int client_write(app_ur_session *elem) { - if(!elem) return -1; + if (!elem) + return -1; - if(elem->state!=UR_STATE_READY) return -1; + if (elem->state != UR_STATE_READY) + return -1; - elem->ctime=current_time; + elem->ctime = current_time; - message_info *mi = (message_info*)buffer_to_send; - mi->msgnum=elem->wmsgnum; - mi->mstime=current_mstime; - app_tcp_conn_info *atc=NULL; + message_info *mi = (message_info *)buffer_to_send; + mi->msgnum = elem->wmsgnum; + mi->mstime = current_mstime; + app_tcp_conn_info *atc = NULL; if (is_TCP_relay()) { - memcpy(elem->out_buffer.buf, buffer_to_send, clmessage_length); - elem->out_buffer.len = clmessage_length; + memcpy(elem->out_buffer.buf, buffer_to_send, clmessage_length); + elem->out_buffer.len = clmessage_length; - if(elem->pinfo.is_peer) { - if(send(elem->pinfo.fd, elem->out_buffer.buf, clmessage_length, 0)>=0) { - ++elem->wmsgnum; - elem->to_send_timems += RTP_PACKET_INTERVAL; - tot_send_messages++; - tot_send_bytes += clmessage_length; - } - return 0; - } + if (elem->pinfo.is_peer) { + if (send(elem->pinfo.fd, elem->out_buffer.buf, clmessage_length, 0) >= 0) { + ++elem->wmsgnum; + elem->to_send_timems += RTP_PACKET_INTERVAL; + tot_send_messages++; + tot_send_bytes += clmessage_length; + } + return 0; + } - if (!(elem->pinfo.tcp_conn) || !(elem->pinfo.tcp_conn_number)) { - return -1; - } - int i = (unsigned int)(turn_random()) % elem->pinfo.tcp_conn_number; - atc = elem->pinfo.tcp_conn[i]; - if(!atc->tcp_data_bound) { - printf("%s: Uninitialized atc: i=%d, atc=0x%lx\n",__FUNCTION__,i,(long)atc); - return -1; - } - } else if(!do_not_use_channel) { - /* Let's always do padding: */ + if (!(elem->pinfo.tcp_conn) || !(elem->pinfo.tcp_conn_number)) { + return -1; + } + int i = (unsigned int)(turn_random()) % elem->pinfo.tcp_conn_number; + atc = elem->pinfo.tcp_conn[i]; + if (!atc->tcp_data_bound) { + printf("%s: Uninitialized atc: i=%d, atc=0x%lx\n", __FUNCTION__, i, (long)atc); + return -1; + } + } else if (!do_not_use_channel) { + /* Let's always do padding: */ stun_init_channel_message(elem->chnum, &(elem->out_buffer), clmessage_length, mandatory_channel_padding || use_tcp); - memcpy(elem->out_buffer.buf+4,buffer_to_send,clmessage_length); + memcpy(elem->out_buffer.buf + 4, buffer_to_send, clmessage_length); } else { stun_init_indication(STUN_METHOD_SEND, &(elem->out_buffer)); stun_attr_add(&(elem->out_buffer), STUN_ATTRIBUTE_DATA, buffer_to_send, clmessage_length); - stun_attr_add_addr(&(elem->out_buffer),STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &(elem->pinfo.peer_addr)); - if(dont_fragment) - stun_attr_add(&(elem->out_buffer), STUN_ATTRIBUTE_DONT_FRAGMENT, NULL, 0); + stun_attr_add_addr(&(elem->out_buffer), STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &(elem->pinfo.peer_addr)); + if (dont_fragment) + stun_attr_add(&(elem->out_buffer), STUN_ATTRIBUTE_DONT_FRAGMENT, NULL, 0); - if(use_fingerprints) - stun_attr_add_fingerprint_str(elem->out_buffer.buf,(size_t*)&(elem->out_buffer.len)); + if (use_fingerprints) + stun_attr_add_fingerprint_str(elem->out_buffer.buf, (size_t *)&(elem->out_buffer.len)); } if (elem->out_buffer.len > 0) { - + if (clnet_verbose && verbose_packets) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "before write ...\n"); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "before write ...\n"); } - int rc=send_buffer(&(elem->pinfo),&(elem->out_buffer),1,atc); + int rc = send_buffer(&(elem->pinfo), &(elem->out_buffer), 1, atc); ++elem->wmsgnum; elem->to_send_timems += RTP_PACKET_INTERVAL; - - if(rc >= 0) { + + if (rc >= 0) { if (clnet_verbose && verbose_packets) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "wrote %d bytes\n", (int) rc); - } + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "wrote %d bytes\n", (int)rc); + } tot_send_messages++; tot_send_bytes += clmessage_length; } else { - return -1; + return -1; } } return 0; } -void client_input_handler(evutil_socket_t fd, short what, void* arg) { +void client_input_handler(evutil_socket_t fd, short what, void *arg) { - if(!(what&EV_READ)||!arg) return; + if (!(what & EV_READ) || !arg) + return; UNUSED_ARG(fd); - app_ur_session* elem = (app_ur_session*)arg; - if(!elem) { + app_ur_session *elem = (app_ur_session *)arg; + if (!elem) { return; } - - switch(elem->state) { + + switch (elem->state) { case UR_STATE_READY: - do { - app_tcp_conn_info *atc = NULL; - int is_tcp_data = 0; - if(elem->pinfo.tcp_conn) { - int i = 0; - for(i=0;i<(int)(elem->pinfo.tcp_conn_number);++i) { - if(elem->pinfo.tcp_conn[i]) { - if((fd==elem->pinfo.tcp_conn[i]->tcp_data_fd) && (elem->pinfo.tcp_conn[i]->tcp_data_bound)) { - is_tcp_data = 1; - atc = elem->pinfo.tcp_conn[i]; - break; - } - } + do { + app_tcp_conn_info *atc = NULL; + int is_tcp_data = 0; + if (elem->pinfo.tcp_conn) { + int i = 0; + for (i = 0; i < (int)(elem->pinfo.tcp_conn_number); ++i) { + if (elem->pinfo.tcp_conn[i]) { + if ((fd == elem->pinfo.tcp_conn[i]->tcp_data_fd) && (elem->pinfo.tcp_conn[i]->tcp_data_bound)) { + is_tcp_data = 1; + atc = elem->pinfo.tcp_conn[i]; + break; + } + } + } } - } - int rc = client_read(elem, is_tcp_data, atc); - if(rc<=0) break; - } while(1); + int rc = client_read(elem, is_tcp_data, atc); + if (rc <= 0) + break; + } while (1); break; - default: - ; + default:; } } -static void run_events(int short_burst) -{ - struct timeval timeout; +static void run_events(int short_burst) { + struct timeval timeout; - if(!short_burst) { - timeout.tv_sec = 1; - timeout.tv_usec = 0; - } else { - timeout.tv_sec = 0; - timeout.tv_usec = 100000; - } + if (!short_burst) { + timeout.tv_sec = 1; + timeout.tv_usec = 0; + } else { + timeout.tv_sec = 0; + timeout.tv_usec = 100000; + } - event_base_loopexit(client_event_base, &timeout); + event_base_loopexit(client_event_base, &timeout); - event_base_dispatch(client_event_base); + event_base_dispatch(client_event_base); } ////////////////////// main method ///////////////// -static int start_client(const char *remote_address, int port, - const unsigned char* ifname, const char *local_address, - int messagenumber, - int i) { +static int start_client(const char *remote_address, int port, const unsigned char *ifname, const char *local_address, + int messagenumber, int i) { - app_ur_session* ss=create_new_ss(); - app_ur_session* ss_rtcp=NULL; + app_ur_session *ss = create_new_ss(); + app_ur_session *ss_rtcp = NULL; - if(!no_rtcp) + if (!no_rtcp) ss_rtcp = create_new_ss(); app_ur_conn_info clnet_info_probe; /* for load balancing probe */ memset(&clnet_info_probe, 0, sizeof(clnet_info_probe)); clnet_info_probe.fd = -1; - app_ur_conn_info *clnet_info=&(ss->pinfo); - app_ur_conn_info *clnet_info_rtcp=NULL; + app_ur_conn_info *clnet_info = &(ss->pinfo); + app_ur_conn_info *clnet_info_rtcp = NULL; - if(!no_rtcp) + if (!no_rtcp) clnet_info_rtcp = &(ss_rtcp->pinfo); - uint16_t chnum=0; - uint16_t chnum_rtcp=0; + uint16_t chnum = 0; + uint16_t chnum_rtcp = 0; - start_connection(port, remote_address, - ifname, local_address, - clnet_verbose, - &clnet_info_probe, - clnet_info, &chnum, - clnet_info_rtcp, &chnum_rtcp); - - if(clnet_info_probe.ssl) { - SSL_free(clnet_info_probe.ssl); - clnet_info_probe.fd = -1; - } else if(clnet_info_probe.fd != -1) { - socket_closesocket(clnet_info_probe.fd); - clnet_info_probe.fd = -1; + start_connection(port, remote_address, ifname, local_address, clnet_verbose, &clnet_info_probe, clnet_info, &chnum, + clnet_info_rtcp, &chnum_rtcp); + + if (clnet_info_probe.ssl) { + SSL_free(clnet_info_probe.ssl); + clnet_info_probe.fd = -1; + } else if (clnet_info_probe.fd != -1) { + socket_closesocket(clnet_info_probe.fd); + clnet_info_probe.fd = -1; } - + socket_set_nonblocking(clnet_info->fd); - - if(!no_rtcp) - socket_set_nonblocking(clnet_info_rtcp->fd); - - struct event* ev = event_new(client_event_base,clnet_info->fd, - EV_READ|EV_PERSIST,client_input_handler, - ss); - event_add(ev,NULL); - - struct event* ev_rtcp = NULL; + if (!no_rtcp) + socket_set_nonblocking(clnet_info_rtcp->fd); - if(!no_rtcp) { - ev_rtcp = event_new(client_event_base,clnet_info_rtcp->fd, - EV_READ|EV_PERSIST,client_input_handler, - ss_rtcp); - - event_add(ev_rtcp,NULL); + struct event *ev = event_new(client_event_base, clnet_info->fd, EV_READ | EV_PERSIST, client_input_handler, ss); + + event_add(ev, NULL); + + struct event *ev_rtcp = NULL; + + if (!no_rtcp) { + ev_rtcp = event_new(client_event_base, clnet_info_rtcp->fd, EV_READ | EV_PERSIST, client_input_handler, ss_rtcp); + + event_add(ev_rtcp, NULL); } - - ss->state=UR_STATE_READY; - - ss->input_ev=ev; - ss->tot_msgnum=messagenumber; - ss->recvmsgnum=-1; - ss->chnum=chnum; - if(!no_rtcp) { + ss->state = UR_STATE_READY; - ss_rtcp->state=UR_STATE_READY; - - ss_rtcp->input_ev=ev_rtcp; - ss_rtcp->tot_msgnum=ss->tot_msgnum; - if(ss_rtcp->tot_msgnum<1) ss_rtcp->tot_msgnum=1; - ss_rtcp->recvmsgnum=-1; - ss_rtcp->chnum=chnum_rtcp; + ss->input_ev = ev; + ss->tot_msgnum = messagenumber; + ss->recvmsgnum = -1; + ss->chnum = chnum; + + if (!no_rtcp) { + + ss_rtcp->state = UR_STATE_READY; + + ss_rtcp->input_ev = ev_rtcp; + ss_rtcp->tot_msgnum = ss->tot_msgnum; + if (ss_rtcp->tot_msgnum < 1) + ss_rtcp->tot_msgnum = 1; + ss_rtcp->recvmsgnum = -1; + ss_rtcp->chnum = chnum_rtcp; } - - elems[i]=ss; + + elems[i] = ss; refresh_channel(ss, 0, 600); - if(!no_rtcp) - elems[i+1]=ss_rtcp; + if (!no_rtcp) + elems[i + 1] = ss_rtcp; return 0; } -static int start_c2c(const char *remote_address, int port, - const unsigned char* ifname, const char *local_address, - int messagenumber, - int i) { +static int start_c2c(const char *remote_address, int port, const unsigned char *ifname, const char *local_address, + int messagenumber, int i) { - app_ur_session* ss1=create_new_ss(); - app_ur_session* ss1_rtcp=NULL; + app_ur_session *ss1 = create_new_ss(); + app_ur_session *ss1_rtcp = NULL; - if(!no_rtcp) + if (!no_rtcp) ss1_rtcp = create_new_ss(); - app_ur_session* ss2=create_new_ss(); - app_ur_session* ss2_rtcp=NULL; + app_ur_session *ss2 = create_new_ss(); + app_ur_session *ss2_rtcp = NULL; - if(!no_rtcp) + if (!no_rtcp) ss2_rtcp = create_new_ss(); app_ur_conn_info clnet_info_probe; /* for load balancing probe */ memset(&clnet_info_probe, 0, sizeof(clnet_info_probe)); clnet_info_probe.fd = -1; - app_ur_conn_info *clnet_info1=&(ss1->pinfo); - app_ur_conn_info *clnet_info1_rtcp=NULL; + app_ur_conn_info *clnet_info1 = &(ss1->pinfo); + app_ur_conn_info *clnet_info1_rtcp = NULL; - if(!no_rtcp) + if (!no_rtcp) clnet_info1_rtcp = &(ss1_rtcp->pinfo); - app_ur_conn_info *clnet_info2=&(ss2->pinfo); - app_ur_conn_info *clnet_info2_rtcp=NULL; + app_ur_conn_info *clnet_info2 = &(ss2->pinfo); + app_ur_conn_info *clnet_info2_rtcp = NULL; - if(!no_rtcp) + if (!no_rtcp) clnet_info2_rtcp = &(ss2_rtcp->pinfo); - uint16_t chnum1=0; - uint16_t chnum1_rtcp=0; - uint16_t chnum2=0; - uint16_t chnum2_rtcp=0; + uint16_t chnum1 = 0; + uint16_t chnum1_rtcp = 0; + uint16_t chnum2 = 0; + uint16_t chnum2_rtcp = 0; - start_c2c_connection(port, remote_address, - ifname, local_address, - clnet_verbose, - &clnet_info_probe, - clnet_info1, &chnum1, - clnet_info1_rtcp, &chnum1_rtcp, - clnet_info2, &chnum2, - clnet_info2_rtcp, &chnum2_rtcp); - - if(clnet_info_probe.ssl) { - SSL_free(clnet_info_probe.ssl); - clnet_info_probe.fd = -1; - } else if(clnet_info_probe.fd != -1) { - socket_closesocket(clnet_info_probe.fd); - clnet_info_probe.fd = -1; + start_c2c_connection(port, remote_address, ifname, local_address, clnet_verbose, &clnet_info_probe, clnet_info1, + &chnum1, clnet_info1_rtcp, &chnum1_rtcp, clnet_info2, &chnum2, clnet_info2_rtcp, &chnum2_rtcp); + + if (clnet_info_probe.ssl) { + SSL_free(clnet_info_probe.ssl); + clnet_info_probe.fd = -1; + } else if (clnet_info_probe.fd != -1) { + socket_closesocket(clnet_info_probe.fd); + clnet_info_probe.fd = -1; } - + socket_set_nonblocking(clnet_info1->fd); - - if(!no_rtcp) - socket_set_nonblocking(clnet_info1_rtcp->fd); - + + if (!no_rtcp) + socket_set_nonblocking(clnet_info1_rtcp->fd); + socket_set_nonblocking(clnet_info2->fd); - - if(!no_rtcp) - socket_set_nonblocking(clnet_info2_rtcp->fd); - - struct event* ev1 = event_new(client_event_base,clnet_info1->fd, - EV_READ|EV_PERSIST,client_input_handler, - ss1); - event_add(ev1,NULL); - - struct event* ev1_rtcp = NULL; + if (!no_rtcp) + socket_set_nonblocking(clnet_info2_rtcp->fd); - if(!no_rtcp) { - ev1_rtcp = event_new(client_event_base,clnet_info1_rtcp->fd, - EV_READ|EV_PERSIST,client_input_handler, - ss1_rtcp); - - event_add(ev1_rtcp,NULL); + struct event *ev1 = event_new(client_event_base, clnet_info1->fd, EV_READ | EV_PERSIST, client_input_handler, ss1); + + event_add(ev1, NULL); + + struct event *ev1_rtcp = NULL; + + if (!no_rtcp) { + ev1_rtcp = event_new(client_event_base, clnet_info1_rtcp->fd, EV_READ | EV_PERSIST, client_input_handler, ss1_rtcp); + + event_add(ev1_rtcp, NULL); } - struct event* ev2 = event_new(client_event_base,clnet_info2->fd, - EV_READ|EV_PERSIST,client_input_handler, - ss2); + struct event *ev2 = event_new(client_event_base, clnet_info2->fd, EV_READ | EV_PERSIST, client_input_handler, ss2); - event_add(ev2,NULL); - - struct event* ev2_rtcp = NULL; + event_add(ev2, NULL); - if(!no_rtcp) { - ev2_rtcp = event_new(client_event_base,clnet_info2_rtcp->fd, - EV_READ|EV_PERSIST,client_input_handler, - ss2_rtcp); - - event_add(ev2_rtcp,NULL); + struct event *ev2_rtcp = NULL; + + if (!no_rtcp) { + ev2_rtcp = event_new(client_event_base, clnet_info2_rtcp->fd, EV_READ | EV_PERSIST, client_input_handler, ss2_rtcp); + + event_add(ev2_rtcp, NULL); } - ss1->state=UR_STATE_READY; - - ss1->input_ev=ev1; - ss1->tot_msgnum=messagenumber; - ss1->recvmsgnum=-1; - ss1->chnum=chnum1; + ss1->state = UR_STATE_READY; - if(!no_rtcp) { + ss1->input_ev = ev1; + ss1->tot_msgnum = messagenumber; + ss1->recvmsgnum = -1; + ss1->chnum = chnum1; - ss1_rtcp->state=UR_STATE_READY; - - ss1_rtcp->input_ev=ev1_rtcp; - ss1_rtcp->tot_msgnum=ss1->tot_msgnum; - if(ss1_rtcp->tot_msgnum<1) ss1_rtcp->tot_msgnum=1; - ss1_rtcp->recvmsgnum=-1; - ss1_rtcp->chnum=chnum1_rtcp; + if (!no_rtcp) { + + ss1_rtcp->state = UR_STATE_READY; + + ss1_rtcp->input_ev = ev1_rtcp; + ss1_rtcp->tot_msgnum = ss1->tot_msgnum; + if (ss1_rtcp->tot_msgnum < 1) + ss1_rtcp->tot_msgnum = 1; + ss1_rtcp->recvmsgnum = -1; + ss1_rtcp->chnum = chnum1_rtcp; } - ss2->state=UR_STATE_READY; - - ss2->input_ev=ev2; - ss2->tot_msgnum=ss1->tot_msgnum; - ss2->recvmsgnum=-1; - ss2->chnum=chnum2; + ss2->state = UR_STATE_READY; - if(!no_rtcp) { - ss2_rtcp->state=UR_STATE_READY; - - ss2_rtcp->input_ev=ev2_rtcp; - ss2_rtcp->tot_msgnum=ss1_rtcp->tot_msgnum; - ss2_rtcp->recvmsgnum=-1; - ss2_rtcp->chnum=chnum2_rtcp; + ss2->input_ev = ev2; + ss2->tot_msgnum = ss1->tot_msgnum; + ss2->recvmsgnum = -1; + ss2->chnum = chnum2; + + if (!no_rtcp) { + ss2_rtcp->state = UR_STATE_READY; + + ss2_rtcp->input_ev = ev2_rtcp; + ss2_rtcp->tot_msgnum = ss1_rtcp->tot_msgnum; + ss2_rtcp->recvmsgnum = -1; + ss2_rtcp->chnum = chnum2_rtcp; } - - elems[i++]=ss1; - if(!no_rtcp) - elems[i++]=ss1_rtcp; - elems[i++]=ss2; - if(!no_rtcp) - elems[i++]=ss2_rtcp; + + elems[i++] = ss1; + if (!no_rtcp) + elems[i++] = ss1_rtcp; + elems[i++] = ss2; + if (!no_rtcp) + elems[i++] = ss2_rtcp; return 0; } -static int refresh_channel(app_ur_session* elem, uint16_t method, uint32_t lt) -{ +static int refresh_channel(app_ur_session *elem, uint16_t method, uint32_t lt) { - stun_buffer message; - app_ur_conn_info *clnet_info = &(elem->pinfo); + stun_buffer message; + app_ur_conn_info *clnet_info = &(elem->pinfo); - if(clnet_info->is_peer) - return 0; + if (clnet_info->is_peer) + return 0; - if (!method || (method == STUN_METHOD_REFRESH)) { - stun_init_request(STUN_METHOD_REFRESH, &message); - lt = htonl(lt); - stun_attr_add(&message, STUN_ATTRIBUTE_LIFETIME, (const char*) <, 4); + if (!method || (method == STUN_METHOD_REFRESH)) { + stun_init_request(STUN_METHOD_REFRESH, &message); + lt = htonl(lt); + stun_attr_add(&message, STUN_ATTRIBUTE_LIFETIME, (const char *)<, 4); - if(dual_allocation && !mobility) { - int t = ((uint8_t)turn_random())%3; - if(t) { - uint8_t field[4]; - field[0] = (t==1) ? (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4 : (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; - field[1]=0; - field[2]=0; - field[3]=0; - stun_attr_add(&message, STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY, (const char*) field, 4); - } - } + if (dual_allocation && !mobility) { + int t = ((uint8_t)turn_random()) % 3; + if (t) { + uint8_t field[4]; + field[0] = (t == 1) ? (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4 + : (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; + field[1] = 0; + field[2] = 0; + field[3] = 0; + stun_attr_add(&message, STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY, (const char *)field, 4); + } + } - add_origin(&message); - if(add_integrity(clnet_info, &message)<0) return -1; - if(use_fingerprints) - stun_attr_add_fingerprint_str(message.buf, (size_t*) &(message.len)); - send_buffer(clnet_info, &message, 0,0); - } + add_origin(&message); + if (add_integrity(clnet_info, &message) < 0) + return -1; + if (use_fingerprints) + stun_attr_add_fingerprint_str(message.buf, (size_t *)&(message.len)); + send_buffer(clnet_info, &message, 0, 0); + } - if (lt && !addr_any(&(elem->pinfo.peer_addr))) { + if (lt && !addr_any(&(elem->pinfo.peer_addr))) { - if(!no_permissions) { - if (!method || (method == STUN_METHOD_CREATE_PERMISSION)) { - stun_init_request(STUN_METHOD_CREATE_PERMISSION, &message); - stun_attr_add_addr(&message, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &(elem->pinfo.peer_addr)); - add_origin(&message); - if(add_integrity(clnet_info, &message)<0) return -1; - if(use_fingerprints) - stun_attr_add_fingerprint_str(message.buf, (size_t*) &(message.len)); - send_buffer(&(elem->pinfo), &message, 0,0); - } - } + if (!no_permissions) { + if (!method || (method == STUN_METHOD_CREATE_PERMISSION)) { + stun_init_request(STUN_METHOD_CREATE_PERMISSION, &message); + stun_attr_add_addr(&message, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &(elem->pinfo.peer_addr)); + add_origin(&message); + if (add_integrity(clnet_info, &message) < 0) + return -1; + if (use_fingerprints) + stun_attr_add_fingerprint_str(message.buf, (size_t *)&(message.len)); + send_buffer(&(elem->pinfo), &message, 0, 0); + } + } - if (!method || (method == STUN_METHOD_CHANNEL_BIND)) { - if (STUN_VALID_CHANNEL(elem->chnum)) { - stun_set_channel_bind_request(&message, &(elem->pinfo.peer_addr), elem->chnum); - add_origin(&message); - if(add_integrity(clnet_info, &message)<0) return -1; - if(use_fingerprints) - stun_attr_add_fingerprint_str(message.buf, (size_t*) &(message.len)); - send_buffer(&(elem->pinfo), &message,1,0); - } - } - } + if (!method || (method == STUN_METHOD_CHANNEL_BIND)) { + if (STUN_VALID_CHANNEL(elem->chnum)) { + stun_set_channel_bind_request(&message, &(elem->pinfo.peer_addr), elem->chnum); + add_origin(&message); + if (add_integrity(clnet_info, &message) < 0) + return -1; + if (use_fingerprints) + stun_attr_add_fingerprint_str(message.buf, (size_t *)&(message.len)); + send_buffer(&(elem->pinfo), &message, 1, 0); + } + } + } - elem->refresh_time = current_mstime + 30*1000; + elem->refresh_time = current_mstime + 30 * 1000; - return 0; + return 0; } -static inline int client_timer_handler(app_ur_session* elem, int *done) -{ - if (elem) { - if (!turn_time_before(current_mstime, elem->refresh_time)) { - refresh_channel(elem, 0, 600); - } +static inline int client_timer_handler(app_ur_session *elem, int *done) { + if (elem) { + if (!turn_time_before(current_mstime, elem->refresh_time)) { + refresh_channel(elem, 0, 600); + } - if(hang_on && elem->completed) - return 0; + if (hang_on && elem->completed) + return 0; - int max_num = 50; - int cur_num = 0; + int max_num = 50; + int cur_num = 0; - while (!turn_time_before(current_mstime, elem->to_send_timems)) { - if(cur_num++>=max_num) - break; - if (elem->wmsgnum >= elem->tot_msgnum) { - if (!turn_time_before(current_mstime, elem->finished_time) || - (tot_recv_messages>=tot_messages)) { - /* - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s: elem=0x%x: 111.111: c=%d, t=%d, r=%d, w=%d\n",__FUNCTION__,(int)elem,elem->wait_cycles,elem->tot_msgnum,elem->rmsgnum,elem->wmsgnum); - */ - /* - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s: 111.222: ly=%llu, ls=%llu, j=%llu\n",__FUNCTION__, - (unsigned long long)elem->latency, - (unsigned long long)elem->loss, - (unsigned long long)elem->jitter); - */ - total_loss += elem->loss; - elem->loss=0; - total_latency += elem->latency; - elem->latency=0; - total_jitter += elem->jitter; - elem->jitter=0; - elem->completed = 1; - if (!hang_on) { - refresh_channel(elem,0,0); - client_shutdown(elem); - return 1; - } else { - return 0; - } - } - } else { - *done += 1; - client_write(elem); - elem->finished_time = current_mstime + STOPPING_TIME*1000; - } - } - } + while (!turn_time_before(current_mstime, elem->to_send_timems)) { + if (cur_num++ >= max_num) + break; + if (elem->wmsgnum >= elem->tot_msgnum) { + if (!turn_time_before(current_mstime, elem->finished_time) || (tot_recv_messages >= tot_messages)) { + /* + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s: elem=0x%x: 111.111: c=%d, t=%d, r=%d, + w=%d\n",__FUNCTION__,(int)elem,elem->wait_cycles,elem->tot_msgnum,elem->rmsgnum,elem->wmsgnum); + */ + /* + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s: 111.222: ly=%llu, ls=%llu, j=%llu\n",__FUNCTION__, + (unsigned long long)elem->latency, + (unsigned long long)elem->loss, + (unsigned long long)elem->jitter); + */ + total_loss += elem->loss; + elem->loss = 0; + total_latency += elem->latency; + elem->latency = 0; + total_jitter += elem->jitter; + elem->jitter = 0; + elem->completed = 1; + if (!hang_on) { + refresh_channel(elem, 0, 0); + client_shutdown(elem); + return 1; + } else { + return 0; + } + } + } else { + *done += 1; + client_write(elem); + elem->finished_time = current_mstime + STOPPING_TIME * 1000; + } + } + } - return 0; + return 0; } -static void timer_handler(evutil_socket_t fd, short event, void *arg) -{ - UNUSED_ARG(fd); - UNUSED_ARG(event); - UNUSED_ARG(arg); +static void timer_handler(evutil_socket_t fd, short event, void *arg) { + UNUSED_ARG(fd); + UNUSED_ARG(event); + UNUSED_ARG(arg); - __turn_getMSTime(); + __turn_getMSTime(); - if(start_full_timer) { - int i = 0; - int done = 0; - for (i = 0; i < total_clients; ++i) { - if (elems[i]) { - int finished = client_timer_handler(elems[i], &done); - if (finished) { - elems[i] = NULL; - } - } - } - if(done>5 && (dos || random_disconnect)) { - for (i = 0; i < total_clients; ++i) { - if (elems[i]) { - close(elems[i]->pinfo.fd); - elems[i]->pinfo.fd = -1; - } - } - } - } + if (start_full_timer) { + int i = 0; + int done = 0; + for (i = 0; i < total_clients; ++i) { + if (elems[i]) { + int finished = client_timer_handler(elems[i], &done); + if (finished) { + elems[i] = NULL; + } + } + } + if (done > 5 && (dos || random_disconnect)) { + for (i = 0; i < total_clients; ++i) { + if (elems[i]) { + close(elems[i]->pinfo.fd); + elems[i]->pinfo.fd = -1; + } + } + } + } } -void start_mclient(const char *remote_address, int port, - const unsigned char* ifname, const char *local_address, - int messagenumber, int mclient) { +void start_mclient(const char *remote_address, int port, const unsigned char *ifname, const char *local_address, + int messagenumber, int mclient) { - if (mclient < 1) - mclient = 1; + if (mclient < 1) + mclient = 1; - total_clients = mclient; + total_clients = mclient; - if(c2c) { - //mclient must be a multiple of 4: - if(!no_rtcp) - mclient += ((4 - (mclient & 0x00000003)) & 0x00000003); - else if(mclient & 0x1) - ++mclient; - } else { - if(!no_rtcp) - if(mclient & 0x1) - ++mclient; - } + if (c2c) { + // mclient must be a multiple of 4: + if (!no_rtcp) + mclient += ((4 - (mclient & 0x00000003)) & 0x00000003); + else if (mclient & 0x1) + ++mclient; + } else { + if (!no_rtcp) + if (mclient & 0x1) + ++mclient; + } - elems = (app_ur_session**)malloc(sizeof(app_ur_session)*((mclient*2)+1)+sizeof(void*)); + elems = (app_ur_session **)malloc(sizeof(app_ur_session) * ((mclient * 2) + 1) + sizeof(void *)); - __turn_getMSTime(); - uint32_t stime = current_time; + __turn_getMSTime(); + uint32_t stime = current_time; - memset(buffer_to_send, 7, clmessage_length); + memset(buffer_to_send, 7, clmessage_length); - client_event_base = turn_event_base_new(); + client_event_base = turn_event_base_new(); - int i = 0; - int tot_clients = 0; + int i = 0; + int tot_clients = 0; - if(c2c) { - if(!no_rtcp) - for (i = 0; i < (mclient >> 2); i++) { - if(!dos) usleep(SLEEP_INTERVAL); - if (start_c2c(remote_address, port, ifname, local_address, - messagenumber, i << 2) < 0) { - exit(-1); - } - tot_clients+=4; - } - else - for (i = 0; i < (mclient >> 1); i++) { - if(!dos) usleep(SLEEP_INTERVAL); - if (start_c2c(remote_address, port, ifname, local_address, - messagenumber, i << 1) < 0) { - exit(-1); - } - tot_clients+=2; - } - } else { - if(!no_rtcp) - for (i = 0; i < (mclient >> 1); i++) { - if(!dos) usleep(SLEEP_INTERVAL); - if (start_client(remote_address, port, ifname, local_address, - messagenumber, i << 1) < 0) { - exit(-1); - } - tot_clients+=2; - } - else - for (i = 0; i < mclient; i++) { - if(!dos) usleep(SLEEP_INTERVAL); - if (start_client(remote_address, port, ifname, local_address, - messagenumber, i) < 0) { - exit(-1); - } - tot_clients++; - } - } + if (c2c) { + if (!no_rtcp) + for (i = 0; i < (mclient >> 2); i++) { + if (!dos) + usleep(SLEEP_INTERVAL); + if (start_c2c(remote_address, port, ifname, local_address, messagenumber, i << 2) < 0) { + exit(-1); + } + tot_clients += 4; + } + else + for (i = 0; i < (mclient >> 1); i++) { + if (!dos) + usleep(SLEEP_INTERVAL); + if (start_c2c(remote_address, port, ifname, local_address, messagenumber, i << 1) < 0) { + exit(-1); + } + tot_clients += 2; + } + } else { + if (!no_rtcp) + for (i = 0; i < (mclient >> 1); i++) { + if (!dos) + usleep(SLEEP_INTERVAL); + if (start_client(remote_address, port, ifname, local_address, messagenumber, i << 1) < 0) { + exit(-1); + } + tot_clients += 2; + } + else + for (i = 0; i < mclient; i++) { + if (!dos) + usleep(SLEEP_INTERVAL); + if (start_client(remote_address, port, ifname, local_address, messagenumber, i) < 0) { + exit(-1); + } + tot_clients++; + } + } - if(dos) - _exit(0); + if (dos) + _exit(0); - total_clients = tot_clients; + total_clients = tot_clients; - __turn_getMSTime(); + __turn_getMSTime(); - struct event *ev = event_new(client_event_base, -1, EV_TIMEOUT|EV_PERSIST, timer_handler, NULL); - struct timeval tv; + struct event *ev = event_new(client_event_base, -1, EV_TIMEOUT | EV_PERSIST, timer_handler, NULL); + struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 1000; + tv.tv_sec = 0; + tv.tv_usec = 1000; - evtimer_add(ev,&tv); + evtimer_add(ev, &tv); - for(i=0;ipinfo.is_peer) { - int connect_err = 0; - socket_connect(elems[i]->pinfo.fd, &(elems[i]->pinfo.remote_addr), &connect_err); - } - } else { - int j = 0; - for(j=i+1;jpinfo), &(elems[j]->pinfo.relay_addr)) < 0) { - exit(-1); - } - } - } - } - run_events(1); - } + if (is_TCP_relay()) { + if (passive_tcp) { + if (elems[i]->pinfo.is_peer) { + int connect_err = 0; + socket_connect(elems[i]->pinfo.fd, &(elems[i]->pinfo.remote_addr), &connect_err); + } + } else { + int j = 0; + for (j = i + 1; j < total_clients; j++) { + if (turn_tcp_connect(clnet_verbose, &(elems[i]->pinfo), &(elems[j]->pinfo.relay_addr)) < 0) { + exit(-1); + } + } + } + } + run_events(1); + } - __turn_getMSTime(); + __turn_getMSTime(); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Total connect time is %u\n", - ((unsigned int) (current_time - stime))); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Total connect time is %u\n", ((unsigned int)(current_time - stime))); - stime = current_time; + stime = current_time; - if(is_TCP_relay()) { - uint64_t connect_wait_start_time = current_time; - while(1) { - int i = 0; - int completed = 0; - if(passive_tcp) { - for(i=0;ipinfo.is_peer) { - completed+=1; - } else if(elems[i]->pinfo.tcp_conn_number>0 && - elems[i]->pinfo.tcp_conn[0]->tcp_data_bound) { - completed += elems[i]->pinfo.tcp_conn_number; - } - } - if(completed >= total_clients) - break; - } else { - for(i=0;ipinfo.tcp_conn_number;j++) { - if(elems[i]->pinfo.tcp_conn[j]->tcp_data_bound) { - completed++; - } - } - } - if(completed >= total_clients*(total_clients-1)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%d connections are completed\n",(int)(completed)); - break; - } - } - run_events(0); - if(current_time > connect_wait_start_time + STARTING_TCP_RELAY_TIME + total_clients) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: %d connections are completed, not enough\n", - (int)(completed)); - break; - } - } - } + if (is_TCP_relay()) { + uint64_t connect_wait_start_time = current_time; + while (1) { + int i = 0; + int completed = 0; + if (passive_tcp) { + for (i = 0; i < total_clients; ++i) { + if (elems[i]->pinfo.is_peer) { + completed += 1; + } else if (elems[i]->pinfo.tcp_conn_number > 0 && elems[i]->pinfo.tcp_conn[0]->tcp_data_bound) { + completed += elems[i]->pinfo.tcp_conn_number; + } + } + if (completed >= total_clients) + break; + } else { + for (i = 0; i < total_clients; ++i) { + int j = 0; + for (j = 0; j < (int)elems[i]->pinfo.tcp_conn_number; j++) { + if (elems[i]->pinfo.tcp_conn[j]->tcp_data_bound) { + completed++; + } + } + } + if (completed >= total_clients * (total_clients - 1)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%d connections are completed\n", (int)(completed)); + break; + } + } + run_events(0); + if (current_time > connect_wait_start_time + STARTING_TCP_RELAY_TIME + total_clients) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: %d connections are completed, not enough\n", (int)(completed)); + break; + } + } + } - __turn_getMSTime(); - stime = current_time; + __turn_getMSTime(); + stime = current_time; - for(i=0;ito_send_timems = current_mstime + 1000 + ((uint32_t)turn_random())%5000; - } + for (i = 0; i < total_clients; i++) { + elems[i]->to_send_timems = current_mstime + 1000 + ((uint32_t)turn_random()) % 5000; + } - tot_messages = elems[0]->tot_msgnum * total_clients; + tot_messages = elems[0]->tot_msgnum * total_clients; - start_full_timer = 1; + start_full_timer = 1; - while (1) { + while (1) { - run_events(1); + run_events(1); - int msz = (int)current_clients_number; - if (msz < 1) { - break; - } + int msz = (int)current_clients_number; + if (msz < 1) { + break; + } - if(show_statistics) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: msz=%d, tot_send_msgs=%lu, tot_recv_msgs=%lu, tot_send_bytes ~ %llu, tot_recv_bytes ~ %llu\n", - __FUNCTION__, msz, (unsigned long) tot_send_messages, - (unsigned long) tot_recv_messages, - (unsigned long long) tot_send_bytes, - (unsigned long long) tot_recv_bytes); - show_statistics=0; - } - } + if (show_statistics) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, + "%s: msz=%d, tot_send_msgs=%lu, tot_recv_msgs=%lu, tot_send_bytes ~ %llu, tot_recv_bytes ~ %llu\n", + __FUNCTION__, msz, (unsigned long)tot_send_messages, (unsigned long)tot_recv_messages, + (unsigned long long)tot_send_bytes, (unsigned long long)tot_recv_bytes); + show_statistics = 0; + } + } - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: tot_send_msgs=%lu, tot_recv_msgs=%lu\n", - __FUNCTION__, - (unsigned long) tot_send_messages, - (unsigned long) tot_recv_messages); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: tot_send_msgs=%lu, tot_recv_msgs=%lu\n", __FUNCTION__, + (unsigned long)tot_send_messages, (unsigned long)tot_recv_messages); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: tot_send_bytes ~ %lu, tot_recv_bytes ~ %lu\n", - __FUNCTION__, - (unsigned long) tot_send_bytes, - (unsigned long) tot_recv_bytes); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: tot_send_bytes ~ %lu, tot_recv_bytes ~ %lu\n", __FUNCTION__, + (unsigned long)tot_send_bytes, (unsigned long)tot_recv_bytes); - if (client_event_base) - event_base_free(client_event_base); + if (client_event_base) + event_base_free(client_event_base); - if(tot_send_messagesnonce[0]) { + + if (oauth && clnet_info->oauth) { + + uint16_t method = stun_get_method_str(message->buf, message->len); + + int cok = clnet_info->cok; + + if (((method == STUN_METHOD_ALLOCATE) || (method == STUN_METHOD_REFRESH)) || !(clnet_info->key_set)) { + + cok = ((unsigned short)turn_random()) % 3; + clnet_info->cok = cok; + oauth_token otoken; + encoded_oauth_token etoken; + uint8_t nonce[12]; + RAND_bytes((unsigned char *)nonce, 12); + long halflifetime = OAUTH_SESSION_LIFETIME / 2; + long random_lifetime = 0; + while (!random_lifetime) { + random_lifetime = turn_random(); + } + if (random_lifetime < 0) + random_lifetime = -random_lifetime; + random_lifetime = random_lifetime % halflifetime; + otoken.enc_block.lifetime = (uint32_t)(halflifetime + random_lifetime); + otoken.enc_block.timestamp = ((uint64_t)turn_time()) << 16; + if (shatype == SHATYPE_SHA256) { + otoken.enc_block.key_length = 32; + } else if (shatype == SHATYPE_SHA384) { + otoken.enc_block.key_length = 48; + } else if (shatype == SHATYPE_SHA512) { + otoken.enc_block.key_length = 64; + } else { + otoken.enc_block.key_length = 20; + } + RAND_bytes((unsigned char *)(otoken.enc_block.mac_key), otoken.enc_block.key_length); + if (encode_oauth_token(clnet_info->server_name, &etoken, &(okey_array[cok]), &otoken, nonce) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, " Cannot encode token\n"); + return -1; + } + stun_attr_add_str(message->buf, (size_t *)&(message->len), STUN_ATTRIBUTE_OAUTH_ACCESS_TOKEN, + (const uint8_t *)etoken.token, (int)etoken.size); + + memcpy(clnet_info->key, otoken.enc_block.mac_key, otoken.enc_block.key_length); + clnet_info->key_set = 1; + } + + if (stun_attr_add_integrity_by_key_str(message->buf, (size_t *)&(message->len), (uint8_t *)okey_array[cok].kid, + clnet_info->realm, clnet_info->key, clnet_info->nonce, shatype) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, " Cannot add integrity to the message\n"); + return -1; + } + + // self-test: + { + password_t pwd; + if (stun_check_message_integrity_by_key_str(get_turn_credentials_type(), message->buf, (size_t)(message->len), + clnet_info->key, pwd, shatype) < 1) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, " Self-test of integrity does not comple correctly !\n"); + return -1; + } + } + } else { + if (stun_attr_add_integrity_by_user_str(message->buf, (size_t *)&(message->len), g_uname, clnet_info->realm, + g_upwd, clnet_info->nonce, shatype) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, " Cannot add integrity to the message\n"); + return -1; + } + } + } + + return 0; } -int add_integrity(app_ur_conn_info *clnet_info, stun_buffer *message) -{ - if(clnet_info->nonce[0]) { +int check_integrity(app_ur_conn_info *clnet_info, stun_buffer *message) { + SHATYPE sht = shatype; - if(oauth && clnet_info->oauth) { + if (oauth && clnet_info->oauth) { - uint16_t method = stun_get_method_str(message->buf, message->len); + password_t pwd; - int cok = clnet_info->cok; + return stun_check_message_integrity_by_key_str(get_turn_credentials_type(), message->buf, (size_t)(message->len), + clnet_info->key, pwd, sht); - if(((method == STUN_METHOD_ALLOCATE) || (method == STUN_METHOD_REFRESH)) || !(clnet_info->key_set)) - { + } else { - cok=((unsigned short)turn_random())%3; - clnet_info->cok = cok; - oauth_token otoken; - encoded_oauth_token etoken; - uint8_t nonce[12]; - RAND_bytes((unsigned char*)nonce,12); - long halflifetime = OAUTH_SESSION_LIFETIME/2; - long random_lifetime = 0; - while(!random_lifetime) { - random_lifetime = turn_random(); - } - if(random_lifetime<0) random_lifetime=-random_lifetime; - random_lifetime = random_lifetime % halflifetime; - otoken.enc_block.lifetime = (uint32_t)(halflifetime + random_lifetime); - otoken.enc_block.timestamp = ((uint64_t)turn_time()) << 16; - if(shatype == SHATYPE_SHA256) { - otoken.enc_block.key_length = 32; - } else if(shatype == SHATYPE_SHA384) { - otoken.enc_block.key_length = 48; - } else if(shatype == SHATYPE_SHA512) { - otoken.enc_block.key_length = 64; - } else { - otoken.enc_block.key_length = 20; - } - RAND_bytes((unsigned char *)(otoken.enc_block.mac_key), otoken.enc_block.key_length); - if(encode_oauth_token(clnet_info->server_name, &etoken, &(okey_array[cok]), &otoken, nonce)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO," Cannot encode token\n"); - return -1; - } - stun_attr_add_str(message->buf, (size_t*)&(message->len), STUN_ATTRIBUTE_OAUTH_ACCESS_TOKEN, - (const uint8_t*)etoken.token, (int)etoken.size); + if (stun_check_message_integrity_str(get_turn_credentials_type(), message->buf, (size_t)(message->len), g_uname, + clnet_info->realm, g_upwd, sht) < 1) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Wrong integrity in a message received from server\n"); + return -1; + } + } - memcpy(clnet_info->key,otoken.enc_block.mac_key,otoken.enc_block.key_length); - clnet_info->key_set = 1; - } - - if(stun_attr_add_integrity_by_key_str(message->buf, (size_t*)&(message->len), (uint8_t*)okey_array[cok].kid, - clnet_info->realm, clnet_info->key, clnet_info->nonce, shatype)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO," Cannot add integrity to the message\n"); - return -1; - } - - //self-test: - { - password_t pwd; - if(stun_check_message_integrity_by_key_str(get_turn_credentials_type(), - message->buf, (size_t)(message->len), clnet_info->key, pwd, shatype)<1) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR," Self-test of integrity does not comple correctly !\n"); - return -1; - } - } - } else { - if(stun_attr_add_integrity_by_user_str(message->buf, (size_t*)&(message->len), g_uname, - clnet_info->realm, g_upwd, clnet_info->nonce, shatype)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO," Cannot add integrity to the message\n"); - return -1; - } - } - } - - return 0; + return 0; } -int check_integrity(app_ur_conn_info *clnet_info, stun_buffer *message) -{ - SHATYPE sht = shatype; - - if(oauth && clnet_info->oauth) { - - password_t pwd; - - return stun_check_message_integrity_by_key_str(get_turn_credentials_type(), - message->buf, (size_t)(message->len), clnet_info->key, pwd, sht); - - } else { - - if(stun_check_message_integrity_str(get_turn_credentials_type(), - message->buf, (size_t)(message->len), g_uname, - clnet_info->realm, g_upwd, sht)<1) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Wrong integrity in a message received from server\n"); - return -1; - } - } - - return 0; -} - -SOCKET_TYPE get_socket_type(void) -{ - if(use_sctp) { - if(use_secure) { - return TLS_SCTP_SOCKET; - } else { - return SCTP_SOCKET; - } - } else if(use_tcp) { - if(use_secure) { - return TLS_SOCKET; - } else { - return TCP_SOCKET; - } - } else { - if(use_secure) { - return DTLS_SOCKET; - } else { - return UDP_SOCKET; - } - } +SOCKET_TYPE get_socket_type(void) { + if (use_sctp) { + if (use_secure) { + return TLS_SCTP_SOCKET; + } else { + return SCTP_SOCKET; + } + } else if (use_tcp) { + if (use_secure) { + return TLS_SOCKET; + } else { + return TCP_SOCKET; + } + } else { + if (use_secure) { + return DTLS_SOCKET; + } else { + return UDP_SOCKET; + } + } } /////////////////////////////////////////// - diff --git a/src/apps/uclient/uclient.h b/src/apps/uclient/uclient.h index ea0fa64..5ea9da0 100644 --- a/src/apps/uclient/uclient.h +++ b/src/apps/uclient/uclient.h @@ -32,8 +32,8 @@ #define __UCLIENT_ECHO__ #include "ns_turn_utils.h" -#include "stun_buffer.h" #include "session.h" +#include "stun_buffer.h" #include "ns_turn_openssl.h" @@ -60,7 +60,7 @@ extern ioa_addr peer_addr; extern int no_rtcp; extern int default_address_family; extern int dont_fragment; -extern uint8_t g_uname[STUN_MAX_USERNAME_SIZE+1]; +extern uint8_t g_uname[STUN_MAX_USERNAME_SIZE + 1]; extern password_t g_upwd; extern char g_auth_secret[1025]; extern int g_use_auth_secret_with_timestamp; @@ -70,7 +70,7 @@ extern int root_tls_ctx_num; extern int RTP_PACKET_INTERVAL; extern uint8_t relay_transport; extern unsigned char client_ifname[1025]; -extern struct event_base* client_event_base; +extern struct event_base *client_event_base; extern int passive_tcp; extern int mandatory_channel_padding; extern int negative_test; @@ -84,7 +84,7 @@ extern int extra_requests; extern band_limit_t bps; extern int dual_allocation; -extern char origin[STUN_MAX_ORIGIN_SIZE+1]; +extern char origin[STUN_MAX_ORIGIN_SIZE + 1]; extern int oauth; extern oauth_key okey_array[3]; @@ -94,14 +94,14 @@ extern oauth_key okey_array[3]; #define is_TCP_relay() (relay_transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE) -void start_mclient(const char *remote_address, int port, - const unsigned char* ifname, const char *local_address, - int messagenumber, int mclient); +void start_mclient(const char *remote_address, int port, const unsigned char *ifname, const char *local_address, + int messagenumber, int mclient); -int send_buffer(app_ur_conn_info *clnet_info, stun_buffer* message, int data_connection, app_tcp_conn_info *atc); -int recv_buffer(app_ur_conn_info *clnet_info, stun_buffer* message, int sync, int data_connection, app_tcp_conn_info *atc, stun_buffer* request_message); +int send_buffer(app_ur_conn_info *clnet_info, stun_buffer *message, int data_connection, app_tcp_conn_info *atc); +int recv_buffer(app_ur_conn_info *clnet_info, stun_buffer *message, int sync, int data_connection, + app_tcp_conn_info *atc, stun_buffer *request_message); -void client_input_handler(evutil_socket_t fd, short what, void* arg); +void client_input_handler(evutil_socket_t fd, short what, void *arg); turn_credential_type get_turn_credentials_type(void); @@ -117,4 +117,3 @@ SOCKET_TYPE get_socket_type(void); #endif #endif //__UCLIENT_ECHO__ - diff --git a/src/client++/TurnMsgLib.h b/src/client++/TurnMsgLib.h index a286333..90df2ab 100644 --- a/src/client++/TurnMsgLib.h +++ b/src/client++/TurnMsgLib.h @@ -45,8 +45,8 @@ class StunAttr; */ class EndOfStunMsgException { public: - EndOfStunMsgException() {} - virtual ~EndOfStunMsgException() {} + EndOfStunMsgException() {} + virtual ~EndOfStunMsgException() {} }; /** @@ -54,8 +54,8 @@ public: */ class WrongStunAttrFormatException { public: - WrongStunAttrFormatException() {} - virtual ~WrongStunAttrFormatException() {} + WrongStunAttrFormatException() {} + virtual ~WrongStunAttrFormatException() {} }; /** @@ -63,8 +63,8 @@ public: */ class WrongStunBufferFormatException { public: - WrongStunBufferFormatException() {} - virtual ~WrongStunBufferFormatException() {} + WrongStunBufferFormatException() {} + virtual ~WrongStunBufferFormatException() {} }; /** @@ -72,114 +72,101 @@ public: */ class StunAttrIterator { public: - /** - * Iterator constructor: creates iterator on raw messagebuffer. - */ - StunAttrIterator(uint8_t *buf, size_t sz) : - _buf(buf), _sz(sz) { - if(!stun_is_command_message_str(_buf, _sz)) { - throw WrongStunBufferFormatException(); - } - _sar = stun_attr_get_first_str(_buf, _sz); - } + /** + * Iterator constructor: creates iterator on raw messagebuffer. + */ + StunAttrIterator(uint8_t *buf, size_t sz) : _buf(buf), _sz(sz) { + if (!stun_is_command_message_str(_buf, _sz)) { + throw WrongStunBufferFormatException(); + } + _sar = stun_attr_get_first_str(_buf, _sz); + } - /** - * Iterator constructor: create iterator over message. - */ - template - StunAttrIterator(T &msg) : - _buf(msg.getRawBuffer()), _sz(msg.getSize()) { - if(!stun_is_command_message_str(_buf, _sz)) { - throw WrongStunBufferFormatException(); - } - _sar = stun_attr_get_first_str(_buf, _sz); - } + /** + * Iterator constructor: create iterator over message. + */ + template StunAttrIterator(T &msg) : _buf(msg.getRawBuffer()), _sz(msg.getSize()) { + if (!stun_is_command_message_str(_buf, _sz)) { + throw WrongStunBufferFormatException(); + } + _sar = stun_attr_get_first_str(_buf, _sz); + } - /** - * Iterator constructor: creates iterator over raw buffer, starting from first - * location of an attribute of particular type. - */ - StunAttrIterator(uint8_t *buf, size_t sz, uint16_t attr_type) : - _buf(buf), _sz(sz) { - if(!stun_is_command_message_str(_buf, _sz)) { - throw WrongStunBufferFormatException(); - } - _sar = stun_attr_get_first_by_type_str(_buf, _sz, attr_type); - } + /** + * Iterator constructor: creates iterator over raw buffer, starting from first + * location of an attribute of particular type. + */ + StunAttrIterator(uint8_t *buf, size_t sz, uint16_t attr_type) : _buf(buf), _sz(sz) { + if (!stun_is_command_message_str(_buf, _sz)) { + throw WrongStunBufferFormatException(); + } + _sar = stun_attr_get_first_by_type_str(_buf, _sz, attr_type); + } - /** - * Iterator constructor: creates iterator over message, starting from first - * location of an attribute of particular type. - */ - template - StunAttrIterator(T &msg, uint16_t attr_type) : - _buf(msg.getRawBuffer()), _sz(msg.getSize()) { - if(!stun_is_command_message_str(_buf, _sz)) { - throw WrongStunBufferFormatException(); - } - _sar = stun_attr_get_first_by_type_str(_buf, _sz, attr_type); - } + /** + * Iterator constructor: creates iterator over message, starting from first + * location of an attribute of particular type. + */ + template StunAttrIterator(T &msg, uint16_t attr_type) : _buf(msg.getRawBuffer()), _sz(msg.getSize()) { + if (!stun_is_command_message_str(_buf, _sz)) { + throw WrongStunBufferFormatException(); + } + _sar = stun_attr_get_first_by_type_str(_buf, _sz, attr_type); + } - /** - * Moves iterator to next attribute location - */ - void next() { - if(!_sar) { - throw EndOfStunMsgException(); - } - _sar = stun_attr_get_next_str(_buf,_sz,_sar); - } + /** + * Moves iterator to next attribute location + */ + void next() { + if (!_sar) { + throw EndOfStunMsgException(); + } + _sar = stun_attr_get_next_str(_buf, _sz, _sar); + } - /** - * Is the iterator finished - */ - bool eof() const { - return (!_sar); - } + /** + * Is the iterator finished + */ + bool eof() const { return (!_sar); } - /** - * Is the iterator at an address attribute - */ - bool isAddr() const { - return stun_attr_is_addr(_sar); - } + /** + * Is the iterator at an address attribute + */ + bool isAddr() const { return stun_attr_is_addr(_sar); } - /** - * Return address family attribute value (if the iterator at the "address family" attribute. - */ - int getAddressFamily() const { - return stun_get_requested_address_family(_sar); - } + /** + * Return address family attribute value (if the iterator at the "address family" attribute. + */ + int getAddressFamily() const { return stun_get_requested_address_family(_sar); } - /** - * Get attribute type - */ - int getType() const { - return stun_attr_get_type(_sar); - } + /** + * Get attribute type + */ + int getType() const { return stun_attr_get_type(_sar); } - /** - * Destructor - */ - virtual ~StunAttrIterator() {} + /** + * Destructor + */ + virtual ~StunAttrIterator() {} + + /** + * Return raw memroy field of the attribute value. + * If the attribute value length is zero (0), then return NULL. + */ + const uint8_t *getRawBuffer(size_t &sz) const { + int len = stun_attr_get_len(_sar); + if (len < 0) + throw WrongStunAttrFormatException(); + sz = (size_t)len; + const uint8_t *value = stun_attr_get_value(_sar); + return value; + } + friend class StunAttr; - /** - * Return raw memroy field of the attribute value. - * If the attribute value length is zero (0), then return NULL. - */ - const uint8_t *getRawBuffer(size_t &sz) const { - int len = stun_attr_get_len(_sar); - if(len<0) - throw WrongStunAttrFormatException(); - sz = (size_t)len; - const uint8_t *value = stun_attr_get_value(_sar); - return value; - } - friend class StunAttr; private: - uint8_t *_buf; - size_t _sz; - stun_attr_ref _sar; + uint8_t *_buf; + size_t _sz; + stun_attr_ref _sar; }; /** @@ -188,121 +175,115 @@ private: */ class StunAttr { public: - /** - * Empty constructor - */ - StunAttr() : _attr_type(0), _value(0), _sz(0) {} + /** + * Empty constructor + */ + StunAttr() : _attr_type(0), _value(0), _sz(0) {} - /** - * Constructs attribute from iterator - */ - StunAttr(const StunAttrIterator &iter) { - if(iter.eof()) { - throw EndOfStunMsgException(); - } - size_t sz = 0; - const uint8_t *ptr = iter.getRawBuffer(sz); - if(sz>=0xFFFF) - throw WrongStunAttrFormatException(); - int at = iter.getType(); - if(at<0) - throw WrongStunAttrFormatException(); - _attr_type = (uint16_t)at; - _sz = sz; - _value=(uint8_t*)malloc(_sz); - if(ptr) - memcpy(_value,ptr,_sz); - } + /** + * Constructs attribute from iterator + */ + StunAttr(const StunAttrIterator &iter) { + if (iter.eof()) { + throw EndOfStunMsgException(); + } + size_t sz = 0; + const uint8_t *ptr = iter.getRawBuffer(sz); + if (sz >= 0xFFFF) + throw WrongStunAttrFormatException(); + int at = iter.getType(); + if (at < 0) + throw WrongStunAttrFormatException(); + _attr_type = (uint16_t)at; + _sz = sz; + _value = (uint8_t *)malloc(_sz); + if (ptr) + memcpy(_value, ptr, _sz); + } - /** - * Destructor - */ - virtual ~StunAttr() { - if(_value) - free(_value); - } + /** + * Destructor + */ + virtual ~StunAttr() { + if (_value) + free(_value); + } - /** - * Return raw data representation of the attribute - */ - const uint8_t *getRawValue(size_t &sz) const { - sz=_sz; - return _value; - } + /** + * Return raw data representation of the attribute + */ + const uint8_t *getRawValue(size_t &sz) const { + sz = _sz; + return _value; + } - /** - * Set raw data value - */ - void setRawValue(uint8_t *value, size_t sz) { - if(sz>0xFFFF) - throw WrongStunAttrFormatException(); - if(_value) - free(_value); - _sz = sz; - _value=(uint8_t*)malloc(_sz); - if(value) - memcpy(_value,value,_sz); - } + /** + * Set raw data value + */ + void setRawValue(uint8_t *value, size_t sz) { + if (sz > 0xFFFF) + throw WrongStunAttrFormatException(); + if (_value) + free(_value); + _sz = sz; + _value = (uint8_t *)malloc(_sz); + if (value) + memcpy(_value, value, _sz); + } - /** - * Get attribute type - */ - uint16_t getType() const { - return _attr_type; - } + /** + * Get attribute type + */ + uint16_t getType() const { return _attr_type; } - /** - * Set attribute type - */ - void setType(uint16_t at) { - _attr_type = at; - } + /** + * Set attribute type + */ + void setType(uint16_t at) { _attr_type = at; } + + /** + * Add attribute to a message + */ + template int addToMsg(T &msg) { + if (!_attr_type) + throw WrongStunAttrFormatException(); + uint8_t *buffer = msg.getRawBuffer(); + if (buffer) { + size_t sz = msg.getSize(); + if (addToBuffer(buffer, sz) < 0) { + throw WrongStunBufferFormatException(); + } + msg.setSize(sz); + return 0; + } + throw WrongStunBufferFormatException(); + } - /** - * Add attribute to a message - */ - template - int addToMsg(T &msg) { - if(!_attr_type) - throw WrongStunAttrFormatException(); - uint8_t *buffer = msg.getRawBuffer(); - if(buffer) { - size_t sz = msg.getSize(); - if(addToBuffer(buffer, sz)<0) { - throw WrongStunBufferFormatException(); - } - msg.setSize(sz); - return 0; - } - throw WrongStunBufferFormatException(); - } protected: + /** + * Virtual function member to add attribute to a raw buffer + */ + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { + if (buffer) { + if (!_value) + throw WrongStunAttrFormatException(); + if (stun_attr_add_str(buffer, &sz, _attr_type, _value, _sz) < 0) { + throw WrongStunBufferFormatException(); + } + return 0; + } + throw WrongStunBufferFormatException(); + } - /** - * Virtual function member to add attribute to a raw buffer - */ - virtual int addToBuffer(uint8_t *buffer, size_t &sz) { - if(buffer) { - if(!_value) - throw WrongStunAttrFormatException(); - if(stun_attr_add_str(buffer, &sz, _attr_type, _value, _sz)<0) { - throw WrongStunBufferFormatException(); - } - return 0; - } - throw WrongStunBufferFormatException(); - } + /** + * Get low-level iterator object + */ + static stun_attr_ref getSar(const StunAttrIterator &iter) { return iter._sar; } - /** - * Get low-level iterator object - */ - static stun_attr_ref getSar(const StunAttrIterator &iter) { - return iter._sar; - } private: - uint16_t _attr_type; - uint8_t *_value; - size_t _sz; + uint16_t _attr_type; + uint8_t *_value; + size_t _sz; }; /** @@ -310,31 +291,24 @@ private: */ class StunAttrChannelNumber : public StunAttr { public: - StunAttrChannelNumber() : _cn(0) { - setType(STUN_ATTRIBUTE_CHANNEL_NUMBER); - } - StunAttrChannelNumber(const StunAttrIterator &iter) : - StunAttr(iter) { + StunAttrChannelNumber() : _cn(0) { setType(STUN_ATTRIBUTE_CHANNEL_NUMBER); } + StunAttrChannelNumber(const StunAttrIterator &iter) : StunAttr(iter) { + + if (iter.eof()) + throw EndOfStunMsgException(); + _cn = stun_attr_get_channel_number(getSar(iter)); + if (!_cn) + throw WrongStunAttrFormatException(); + } + virtual ~StunAttrChannelNumber() {} + uint16_t getChannelNumber() const { return _cn; } + void setChannelNumber(uint16_t cn) { _cn = cn; } - if(iter.eof()) - throw EndOfStunMsgException(); - _cn = stun_attr_get_channel_number(getSar(iter)); - if(!_cn) - throw WrongStunAttrFormatException(); - } - virtual ~StunAttrChannelNumber() {} - uint16_t getChannelNumber() const { - return _cn; - } - void setChannelNumber(uint16_t cn) { - _cn = cn; - } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) { - return stun_attr_add_channel_number_str(buffer,&sz,_cn); - } + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_channel_number_str(buffer, &sz, _cn); } + private: - uint16_t _cn; + uint16_t _cn; }; /** @@ -342,29 +316,24 @@ private: */ class StunAttrEvenPort : public StunAttr { public: - StunAttrEvenPort() : _ep(0) { - setType(STUN_ATTRIBUTE_EVEN_PORT); - } - StunAttrEvenPort(const StunAttrIterator &iter) : - StunAttr(iter) { + StunAttrEvenPort() : _ep(0) { setType(STUN_ATTRIBUTE_EVEN_PORT); } + StunAttrEvenPort(const StunAttrIterator &iter) : StunAttr(iter) { + + if (iter.eof()) + throw EndOfStunMsgException(); + _ep = stun_attr_get_even_port(getSar(iter)); + } + virtual ~StunAttrEvenPort() {} + uint8_t getEvenPort() const { return _ep; } + void setEvenPort(uint8_t ep) { _ep = ep; } - if(iter.eof()) - throw EndOfStunMsgException(); - _ep = stun_attr_get_even_port(getSar(iter)); - } - virtual ~StunAttrEvenPort() {} - uint8_t getEvenPort() const { - return _ep; - } - void setEvenPort(uint8_t ep) { - _ep = ep; - } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) { - return stun_attr_add_str(buffer, &sz, STUN_ATTRIBUTE_EVEN_PORT, &_ep, 1); - } + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { + return stun_attr_add_str(buffer, &sz, STUN_ATTRIBUTE_EVEN_PORT, &_ep, 1); + } + private: - uint8_t _ep; + uint8_t _ep; }; /** @@ -372,30 +341,25 @@ private: */ class StunAttrReservationToken : public StunAttr { public: - StunAttrReservationToken() : _rt(0) { - setType(STUN_ATTRIBUTE_RESERVATION_TOKEN); - } - StunAttrReservationToken(const StunAttrIterator &iter) : - StunAttr(iter) { + StunAttrReservationToken() : _rt(0) { setType(STUN_ATTRIBUTE_RESERVATION_TOKEN); } + StunAttrReservationToken(const StunAttrIterator &iter) : StunAttr(iter) { + + if (iter.eof()) + throw EndOfStunMsgException(); + _rt = stun_attr_get_reservation_token_value(getSar(iter)); + } + virtual ~StunAttrReservationToken() {} + uint64_t getReservationToken() const { return _rt; } + void setReservationToken(uint64_t rt) { _rt = rt; } - if(iter.eof()) - throw EndOfStunMsgException(); - _rt = stun_attr_get_reservation_token_value(getSar(iter)); - } - virtual ~StunAttrReservationToken() {} - uint64_t getReservationToken() const { - return _rt; - } - void setReservationToken(uint64_t rt) { - _rt = rt; - } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) { - uint64_t reservation_token = ioa_ntoh64(_rt); - return stun_attr_add_str(buffer, &sz, STUN_ATTRIBUTE_RESERVATION_TOKEN, (uint8_t*) (&reservation_token), 8); - } + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { + uint64_t reservation_token = ioa_ntoh64(_rt); + return stun_attr_add_str(buffer, &sz, STUN_ATTRIBUTE_RESERVATION_TOKEN, (uint8_t *)(&reservation_token), 8); + } + private: - uint64_t _rt; + uint64_t _rt; }; /** @@ -403,34 +367,31 @@ private: */ class StunAttrAddr : public StunAttr { public: - StunAttrAddr(uint16_t attr_type = 0) { - addr_set_any(&_addr); - setType(attr_type); - } - StunAttrAddr(const StunAttrIterator &iter) : - StunAttr(iter) { + StunAttrAddr(uint16_t attr_type = 0) { + addr_set_any(&_addr); + setType(attr_type); + } + StunAttrAddr(const StunAttrIterator &iter) : StunAttr(iter) { + + if (iter.eof()) + throw EndOfStunMsgException(); + size_t sz = 0; + const uint8_t *buf = iter.getRawBuffer(sz); + if (stun_attr_get_addr_str(buf, sz, getSar(iter), &_addr, NULL) < 0) { + throw WrongStunAttrFormatException(); + } + } + virtual ~StunAttrAddr() {} + void getAddr(ioa_addr &addr) const { addr_cpy(&addr, &_addr); } + void setAddr(ioa_addr &addr) { addr_cpy(&_addr, &addr); } - if(iter.eof()) - throw EndOfStunMsgException(); - size_t sz = 0; - const uint8_t *buf = iter.getRawBuffer(sz); - if(stun_attr_get_addr_str(buf,sz,getSar(iter),&_addr,NULL)<0) { - throw WrongStunAttrFormatException(); - } - } - virtual ~StunAttrAddr() {} - void getAddr(ioa_addr &addr) const { - addr_cpy(&addr,&_addr); - } - void setAddr(ioa_addr &addr) { - addr_cpy(&_addr,&addr); - } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) { - return stun_attr_add_addr_str(buffer, &sz, getType(), &_addr); - } + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { + return stun_attr_add_addr_str(buffer, &sz, getType(), &_addr); + } + private: - ioa_addr _addr; + ioa_addr _addr; }; /** @@ -438,45 +399,40 @@ private: */ class StunAttrChangeRequest : public StunAttr { public: - StunAttrChangeRequest() : _changeIp(0), _changePort(0) { - setType(STUN_ATTRIBUTE_CHANGE_REQUEST); - } - StunAttrChangeRequest(const StunAttrIterator &iter) : - StunAttr(iter) { + StunAttrChangeRequest() : _changeIp(0), _changePort(0) { setType(STUN_ATTRIBUTE_CHANGE_REQUEST); } + StunAttrChangeRequest(const StunAttrIterator &iter) : StunAttr(iter) { - if(iter.eof()) - throw EndOfStunMsgException(); + if (iter.eof()) + throw EndOfStunMsgException(); + + if (stun_attr_get_change_request_str(getSar(iter), &_changeIp, &_changePort) < 0) { + throw WrongStunAttrFormatException(); + } + } + virtual ~StunAttrChangeRequest() {} + bool getChangeIp() const { return _changeIp; } + void setChangeIp(bool ci) { + if (ci) + _changeIp = 1; + else + _changeIp = 0; + } + bool getChangePort() const { return _changePort; } + void setChangePort(bool cp) { + if (cp) + _changePort = 1; + else + _changePort = 0; + } - if(stun_attr_get_change_request_str(getSar(iter), &_changeIp, &_changePort)<0) { - throw WrongStunAttrFormatException(); - } - } - virtual ~StunAttrChangeRequest() {} - bool getChangeIp() const { - return _changeIp; - } - void setChangeIp(bool ci) { - if(ci) - _changeIp = 1; - else - _changeIp = 0; - } - bool getChangePort() const { - return _changePort; - } - void setChangePort(bool cp) { - if(cp) - _changePort = 1; - else - _changePort = 0; - } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) { - return stun_attr_add_change_request_str(buffer, &sz, _changeIp, _changePort); - } + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { + return stun_attr_add_change_request_str(buffer, &sz, _changeIp, _changePort); + } + private: - int _changeIp; - int _changePort; + int _changeIp; + int _changePort; }; /** @@ -484,34 +440,27 @@ private: */ class StunAttrResponsePort : public StunAttr { public: - StunAttrResponsePort() : _rp(0) { - setType(STUN_ATTRIBUTE_RESPONSE_PORT); - } - StunAttrResponsePort(const StunAttrIterator &iter) : - StunAttr(iter) { + StunAttrResponsePort() : _rp(0) { setType(STUN_ATTRIBUTE_RESPONSE_PORT); } + StunAttrResponsePort(const StunAttrIterator &iter) : StunAttr(iter) { - if(iter.eof()) - throw EndOfStunMsgException(); + if (iter.eof()) + throw EndOfStunMsgException(); + + int rp = stun_attr_get_response_port_str(getSar(iter)); + if (rp < 0) { + throw WrongStunAttrFormatException(); + } + _rp = (uint16_t)rp; + } + virtual ~StunAttrResponsePort() {} + uint16_t getResponsePort() const { return _rp; } + void setResponsePort(uint16_t p) { _rp = p; } - int rp = stun_attr_get_response_port_str(getSar(iter)); - if(rp<0) { - throw WrongStunAttrFormatException(); - } - _rp = (uint16_t)rp; - } - virtual ~StunAttrResponsePort() {} - uint16_t getResponsePort() const { - return _rp; - } - void setResponsePort(uint16_t p) { - _rp = p; - } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) { - return stun_attr_add_response_port_str(buffer, &sz, _rp); - } + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_response_port_str(buffer, &sz, _rp); } + private: - uint16_t _rp; + uint16_t _rp; }; /** @@ -519,37 +468,30 @@ private: */ class StunAttrPadding : public StunAttr { public: - StunAttrPadding() : _p(0) { - setType(STUN_ATTRIBUTE_PADDING); - } - StunAttrPadding(const StunAttrIterator &iter) : - StunAttr(iter) { + StunAttrPadding() : _p(0) { setType(STUN_ATTRIBUTE_PADDING); } + StunAttrPadding(const StunAttrIterator &iter) : StunAttr(iter) { - if(iter.eof()) - throw EndOfStunMsgException(); + if (iter.eof()) + throw EndOfStunMsgException(); + + int p = stun_attr_get_padding_len_str(getSar(iter)); + if (p < 0) { + throw WrongStunAttrFormatException(); + } + _p = (uint16_t)p; + } + virtual ~StunAttrPadding() {} + uint16_t getPadding() const { return _p; } + /** + * Set length of padding + */ + void setPadding(uint16_t p) { _p = p; } - int p = stun_attr_get_padding_len_str(getSar(iter)); - if(p<0) { - throw WrongStunAttrFormatException(); - } - _p = (uint16_t)p; - } - virtual ~StunAttrPadding() {} - uint16_t getPadding() const { - return _p; - } - /** - * Set length of padding - */ - void setPadding(uint16_t p) { - _p = p; - } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) { - return stun_attr_add_padding_str(buffer, &sz, _p); - } + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_padding_str(buffer, &sz, _p); } + private: - uint16_t _p; + uint16_t _p; }; /** @@ -557,239 +499,214 @@ private: */ class StunMsg { public: - /** - * Empty constructor - */ - StunMsg() { - _allocated_sz = 0xFFFF; - _buffer = (uint8_t*)malloc(_allocated_sz); - _deallocate = true; - _sz = 0; - _constructed = 0; - } + /** + * Empty constructor + */ + StunMsg() { + _allocated_sz = 0xFFFF; + _buffer = (uint8_t *)malloc(_allocated_sz); + _deallocate = true; + _sz = 0; + _constructed = 0; + } - /** - * Construct message over raw buffer. - * Parameter "construct" is true if the buffer is initialized. - */ - StunMsg(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) : - _buffer(buffer), _deallocate(false), _allocated_sz(total_sz), - _sz(sz), _constructed(constructed) {} + /** + * Construct message over raw buffer. + * Parameter "construct" is true if the buffer is initialized. + */ + StunMsg(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) + : _buffer(buffer), _deallocate(false), _allocated_sz(total_sz), _sz(sz), _constructed(constructed) {} - /** - * Destructor - */ - virtual ~StunMsg() { - if(_deallocate && _buffer) { - free(_buffer); - } - } + /** + * Destructor + */ + virtual ~StunMsg() { + if (_deallocate && _buffer) { + free(_buffer); + } + } - /** - * Initialize buffer - */ - void construct() { - constructBuffer(); - } + /** + * Initialize buffer + */ + void construct() { constructBuffer(); } - /** - * Checks if the message is properly constructed - */ - bool isValid() { - return check(); - } + /** + * Checks if the message is properly constructed + */ + bool isValid() { return check(); } - /** - * get raw buffer - */ - uint8_t *getRawBuffer() { - return _buffer; - } + /** + * get raw buffer + */ + uint8_t *getRawBuffer() { return _buffer; } - /** - * Get message size in the buffer (message can be mnuch smaller than the whole buffer) - */ - size_t getSize() const { - return _sz; - } + /** + * Get message size in the buffer (message can be mnuch smaller than the whole buffer) + */ + size_t getSize() const { return _sz; } - /** - * Set message size - */ - void setSize(size_t sz) { - if(sz>_allocated_sz) - throw WrongStunBufferFormatException(); - _sz = sz; - } + /** + * Set message size + */ + void setSize(size_t sz) { + if (sz > _allocated_sz) + throw WrongStunBufferFormatException(); + _sz = sz; + } - /** - * Check if the raw buffer is a TURN "command" (request, response or indication). - */ - static bool isCommand(uint8_t *buffer, size_t sz) { - return stun_is_command_message_str(buffer, sz); - } + /** + * Check if the raw buffer is a TURN "command" (request, response or indication). + */ + static bool isCommand(uint8_t *buffer, size_t sz) { return stun_is_command_message_str(buffer, sz); } - /** - * Check if the current message object is a "command" (request, response, or indication). - */ - bool isCommand() const { - return stun_is_command_message_str(_buffer, _sz); - } + /** + * Check if the current message object is a "command" (request, response, or indication). + */ + bool isCommand() const { return stun_is_command_message_str(_buffer, _sz); } - static bool isIndication(uint8_t *buffer, size_t sz) { - return stun_is_indication_str(buffer, sz); - } + static bool isIndication(uint8_t *buffer, size_t sz) { return stun_is_indication_str(buffer, sz); } - static bool isRequest(uint8_t *buffer, size_t sz) { - return stun_is_request_str(buffer, sz); - } + static bool isRequest(uint8_t *buffer, size_t sz) { return stun_is_request_str(buffer, sz); } - static bool isSuccessResponse(uint8_t *buffer, size_t sz) { - return stun_is_success_response_str(buffer, sz); - } + static bool isSuccessResponse(uint8_t *buffer, size_t sz) { return stun_is_success_response_str(buffer, sz); } - static bool isErrorResponse(uint8_t *buffer, size_t sz, - int &err_code, uint8_t *err_msg, size_t err_msg_size) { - return stun_is_error_response_str(buffer, sz, &err_code, err_msg, err_msg_size); - } + static bool isErrorResponse(uint8_t *buffer, size_t sz, int &err_code, uint8_t *err_msg, size_t err_msg_size) { + return stun_is_error_response_str(buffer, sz, &err_code, err_msg, err_msg_size); + } - /** - * Check if the raw buffer is a challenge response (the one with 401 error and realm and nonce values). - */ - static bool isChallengeResponse(const uint8_t* buf, size_t sz, - int &err_code, uint8_t *err_msg, size_t err_msg_size, - uint8_t *realm, uint8_t *nonce, - uint8_t *server_name, int *oauth) { - return stun_is_challenge_response_str(buf, sz, &err_code, err_msg, err_msg_size, realm, nonce, server_name, oauth); - } + /** + * Check if the raw buffer is a challenge response (the one with 401 error and realm and nonce values). + */ + static bool isChallengeResponse(const uint8_t *buf, size_t sz, int &err_code, uint8_t *err_msg, size_t err_msg_size, + uint8_t *realm, uint8_t *nonce, uint8_t *server_name, int *oauth) { + return stun_is_challenge_response_str(buf, sz, &err_code, err_msg, err_msg_size, realm, nonce, server_name, oauth); + } - /** - * Check if the message is a channel message - */ - static bool isChannel(uint8_t *buffer, size_t sz) { - return is_channel_msg_str(buffer, sz); - } + /** + * Check if the message is a channel message + */ + static bool isChannel(uint8_t *buffer, size_t sz) { return is_channel_msg_str(buffer, sz); } - /** - * Check if the fingerprint is present. - */ - static bool isFingerprintPresent(uint8_t *buffer, size_t sz) { - if(!stun_is_command_message_str(buffer,sz)) - return false; - stun_attr_ref sar = stun_attr_get_first_by_type_str(buffer, sz, STUN_ATTRIBUTE_FINGERPRINT); - if(!sar) - return false; + /** + * Check if the fingerprint is present. + */ + static bool isFingerprintPresent(uint8_t *buffer, size_t sz) { + if (!stun_is_command_message_str(buffer, sz)) + return false; + stun_attr_ref sar = stun_attr_get_first_by_type_str(buffer, sz, STUN_ATTRIBUTE_FINGERPRINT); + if (!sar) + return false; - return true; - } + return true; + } - /** - * Check the fingerprint - */ - static bool checkFingerprint(uint8_t *buffer, size_t sz) { - return stun_is_command_message_full_check_str(buffer, sz, 1, NULL); - } + /** + * Check the fingerprint + */ + static bool checkFingerprint(uint8_t *buffer, size_t sz) { + return stun_is_command_message_full_check_str(buffer, sz, 1, NULL); + } - /** - * Add attribute to the message - */ - int addAttr(StunAttr &attr) { - return attr.addToMsg(*this); - } + /** + * Add attribute to the message + */ + int addAttr(StunAttr &attr) { return attr.addToMsg(*this); } - /** - * Get transaction ID - */ - virtual stun_tid getTid() const { - if(!_constructed || !isCommand()) - throw WrongStunBufferFormatException(); - stun_tid tid; - stun_tid_from_message_str(_buffer,_sz,&tid); - return tid; - } + /** + * Get transaction ID + */ + virtual stun_tid getTid() const { + if (!_constructed || !isCommand()) + throw WrongStunBufferFormatException(); + stun_tid tid; + stun_tid_from_message_str(_buffer, _sz, &tid); + return tid; + } - /** - * Set transaction ID - */ - virtual void setTid(stun_tid &tid) { - if(!_constructed || !isCommand()) - throw WrongStunBufferFormatException(); - stun_tid_message_cpy(_buffer, &tid); - } + /** + * Set transaction ID + */ + virtual void setTid(stun_tid &tid) { + if (!_constructed || !isCommand()) + throw WrongStunBufferFormatException(); + stun_tid_message_cpy(_buffer, &tid); + } - /** - * Add fingerprint to the message - */ - void addFingerprint() { - if(!_constructed || !isCommand()) - throw WrongStunBufferFormatException(); - stun_attr_add_fingerprint_str(_buffer,&_sz); - } + /** + * Add fingerprint to the message + */ + void addFingerprint() { + if (!_constructed || !isCommand()) + throw WrongStunBufferFormatException(); + stun_attr_add_fingerprint_str(_buffer, &_sz); + } - /** - * Check message integrity, in secure communications. - */ - bool checkMessageIntegrity(turn_credential_type ct, std::string &uname, std::string &realm, std::string &upwd) const { - if(!_constructed || !isCommand()) - throw WrongStunBufferFormatException(); - uint8_t *suname=(uint8_t*)strdup(uname.c_str()); - uint8_t *srealm=(uint8_t*)strdup(realm.c_str()); - uint8_t *supwd=(uint8_t*)strdup(upwd.c_str()); - SHATYPE sht = SHATYPE_SHA1; - bool ret = (0< stun_check_message_integrity_str(ct,_buffer, _sz, suname, srealm, supwd, sht)); - free(suname); - free(srealm); - free(supwd); - return ret; - } + /** + * Check message integrity, in secure communications. + */ + bool checkMessageIntegrity(turn_credential_type ct, std::string &uname, std::string &realm, std::string &upwd) const { + if (!_constructed || !isCommand()) + throw WrongStunBufferFormatException(); + uint8_t *suname = (uint8_t *)strdup(uname.c_str()); + uint8_t *srealm = (uint8_t *)strdup(realm.c_str()); + uint8_t *supwd = (uint8_t *)strdup(upwd.c_str()); + SHATYPE sht = SHATYPE_SHA1; + bool ret = (0 < stun_check_message_integrity_str(ct, _buffer, _sz, suname, srealm, supwd, sht)); + free(suname); + free(srealm); + free(supwd); + return ret; + } - /** - * Adds long-term message integrity data to the message. - */ - void addLTMessageIntegrity(std::string &uname, std::string &realm, std::string &upwd, std::string &nonce) { + /** + * Adds long-term message integrity data to the message. + */ + void addLTMessageIntegrity(std::string &uname, std::string &realm, std::string &upwd, std::string &nonce) { - if(!_constructed || !isCommand()) - throw WrongStunBufferFormatException(); + if (!_constructed || !isCommand()) + throw WrongStunBufferFormatException(); - uint8_t *suname=(uint8_t*)strdup(uname.c_str()); - uint8_t *srealm=(uint8_t*)strdup(realm.c_str()); - uint8_t *supwd=(uint8_t*)strdup(upwd.c_str()); - uint8_t *snonce=(uint8_t*)strdup(nonce.c_str()); + uint8_t *suname = (uint8_t *)strdup(uname.c_str()); + uint8_t *srealm = (uint8_t *)strdup(realm.c_str()); + uint8_t *supwd = (uint8_t *)strdup(upwd.c_str()); + uint8_t *snonce = (uint8_t *)strdup(nonce.c_str()); - stun_attr_add_integrity_by_user_str(_buffer, &_sz, suname, srealm, supwd, snonce, SHATYPE_SHA1); + stun_attr_add_integrity_by_user_str(_buffer, &_sz, suname, srealm, supwd, snonce, SHATYPE_SHA1); - free(suname); - free(srealm); - free(supwd); - free(snonce); - } + free(suname); + free(srealm); + free(supwd); + free(snonce); + } - /** - * Adds short-term message integrity data to the message. - */ - void addSTMessageIntegrity(std::string &uname, std::string &upwd) { + /** + * Adds short-term message integrity data to the message. + */ + void addSTMessageIntegrity(std::string &uname, std::string &upwd) { - if(!_constructed || !isCommand()) - throw WrongStunBufferFormatException(); + if (!_constructed || !isCommand()) + throw WrongStunBufferFormatException(); - uint8_t *suname=(uint8_t*)strdup(uname.c_str()); - uint8_t *supwd=(uint8_t*)strdup(upwd.c_str()); + uint8_t *suname = (uint8_t *)strdup(uname.c_str()); + uint8_t *supwd = (uint8_t *)strdup(upwd.c_str()); - stun_attr_add_integrity_by_user_short_term_str(_buffer, &_sz, suname, supwd, SHATYPE_SHA1); + stun_attr_add_integrity_by_user_short_term_str(_buffer, &_sz, suname, supwd, SHATYPE_SHA1); - free(suname); - free(supwd); - } + free(suname); + free(supwd); + } protected: - virtual void constructBuffer() = 0; - virtual bool check() = 0; + virtual void constructBuffer() = 0; + virtual bool check() = 0; + protected: - uint8_t *_buffer; - bool _deallocate; - size_t _allocated_sz; - size_t _sz; - bool _constructed; + uint8_t *_buffer; + bool _deallocate; + size_t _allocated_sz; + size_t _sz; + bool _constructed; }; /** @@ -797,79 +714,71 @@ protected: */ class StunMsgRequest : public StunMsg { public: - StunMsgRequest(uint16_t method) : _method(method) {}; - StunMsgRequest(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) : - StunMsg(buffer,total_sz,sz,constructed),_method(0) { + StunMsgRequest(uint16_t method) : _method(method){}; + StunMsgRequest(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) + : StunMsg(buffer, total_sz, sz, constructed), _method(0) { - if(constructed) { - if(!stun_is_request_str(buffer,sz)) { - throw WrongStunBufferFormatException(); - } - _method = stun_get_method_str(buffer,sz); - } - } - virtual ~StunMsgRequest() {} + if (constructed) { + if (!stun_is_request_str(buffer, sz)) { + throw WrongStunBufferFormatException(); + } + _method = stun_get_method_str(buffer, sz); + } + } + virtual ~StunMsgRequest() {} - /** - * Get request method - */ - uint16_t getMethod() const { - return _method; - } + /** + * Get request method + */ + uint16_t getMethod() const { return _method; } - /** - * Set method - */ - void setMethod(uint16_t method) { - _method = method; - } + /** + * Set method + */ + void setMethod(uint16_t method) { _method = method; } - /** - * Construct binding request - */ - void constructBindingRequest() { - stun_set_binding_request_str(_buffer, &_sz); - } + /** + * Construct binding request + */ + void constructBindingRequest() { stun_set_binding_request_str(_buffer, &_sz); } - bool isBindingRequest() const { - return stun_is_binding_request_str(_buffer,_sz,0); - } + bool isBindingRequest() const { return stun_is_binding_request_str(_buffer, _sz, 0); } - /** - * Construct allocate request - */ - void constructAllocateRequest(uint32_t lifetime, int af4, int af6, uint8_t transport, int mobile, const char* rt, int ep) { - stun_set_allocate_request_str(_buffer, &_sz, lifetime, af4, af6, transport, mobile, rt, ep); - } + /** + * Construct allocate request + */ + void constructAllocateRequest(uint32_t lifetime, int af4, int af6, uint8_t transport, int mobile, const char *rt, + int ep) { + stun_set_allocate_request_str(_buffer, &_sz, lifetime, af4, af6, transport, mobile, rt, ep); + } - /** - * Construct channel bind request - */ - void constructChannelBindRequest(const ioa_addr &peer_addr, uint16_t channel_number) { - stun_set_channel_bind_request_str(_buffer, &_sz, - &peer_addr, channel_number); - } + /** + * Construct channel bind request + */ + void constructChannelBindRequest(const ioa_addr &peer_addr, uint16_t channel_number) { + stun_set_channel_bind_request_str(_buffer, &_sz, &peer_addr, channel_number); + } protected: - virtual void constructBuffer() { - stun_init_request_str(_method,_buffer,&_sz); - _constructed = true; - } + virtual void constructBuffer() { + stun_init_request_str(_method, _buffer, &_sz); + _constructed = true; + } - virtual bool check() { - if(!_constructed) - return false; - if(!stun_is_request_str(_buffer,_sz)) { - return false; - } - if(_method != stun_get_method_str(_buffer,_sz)) { - return false; - } - return true; - } + virtual bool check() { + if (!_constructed) + return false; + if (!stun_is_request_str(_buffer, _sz)) { + return false; + } + if (_method != stun_get_method_str(_buffer, _sz)) { + return false; + } + return true; + } private: - uint16_t _method; + uint16_t _method; }; /** @@ -877,183 +786,154 @@ private: */ class StunMsgResponse : public StunMsg { public: - StunMsgResponse(uint16_t method, stun_tid &tid) : _method(method), _err(0), _reason(""), _tid(tid) {}; - StunMsgResponse(uint16_t method, int error_code, std::string reason, stun_tid &tid) : - _method(method), _err(error_code), _reason(reason), _tid(tid) { + StunMsgResponse(uint16_t method, stun_tid &tid) : _method(method), _err(0), _reason(""), _tid(tid){}; + StunMsgResponse(uint16_t method, int error_code, std::string reason, stun_tid &tid) + : _method(method), _err(error_code), _reason(reason), _tid(tid){ - }; - StunMsgResponse(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) : - StunMsg(buffer,total_sz,sz,constructed),_method(0),_err(0),_reason("") { + }; + StunMsgResponse(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) + : StunMsg(buffer, total_sz, sz, constructed), _method(0), _err(0), _reason("") { - if(constructed) { - if(!stun_is_success_response_str(buffer,sz)) { - uint8_t errtxt[0xFFFF]; - if(!stun_is_error_response_str(buffer,sz,&_err,errtxt,sizeof(errtxt))) { - throw WrongStunBufferFormatException(); - } - _reason = (char*)errtxt; - } - _method = stun_get_method_str(buffer,sz); - stun_tid_from_message_str(_buffer,_sz,&_tid); - } - } + if (constructed) { + if (!stun_is_success_response_str(buffer, sz)) { + uint8_t errtxt[0xFFFF]; + if (!stun_is_error_response_str(buffer, sz, &_err, errtxt, sizeof(errtxt))) { + throw WrongStunBufferFormatException(); + } + _reason = (char *)errtxt; + } + _method = stun_get_method_str(buffer, sz); + stun_tid_from_message_str(_buffer, _sz, &_tid); + } + } - uint16_t getMethod() const { - return _method; - } + uint16_t getMethod() const { return _method; } - void setMethod(uint16_t method) { - _method = method; - } + void setMethod(uint16_t method) { _method = method; } - /** - * Get error code - */ - int getError() const { - return _err; - } + /** + * Get error code + */ + int getError() const { return _err; } - /** - * Set error code - */ - void setError(int err) { - _err = err; - } + /** + * Set error code + */ + void setError(int err) { _err = err; } - /** - * Get error message - */ - std::string getReason() const { - return _reason; - } + /** + * Get error message + */ + std::string getReason() const { return _reason; } - /** - * Set error message - */ - void setReason(std::string reason) { - _reason = reason; - } + /** + * Set error message + */ + void setReason(std::string reason) { _reason = reason; } - /** - * Set transaction ID - */ - void setTid(stun_tid &tid) { - _tid = tid; - } + /** + * Set transaction ID + */ + void setTid(stun_tid &tid) { _tid = tid; } - /** - * Get transaction ID - */ - virtual stun_tid getTid() const { - return _tid; - } + /** + * Get transaction ID + */ + virtual stun_tid getTid() const { return _tid; } - /** - * Check if this is a challenge response, and return realm and nonce - */ - bool isChallenge(std::string &realm, std::string &nonce) const { - bool ret = false; - if(_constructed) { - int err_code; - uint8_t err_msg[1025]; - size_t err_msg_size=sizeof(err_msg); - uint8_t srealm[0xFFFF]; - uint8_t snonce[0xFFFF]; - ret = stun_is_challenge_response_str(_buffer, _sz, &err_code, err_msg, err_msg_size, srealm, snonce, NULL, NULL); - if(ret) { - realm = (char*)srealm; - nonce = (char*)snonce; - } - } - return ret; - } + /** + * Check if this is a challenge response, and return realm and nonce + */ + bool isChallenge(std::string &realm, std::string &nonce) const { + bool ret = false; + if (_constructed) { + int err_code; + uint8_t err_msg[1025]; + size_t err_msg_size = sizeof(err_msg); + uint8_t srealm[0xFFFF]; + uint8_t snonce[0xFFFF]; + ret = stun_is_challenge_response_str(_buffer, _sz, &err_code, err_msg, err_msg_size, srealm, snonce, NULL, NULL); + if (ret) { + realm = (char *)srealm; + nonce = (char *)snonce; + } + } + return ret; + } - bool isChallenge() const { - std::string realm, nonce; - return isChallenge(realm, nonce); - } + bool isChallenge() const { + std::string realm, nonce; + return isChallenge(realm, nonce); + } - /** - * Check if this is a success response - */ - bool isSuccess() const { - return (_err == 0); - } + /** + * Check if this is a success response + */ + bool isSuccess() const { return (_err == 0); } - /** - * Construct binding response - */ - void constructBindingResponse(stun_tid &tid, - const ioa_addr &reflexive_addr, int error_code, - const uint8_t *reason) { + /** + * Construct binding response + */ + void constructBindingResponse(stun_tid &tid, const ioa_addr &reflexive_addr, int error_code, const uint8_t *reason) { - stun_set_binding_response_str(_buffer, &_sz, &tid, - &reflexive_addr, error_code, - reason, 0 , 0 , 1); - } + stun_set_binding_response_str(_buffer, &_sz, &tid, &reflexive_addr, error_code, reason, 0, 0, 1); + } - bool isBindingResponse() const { - return stun_is_binding_response_str(_buffer,_sz); - } + bool isBindingResponse() const { return stun_is_binding_response_str(_buffer, _sz); } - /** - * Construct allocate response - */ - void constructAllocateResponse(stun_tid &tid, - const ioa_addr &relayed_addr1, - const ioa_addr &relayed_addr2, - const ioa_addr &reflexive_addr, - uint32_t lifetime, int error_code, const uint8_t *reason, - uint64_t reservation_token, char *mobile_id) { + /** + * Construct allocate response + */ + void constructAllocateResponse(stun_tid &tid, const ioa_addr &relayed_addr1, const ioa_addr &relayed_addr2, + const ioa_addr &reflexive_addr, uint32_t lifetime, int error_code, + const uint8_t *reason, uint64_t reservation_token, char *mobile_id) { - stun_set_allocate_response_str(_buffer, &_sz, &tid, - &relayed_addr1, &relayed_addr2, - &reflexive_addr, - lifetime, STUN_DEFAULT_MAX_ALLOCATE_LIFETIME, error_code, reason, - reservation_token, mobile_id); - } + stun_set_allocate_response_str(_buffer, &_sz, &tid, &relayed_addr1, &relayed_addr2, &reflexive_addr, lifetime, + STUN_DEFAULT_MAX_ALLOCATE_LIFETIME, error_code, reason, reservation_token, + mobile_id); + } - /** - * Construct channel bind response - */ - void constructChannelBindResponse(stun_tid &tid, int error_code, const uint8_t *reason) { - stun_set_channel_bind_response_str(_buffer, &_sz, &tid, error_code, reason); - } + /** + * Construct channel bind response + */ + void constructChannelBindResponse(stun_tid &tid, int error_code, const uint8_t *reason) { + stun_set_channel_bind_response_str(_buffer, &_sz, &tid, error_code, reason); + } protected: - virtual void constructBuffer() { - if(_err) { - stun_init_error_response_str(_method, _buffer, &_sz, _err, (const uint8_t*)_reason.c_str(), &_tid); - } else { - stun_init_success_response_str(_method, _buffer, &_sz, &_tid); - } - _constructed = true; - } + virtual void constructBuffer() { + if (_err) { + stun_init_error_response_str(_method, _buffer, &_sz, _err, (const uint8_t *)_reason.c_str(), &_tid); + } else { + stun_init_success_response_str(_method, _buffer, &_sz, &_tid); + } + _constructed = true; + } - virtual bool check() { - if(!_constructed) - return false; - if(!stun_is_success_response_str(_buffer,_sz)) { - uint8_t errtxt[0xFFFF]; - int cerr=0; - if(!stun_is_error_response_str(_buffer,_sz,&cerr,errtxt,sizeof(errtxt))) { - throw WrongStunBufferFormatException(); - } - if(cerr != _err) { - throw WrongStunBufferFormatException(); - } - } - if(_method != stun_get_method_str(_buffer,_sz)) { - return false; - } - return true; - } + virtual bool check() { + if (!_constructed) + return false; + if (!stun_is_success_response_str(_buffer, _sz)) { + uint8_t errtxt[0xFFFF]; + int cerr = 0; + if (!stun_is_error_response_str(_buffer, _sz, &cerr, errtxt, sizeof(errtxt))) { + throw WrongStunBufferFormatException(); + } + if (cerr != _err) { + throw WrongStunBufferFormatException(); + } + } + if (_method != stun_get_method_str(_buffer, _sz)) { + return false; + } + return true; + } private: - uint16_t _method; - int _err; - std::string _reason; - stun_tid _tid; + uint16_t _method; + int _err; + std::string _reason; + stun_tid _tid; }; /** @@ -1061,47 +941,43 @@ private: */ class StunMsgIndication : public StunMsg { public: - StunMsgIndication(uint16_t method) : _method(method) {}; - StunMsgIndication(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) : - StunMsg(buffer,total_sz,sz,constructed),_method(0) { + StunMsgIndication(uint16_t method) : _method(method){}; + StunMsgIndication(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) + : StunMsg(buffer, total_sz, sz, constructed), _method(0) { - if(constructed) { - if(!stun_is_indication_str(buffer,sz)) { - throw WrongStunBufferFormatException(); - } - _method = stun_get_method_str(buffer,sz); - } - } - virtual ~StunMsgIndication() {} + if (constructed) { + if (!stun_is_indication_str(buffer, sz)) { + throw WrongStunBufferFormatException(); + } + _method = stun_get_method_str(buffer, sz); + } + } + virtual ~StunMsgIndication() {} - uint16_t getMethod() const { - return _method; - } + uint16_t getMethod() const { return _method; } - void setMethod(uint16_t method) { - _method = method; - } + void setMethod(uint16_t method) { _method = method; } protected: - virtual void constructBuffer() { - stun_init_indication_str(_method,_buffer,&_sz); - _constructed = true; - } + virtual void constructBuffer() { + stun_init_indication_str(_method, _buffer, &_sz); + _constructed = true; + } - virtual bool check() { - if(!_constructed) - return false; - if(!stun_is_indication_str(_buffer,_sz)) { - return false; - } - if(_method != stun_get_method_str(_buffer,_sz)) { - return false; - } - return true; - } + virtual bool check() { + if (!_constructed) + return false; + if (!stun_is_indication_str(_buffer, _sz)) { + return false; + } + if (_method != stun_get_method_str(_buffer, _sz)) { + return false; + } + return true; + } private: - uint16_t _method; + uint16_t _method; }; /** @@ -1109,74 +985,66 @@ private: */ class StunMsgChannel : public StunMsg { public: - StunMsgChannel(uint16_t cn, int length) : _cn(cn), _len(length) {}; - StunMsgChannel(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) : - StunMsg(buffer,total_sz,sz,constructed),_cn(0) { + StunMsgChannel(uint16_t cn, int length) : _cn(cn), _len(length){}; + StunMsgChannel(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) + : StunMsg(buffer, total_sz, sz, constructed), _cn(0) { - if(constructed) { - if(!stun_is_channel_message_str(buffer,&_sz,&_cn,0)) { - throw WrongStunBufferFormatException(); - } - if(_sz>0xFFFF || _sz<4) - throw WrongStunBufferFormatException(); + if (constructed) { + if (!stun_is_channel_message_str(buffer, &_sz, &_cn, 0)) { + throw WrongStunBufferFormatException(); + } + if (_sz > 0xFFFF || _sz < 4) + throw WrongStunBufferFormatException(); - _len = _sz-4; - } else { - if(total_sz>0xFFFF || total_sz<4) - throw WrongStunBufferFormatException(); + _len = _sz - 4; + } else { + if (total_sz > 0xFFFF || total_sz < 4) + throw WrongStunBufferFormatException(); - _len = 0; - } - } - virtual ~StunMsgChannel() {} + _len = 0; + } + } + virtual ~StunMsgChannel() {} - uint16_t getChannelNumber() const { - return _cn; - } + uint16_t getChannelNumber() const { return _cn; } - void setChannelNumber(uint16_t cn) { - _cn = cn; - } + void setChannelNumber(uint16_t cn) { _cn = cn; } - /** - * Get length of message itself (excluding the 4 channel number bytes) - */ - size_t getLength() const { - return _len; - } + /** + * Get length of message itself (excluding the 4 channel number bytes) + */ + size_t getLength() const { return _len; } - /** - * Set length of message itself (excluding the 4 channel number bytes) - */ - void setLength(size_t len) { - _len = len; - } + /** + * Set length of message itself (excluding the 4 channel number bytes) + */ + void setLength(size_t len) { _len = len; } protected: - virtual void constructBuffer() { - stun_init_channel_message_str(_cn,_buffer,&_sz,(int)_len,0); - _constructed = true; - } + virtual void constructBuffer() { + stun_init_channel_message_str(_cn, _buffer, &_sz, (int)_len, 0); + _constructed = true; + } - virtual bool check() { - if(!_constructed) - return false; - uint16_t cn = 0; - if(!stun_is_channel_message_str(_buffer,&_sz,&cn,0)) { - return false; - } - if(_cn != cn) { - return false; - } - return true; - } + virtual bool check() { + if (!_constructed) + return false; + uint16_t cn = 0; + if (!stun_is_channel_message_str(_buffer, &_sz, &cn, 0)) { + return false; + } + if (_cn != cn) { + return false; + } + return true; + } private: - uint16_t _cn; - size_t _len; + uint16_t _cn; + size_t _len; }; -} +} // namespace turn /* namespace */ #endif diff --git a/src/client/ns_turn_ioaddr.c b/src/client/ns_turn_ioaddr.c index b35a0ef..9bc0f8b 100644 --- a/src/client/ns_turn_ioaddr.c +++ b/src/client/ns_turn_ioaddr.c @@ -31,133 +31,136 @@ #include "ns_turn_ioaddr.h" #if defined(__unix__) || defined(unix) || defined(__APPLE__) - #include +#include #endif ////////////////////////////////////////////////////////////// -uint32_t get_ioa_addr_len(const ioa_addr* addr) { - if(addr->ss.sa_family == AF_INET) return sizeof(struct sockaddr_in); - else if(addr->ss.sa_family == AF_INET6) return sizeof(struct sockaddr_in6); +uint32_t get_ioa_addr_len(const ioa_addr *addr) { + if (addr->ss.sa_family == AF_INET) + return sizeof(struct sockaddr_in); + else if (addr->ss.sa_family == AF_INET6) + return sizeof(struct sockaddr_in6); return 0; } /////////////////////////////////////////////////////////////// void addr_set_any(ioa_addr *addr) { - if(addr) - memset(addr, 0, sizeof(ioa_addr)); + if (addr) + memset(addr, 0, sizeof(ioa_addr)); } -int addr_any(const ioa_addr* addr) { +int addr_any(const ioa_addr *addr) { - if(!addr) - return 1; + if (!addr) + return 1; - if(addr->ss.sa_family == AF_INET) { - return ((addr->s4.sin_addr.s_addr==0)&&(addr->s4.sin_port==0)); - } else if(addr->ss.sa_family == AF_INET6) { - if(addr->s6.sin6_port!=0) return 0; + if (addr->ss.sa_family == AF_INET) { + return ((addr->s4.sin_addr.s_addr == 0) && (addr->s4.sin_port == 0)); + } else if (addr->ss.sa_family == AF_INET6) { + if (addr->s6.sin6_port != 0) + return 0; else { size_t i; - for(i=0;is6.sin6_addr);i++) - if(((const char*)&(addr->s6.sin6_addr))[i]) return 0; + for (i = 0; i < sizeof(addr->s6.sin6_addr); i++) + if (((const char *)&(addr->s6.sin6_addr))[i]) + return 0; } } return 1; } -int addr_any_no_port(const ioa_addr* addr) { - if(!addr) - return 1; +int addr_any_no_port(const ioa_addr *addr) { + if (!addr) + return 1; - if(addr->ss.sa_family == AF_INET) { - return (addr->s4.sin_addr.s_addr==0); - } else if(addr->ss.sa_family == AF_INET6) { + if (addr->ss.sa_family == AF_INET) { + return (addr->s4.sin_addr.s_addr == 0); + } else if (addr->ss.sa_family == AF_INET6) { size_t i; - for(i=0;is6.sin6_addr);i++) - if(((const char*)(&(addr->s6.sin6_addr)))[i]) return 0; + for (i = 0; i < sizeof(addr->s6.sin6_addr); i++) + if (((const char *)(&(addr->s6.sin6_addr)))[i]) + return 0; } return 1; } -uint32_t hash_int32(uint32_t a) -{ - a = a ^ (a>>4); - a = (a^0xdeadbeef) + (a<<5); - a = a ^ (a>>11); - return a; +uint32_t hash_int32(uint32_t a) { + a = a ^ (a >> 4); + a = (a ^ 0xdeadbeef) + (a << 5); + a = a ^ (a >> 11); + return a; } -uint64_t hash_int64(uint64_t a) -{ - a = a ^ (a>>4); - a = (a^0xdeadbeefdeadbeefLL) + (a<<5); - a = a ^ (a>>11); - return a; +uint64_t hash_int64(uint64_t a) { + a = a ^ (a >> 4); + a = (a ^ 0xdeadbeefdeadbeefLL) + (a << 5); + a = a ^ (a >> 11); + return a; } -uint32_t addr_hash(const ioa_addr *addr) -{ - if(!addr) - return 0; +uint32_t addr_hash(const ioa_addr *addr) { + if (!addr) + return 0; - uint32_t ret = 0; - if (addr->ss.sa_family == AF_INET) { - ret = hash_int32(addr->s4.sin_addr.s_addr + addr->s4.sin_port); - } else { - uint64_t a[2]; - memcpy(&a, &(addr->s6.sin6_addr), sizeof(a)); - ret = (uint32_t)((hash_int64(a[0])<<3) + (hash_int64(a[1] + addr->s6.sin6_port))); - } - return ret; + uint32_t ret = 0; + if (addr->ss.sa_family == AF_INET) { + ret = hash_int32(addr->s4.sin_addr.s_addr + addr->s4.sin_port); + } else { + uint64_t a[2]; + memcpy(&a, &(addr->s6.sin6_addr), sizeof(a)); + ret = (uint32_t)((hash_int64(a[0]) << 3) + (hash_int64(a[1] + addr->s6.sin6_port))); + } + return ret; } -uint32_t addr_hash_no_port(const ioa_addr *addr) -{ - if(!addr) - return 0; +uint32_t addr_hash_no_port(const ioa_addr *addr) { + if (!addr) + return 0; - uint32_t ret = 0; - if (addr->ss.sa_family == AF_INET) { - ret = hash_int32(addr->s4.sin_addr.s_addr); - } else { - uint64_t a[2]; - memcpy(&a, &(addr->s6.sin6_addr), sizeof(a)); - ret = (uint32_t)((hash_int64(a[0])<<3) + (hash_int64(a[1]))); - } - return ret; + uint32_t ret = 0; + if (addr->ss.sa_family == AF_INET) { + ret = hash_int32(addr->s4.sin_addr.s_addr); + } else { + uint64_t a[2]; + memcpy(&a, &(addr->s6.sin6_addr), sizeof(a)); + ret = (uint32_t)((hash_int64(a[0]) << 3) + (hash_int64(a[1]))); + } + return ret; } -void addr_cpy(ioa_addr* dst, const ioa_addr* src) { - if(dst && src) - memcpy(dst,src,sizeof(ioa_addr)); +void addr_cpy(ioa_addr *dst, const ioa_addr *src) { + if (dst && src) + memcpy(dst, src, sizeof(ioa_addr)); } -void addr_cpy4(ioa_addr* dst, const struct sockaddr_in* src) { - if(src && dst) - memcpy(dst,src,sizeof(struct sockaddr_in)); +void addr_cpy4(ioa_addr *dst, const struct sockaddr_in *src) { + if (src && dst) + memcpy(dst, src, sizeof(struct sockaddr_in)); } -void addr_cpy6(ioa_addr* dst, const struct sockaddr_in6* src) { - if(src && dst) - memcpy(dst,src,sizeof(struct sockaddr_in6)); +void addr_cpy6(ioa_addr *dst, const struct sockaddr_in6 *src) { + if (src && dst) + memcpy(dst, src, sizeof(struct sockaddr_in6)); } -int addr_eq(const ioa_addr* a1, const ioa_addr *a2) { +int addr_eq(const ioa_addr *a1, const ioa_addr *a2) { - if(!a1) return (!a2); - else if(!a2) return (!a1); + if (!a1) + return (!a2); + else if (!a2) + return (!a1); - if(a1->ss.sa_family == a2->ss.sa_family) { - if(a1->ss.sa_family == AF_INET && a1->s4.sin_port == a2->s4.sin_port) { - if((int)a1->s4.sin_addr.s_addr == (int)a2->s4.sin_addr.s_addr) { - return 1; + if (a1->ss.sa_family == a2->ss.sa_family) { + if (a1->ss.sa_family == AF_INET && a1->s4.sin_port == a2->s4.sin_port) { + if ((int)a1->s4.sin_addr.s_addr == (int)a2->s4.sin_addr.s_addr) { + return 1; } - } else if(a1->ss.sa_family == AF_INET6 && a1->s6.sin6_port == a2->s6.sin6_port) { - if( memcmp(&(a1->s6.sin6_addr), &(a2->s6.sin6_addr) ,sizeof(struct in6_addr)) == 0 ) { + } else if (a1->ss.sa_family == AF_INET6 && a1->s6.sin6_port == a2->s6.sin6_port) { + if (memcmp(&(a1->s6.sin6_addr), &(a2->s6.sin6_addr), sizeof(struct in6_addr)) == 0) { return 1; } } @@ -166,18 +169,20 @@ int addr_eq(const ioa_addr* a1, const ioa_addr *a2) { return 0; } -int addr_eq_no_port(const ioa_addr* a1, const ioa_addr *a2) { +int addr_eq_no_port(const ioa_addr *a1, const ioa_addr *a2) { - if(!a1) return (!a2); - else if(!a2) return (!a1); - - if(a1->ss.sa_family == a2->ss.sa_family) { - if(a1->ss.sa_family == AF_INET) { - if((int)a1->s4.sin_addr.s_addr == (int)a2->s4.sin_addr.s_addr) { - return 1; + if (!a1) + return (!a2); + else if (!a2) + return (!a1); + + if (a1->ss.sa_family == a2->ss.sa_family) { + if (a1->ss.sa_family == AF_INET) { + if ((int)a1->s4.sin_addr.s_addr == (int)a2->s4.sin_addr.s_addr) { + return 1; } - } else if(a1->ss.sa_family == AF_INET6) { - if( memcmp(&(a1->s6.sin6_addr), &(a2->s6.sin6_addr) ,sizeof(struct in6_addr)) == 0 ) { + } else if (a1->ss.sa_family == AF_INET6) { + if (memcmp(&(a1->s6.sin6_addr), &(a2->s6.sin6_addr), sizeof(struct in6_addr)) == 0) { return 1; } } @@ -185,29 +190,30 @@ int addr_eq_no_port(const ioa_addr* a1, const ioa_addr *a2) { return 0; } -int make_ioa_addr(const uint8_t* saddr0, int port, ioa_addr *addr) { +int make_ioa_addr(const uint8_t *saddr0, int port, ioa_addr *addr) { - if(!saddr0 || !addr) return -1; + if (!saddr0 || !addr) + return -1; char ssaddr[257]; - STRCPY(ssaddr,saddr0); + STRCPY(ssaddr, saddr0); - char* saddr=ssaddr; - while(*saddr == ' ') ++saddr; + char *saddr = ssaddr; + while (*saddr == ' ') + ++saddr; - size_t len=strlen(saddr); - while(len>0) { - if(saddr[len-1]==' ') { - saddr[len-1]=0; - --len; - } else { - break; - } + size_t len = strlen(saddr); + while (len > 0) { + if (saddr[len - 1] == ' ') { + saddr[len - 1] = 0; + --len; + } else { + break; + } } memset(addr, 0, sizeof(ioa_addr)); - if((len == 0)|| - (inet_pton(AF_INET, saddr, &addr->s4.sin_addr) == 1)) { + if ((len == 0) || (inet_pton(AF_INET, saddr, &addr->s4.sin_addr) == 1)) { addr->s4.sin_family = AF_INET; #if defined(TURN_HAS_SIN_LEN) /* tested when configured */ addr->s4.sin_len = sizeof(struct sockaddr_in); @@ -234,176 +240,174 @@ int make_ioa_addr(const uint8_t* saddr0, int port, ioa_addr *addr) { addr_hints.ai_next = NULL; err = getaddrinfo(saddr, NULL, &addr_hints, &addr_result); - if ((err != 0)||(!addr_result)) { - fprintf(stderr,"error resolving '%s' hostname: %s\n",saddr,gai_strerror(err)); + if ((err != 0) || (!addr_result)) { + fprintf(stderr, "error resolving '%s' hostname: %s\n", saddr, gai_strerror(err)); return -1; } - + int family = AF_INET; struct addrinfo *addr_result_orig = addr_result; int found = 0; - beg_af: + beg_af: - while(addr_result) { + while (addr_result) { - if(addr_result->ai_family == family) { - if (addr_result->ai_family == AF_INET) { - memcpy(addr, addr_result->ai_addr, addr_result->ai_addrlen); - addr->s4.sin_port = nswap16(port); + if (addr_result->ai_family == family) { + if (addr_result->ai_family == AF_INET) { + memcpy(addr, addr_result->ai_addr, addr_result->ai_addrlen); + addr->s4.sin_port = nswap16(port); #if defined(TURN_HAS_SIN_LEN) /* tested when configured */ - addr->s4.sin_len = sizeof(struct sockaddr_in); + addr->s4.sin_len = sizeof(struct sockaddr_in); #endif - found = 1; - break; - } else if (addr_result->ai_family == AF_INET6) { - memcpy(addr, addr_result->ai_addr, addr_result->ai_addrlen); - addr->s6.sin6_port = nswap16(port); + found = 1; + break; + } else if (addr_result->ai_family == AF_INET6) { + memcpy(addr, addr_result->ai_addr, addr_result->ai_addrlen); + addr->s6.sin6_port = nswap16(port); #if defined(SIN6_LEN) /* this define is required by IPv6 if used */ - addr->s6.sin6_len = sizeof(struct sockaddr_in6); + addr->s6.sin6_len = sizeof(struct sockaddr_in6); #endif - found = 1; - break; - } - } + found = 1; + break; + } + } - addr_result = addr_result->ai_next; + addr_result = addr_result->ai_next; } - if(!found && family == AF_INET) { - family = AF_INET6; - addr_result = addr_result_orig; - goto beg_af; + if (!found && family == AF_INET) { + family = AF_INET6; + addr_result = addr_result_orig; + goto beg_af; } - + freeaddrinfo(addr_result_orig); } return 0; } -static char* get_addr_string_and_port(char* s0, int *port) -{ - char *s = s0; - while(*s && (*s==' ')) ++s; - if(*s == '[') { - ++s; - char *tail = strstr(s,"]"); - if(tail) { - *tail=0; - ++tail; - while(*tail && (*tail==' ')) ++tail; - if(*tail==':') { - ++tail; - *port = atoi(tail); - return s; - } else if(*tail == 0) { - *port = 0; - return s; - } - } - } else { - char *tail = strstr(s,":"); - if(tail) { - *tail = 0; - ++tail; - *port = atoi(tail); - return s; - } else { - *port = 0; - return s; - } - } - return NULL; +static char *get_addr_string_and_port(char *s0, int *port) { + char *s = s0; + while (*s && (*s == ' ')) + ++s; + if (*s == '[') { + ++s; + char *tail = strstr(s, "]"); + if (tail) { + *tail = 0; + ++tail; + while (*tail && (*tail == ' ')) + ++tail; + if (*tail == ':') { + ++tail; + *port = atoi(tail); + return s; + } else if (*tail == 0) { + *port = 0; + return s; + } + } + } else { + char *tail = strstr(s, ":"); + if (tail) { + *tail = 0; + ++tail; + *port = atoi(tail); + return s; + } else { + *port = 0; + return s; + } + } + return NULL; } -int make_ioa_addr_from_full_string(const uint8_t* saddr, int default_port, ioa_addr *addr) -{ - if(!addr) - return -1; +int make_ioa_addr_from_full_string(const uint8_t *saddr, int default_port, ioa_addr *addr) { + if (!addr) + return -1; - int ret = -1; - int port = 0; - char* s = strdup((const char*)saddr); - char *sa = get_addr_string_and_port(s,&port); - if(sa) { - if(port<1) - port = default_port; - ret = make_ioa_addr((uint8_t*)sa,port,addr); - } - free(s); - return ret; + int ret = -1; + int port = 0; + char *s = strdup((const char *)saddr); + char *sa = get_addr_string_and_port(s, &port); + if (sa) { + if (port < 1) + port = default_port; + ret = make_ioa_addr((uint8_t *)sa, port, addr); + } + free(s); + return ret; } -int addr_to_string(const ioa_addr* addr, uint8_t* saddr) -{ +int addr_to_string(const ioa_addr *addr, uint8_t *saddr) { - if (addr && saddr) { + if (addr && saddr) { - char addrtmp[INET6_ADDRSTRLEN]; + char addrtmp[INET6_ADDRSTRLEN]; - if (addr->ss.sa_family == AF_INET) { - inet_ntop(AF_INET, &addr->s4.sin_addr, addrtmp, INET_ADDRSTRLEN); - if(addr_get_port(addr)>0) - snprintf((char*)saddr, MAX_IOA_ADDR_STRING, "%s:%d", addrtmp, addr_get_port(addr)); - else - strncpy((char*)saddr, addrtmp, MAX_IOA_ADDR_STRING); - } else if (addr->ss.sa_family == AF_INET6) { - inet_ntop(AF_INET6, &addr->s6.sin6_addr, addrtmp, INET6_ADDRSTRLEN); - if(addr_get_port(addr)>0) - snprintf((char*)saddr, MAX_IOA_ADDR_STRING, "[%s]:%d", addrtmp, addr_get_port(addr)); - else - strncpy((char*)saddr, addrtmp, MAX_IOA_ADDR_STRING); - } else { - return -1; - } + if (addr->ss.sa_family == AF_INET) { + inet_ntop(AF_INET, &addr->s4.sin_addr, addrtmp, INET_ADDRSTRLEN); + if (addr_get_port(addr) > 0) + snprintf((char *)saddr, MAX_IOA_ADDR_STRING, "%s:%d", addrtmp, addr_get_port(addr)); + else + strncpy((char *)saddr, addrtmp, MAX_IOA_ADDR_STRING); + } else if (addr->ss.sa_family == AF_INET6) { + inet_ntop(AF_INET6, &addr->s6.sin6_addr, addrtmp, INET6_ADDRSTRLEN); + if (addr_get_port(addr) > 0) + snprintf((char *)saddr, MAX_IOA_ADDR_STRING, "[%s]:%d", addrtmp, addr_get_port(addr)); + else + strncpy((char *)saddr, addrtmp, MAX_IOA_ADDR_STRING); + } else { + return -1; + } - return 0; - } + return 0; + } - return -1; + return -1; } -int addr_to_string_no_port(const ioa_addr* addr, uint8_t* saddr) -{ +int addr_to_string_no_port(const ioa_addr *addr, uint8_t *saddr) { - if (addr && saddr) { + if (addr && saddr) { - char addrtmp[MAX_IOA_ADDR_STRING]; + char addrtmp[MAX_IOA_ADDR_STRING]; - if (addr->ss.sa_family == AF_INET) { - inet_ntop(AF_INET, &addr->s4.sin_addr, addrtmp, INET_ADDRSTRLEN); - strncpy((char*)saddr, addrtmp, MAX_IOA_ADDR_STRING); - } else if (addr->ss.sa_family == AF_INET6) { - inet_ntop(AF_INET6, &addr->s6.sin6_addr, addrtmp, INET6_ADDRSTRLEN); - strncpy((char*)saddr, addrtmp, MAX_IOA_ADDR_STRING); - } else { - return -1; - } + if (addr->ss.sa_family == AF_INET) { + inet_ntop(AF_INET, &addr->s4.sin_addr, addrtmp, INET_ADDRSTRLEN); + strncpy((char *)saddr, addrtmp, MAX_IOA_ADDR_STRING); + } else if (addr->ss.sa_family == AF_INET6) { + inet_ntop(AF_INET6, &addr->s6.sin6_addr, addrtmp, INET6_ADDRSTRLEN); + strncpy((char *)saddr, addrtmp, MAX_IOA_ADDR_STRING); + } else { + return -1; + } - return 0; - } + return 0; + } - return -1; + return -1; } -void addr_set_port(ioa_addr* addr, int port) { - if(addr) { - if(addr->s4.sin_family == AF_INET) { +void addr_set_port(ioa_addr *addr, int port) { + if (addr) { + if (addr->s4.sin_family == AF_INET) { addr->s4.sin_port = nswap16(port); - } else if(addr->s6.sin6_family == AF_INET6) { + } else if (addr->s6.sin6_family == AF_INET6) { addr->s6.sin6_port = nswap16(port); } } } -int addr_get_port(const ioa_addr* addr) { - if(!addr) - return 0; +int addr_get_port(const ioa_addr *addr) { + if (!addr) + return 0; - if(addr->s4.sin_family == AF_INET) { + if (addr->s4.sin_family == AF_INET) { return nswap16(addr->s4.sin_port); - } else if(addr->s6.sin6_family == AF_INET6) { + } else if (addr->s6.sin6_family == AF_INET6) { return nswap16(addr->s6.sin6_port); } return 0; @@ -411,42 +415,50 @@ int addr_get_port(const ioa_addr* addr) { ///////////////////////////////////////////////////////////////////////////// -void ioa_addr_range_set(ioa_addr_range* range, const ioa_addr* addr_min, const ioa_addr* addr_max) { - if(range) { - if(addr_min) addr_cpy(&(range->min),addr_min); - else addr_set_any(&(range->min)); - if(addr_max) addr_cpy(&(range->max),addr_max); - else addr_set_any(&(range->max)); +void ioa_addr_range_set(ioa_addr_range *range, const ioa_addr *addr_min, const ioa_addr *addr_max) { + if (range) { + if (addr_min) + addr_cpy(&(range->min), addr_min); + else + addr_set_any(&(range->min)); + if (addr_max) + addr_cpy(&(range->max), addr_max); + else + addr_set_any(&(range->max)); } } -int addr_less_eq(const ioa_addr* addr1, const ioa_addr* addr2) { +int addr_less_eq(const ioa_addr *addr1, const ioa_addr *addr2) { - if(!addr1) return 1; - else if(!addr2) return 0; + if (!addr1) + return 1; + else if (!addr2) + return 0; else { - if(addr1->ss.sa_family != addr2->ss.sa_family) return (addr1->ss.sa_family < addr2->ss.sa_family); - else if(addr1->ss.sa_family == AF_INET) { + if (addr1->ss.sa_family != addr2->ss.sa_family) + return (addr1->ss.sa_family < addr2->ss.sa_family); + else if (addr1->ss.sa_family == AF_INET) { return ((uint32_t)nswap32(addr1->s4.sin_addr.s_addr) <= (uint32_t)nswap32(addr2->s4.sin_addr.s_addr)); - } else if(addr1->ss.sa_family == AF_INET6) { + } else if (addr1->ss.sa_family == AF_INET6) { int i; - for(i=0;i<16;i++) { - if((uint8_t)(((const char*)&(addr1->s6.sin6_addr))[i]) > (uint8_t)(((const char*)&(addr2->s6.sin6_addr))[i])) - return 0; + for (i = 0; i < 16; i++) { + if ((uint8_t)(((const char *)&(addr1->s6.sin6_addr))[i]) > (uint8_t)(((const char *)&(addr2->s6.sin6_addr))[i])) + return 0; } return 1; - } else return 1; + } else + return 1; } } -int ioa_addr_in_range(const ioa_addr_range* range, const ioa_addr* addr) { +int ioa_addr_in_range(const ioa_addr_range *range, const ioa_addr *addr) { - if(range && addr) { - if(addr_any(&(range->min)) || addr_less_eq(&(range->min),addr)) { - if(addr_any(&(range->max))) { - return 1; + if (range && addr) { + if (addr_any(&(range->min)) || addr_less_eq(&(range->min), addr)) { + if (addr_any(&(range->max))) { + return 1; } else { - return addr_less_eq(addr,&(range->max)); + return addr_less_eq(addr, &(range->max)); } } } @@ -454,73 +466,70 @@ int ioa_addr_in_range(const ioa_addr_range* range, const ioa_addr* addr) { return 0; } -void ioa_addr_range_cpy(ioa_addr_range* dest, const ioa_addr_range* src) { - if(dest && src) { - addr_cpy(&(dest->min),&(src->min)); - addr_cpy(&(dest->max),&(src->max)); +void ioa_addr_range_cpy(ioa_addr_range *dest, const ioa_addr_range *src) { + if (dest && src) { + addr_cpy(&(dest->min), &(src->min)); + addr_cpy(&(dest->max), &(src->max)); } } /////// Check whether this is a good address ////////////// -int ioa_addr_is_multicast(ioa_addr *addr) -{ - if(addr) { - if(addr->ss.sa_family == AF_INET) { - const uint8_t *u = ((const uint8_t*)&(addr->s4.sin_addr)); - return (u[0] > 223); - } else if(addr->ss.sa_family == AF_INET6) { - uint8_t u = ((const uint8_t*)&(addr->s6.sin6_addr))[0]; - return (u == 255); - } - } - return 0; +int ioa_addr_is_multicast(ioa_addr *addr) { + if (addr) { + if (addr->ss.sa_family == AF_INET) { + const uint8_t *u = ((const uint8_t *)&(addr->s4.sin_addr)); + return (u[0] > 223); + } else if (addr->ss.sa_family == AF_INET6) { + uint8_t u = ((const uint8_t *)&(addr->s6.sin6_addr))[0]; + return (u == 255); + } + } + return 0; } -int ioa_addr_is_loopback(ioa_addr *addr) -{ - if(addr) { - if(addr->ss.sa_family == AF_INET) { - const uint8_t *u = ((const uint8_t*)&(addr->s4.sin_addr)); - return (u[0] == 127); - } else if(addr->ss.sa_family == AF_INET6) { - const uint8_t *u = ((const uint8_t*)&(addr->s6.sin6_addr)); - if(u[15] == 1) { - int i; - for(i=0;i<15;++i) { - if(u[i]) - return 0; - } - return 1; - } - } - } - return 0; +int ioa_addr_is_loopback(ioa_addr *addr) { + if (addr) { + if (addr->ss.sa_family == AF_INET) { + const uint8_t *u = ((const uint8_t *)&(addr->s4.sin_addr)); + return (u[0] == 127); + } else if (addr->ss.sa_family == AF_INET6) { + const uint8_t *u = ((const uint8_t *)&(addr->s6.sin6_addr)); + if (u[15] == 1) { + int i; + for (i = 0; i < 15; ++i) { + if (u[i]) + return 0; + } + return 1; + } + } + } + return 0; } /* To avoid a vulnerability this function checks whether the addr is in 0.0.0.0/8 or ::/128. -Source from (INADDR_ANY) 0.0.0.0/32 and (in6addr_any) ::/128 routed to loopback on Linux systems for old BSD backward compatibility. -https://github.com/torvalds/linux/blob/a2f5ea9e314ba6778f885c805c921e9362ec0420/net/ipv6/tcp_ipv6.c#L182 +Source from (INADDR_ANY) 0.0.0.0/32 and (in6addr_any) ::/128 routed to loopback on Linux systems for old BSD backward +compatibility. https://github.com/torvalds/linux/blob/a2f5ea9e314ba6778f885c805c921e9362ec0420/net/ipv6/tcp_ipv6.c#L182 To avoid any trouble we match the whole 0.0.0.0/8 that defined in RFC6890 as local network "this". */ -int ioa_addr_is_zero(ioa_addr *addr) -{ - if(addr) { - if(addr->ss.sa_family == AF_INET) { - const uint8_t *u = ((const uint8_t*)&(addr->s4.sin_addr)); - return (u[0] == 0); - } else if(addr->ss.sa_family == AF_INET6) { - const uint8_t *u = ((const uint8_t*)&(addr->s6.sin6_addr)); - int i; - for(i=0;i<=15;++i) { - if(u[i]) - return 0; - } - return 1; - } - } - return 0; +int ioa_addr_is_zero(ioa_addr *addr) { + if (addr) { + if (addr->ss.sa_family == AF_INET) { + const uint8_t *u = ((const uint8_t *)&(addr->s4.sin_addr)); + return (u[0] == 0); + } else if (addr->ss.sa_family == AF_INET6) { + const uint8_t *u = ((const uint8_t *)&(addr->s6.sin6_addr)); + int i; + for (i = 0; i <= 15; ++i) { + if (u[i]) + return 0; + } + return 1; + } + } + return 0; } /////// Map "public" address to "private" address ////////////// @@ -533,44 +542,40 @@ static ioa_addr **private_addrs = NULL; static size_t mcount = 0; static size_t msz = 0; -void ioa_addr_add_mapping(ioa_addr *apub, ioa_addr *apriv) -{ - size_t new_size = msz + sizeof(ioa_addr*); - public_addrs = (ioa_addr**)realloc(public_addrs, new_size); - private_addrs = (ioa_addr**)realloc(private_addrs, new_size); - public_addrs[mcount]=(ioa_addr*)malloc(sizeof(ioa_addr)); - private_addrs[mcount]=(ioa_addr*)malloc(sizeof(ioa_addr)); - addr_cpy(public_addrs[mcount],apub); - addr_cpy(private_addrs[mcount],apriv); - ++mcount; - msz += sizeof(ioa_addr*); +void ioa_addr_add_mapping(ioa_addr *apub, ioa_addr *apriv) { + size_t new_size = msz + sizeof(ioa_addr *); + public_addrs = (ioa_addr **)realloc(public_addrs, new_size); + private_addrs = (ioa_addr **)realloc(private_addrs, new_size); + public_addrs[mcount] = (ioa_addr *)malloc(sizeof(ioa_addr)); + private_addrs[mcount] = (ioa_addr *)malloc(sizeof(ioa_addr)); + addr_cpy(public_addrs[mcount], apub); + addr_cpy(private_addrs[mcount], apriv); + ++mcount; + msz += sizeof(ioa_addr *); } -void map_addr_from_public_to_private(const ioa_addr *public_addr, ioa_addr *private_addr) -{ - size_t i; - for(i=0;i= 0x30000000L - unsigned int keylen = 0; - EVP_MD_CTX *ctx = EVP_MD_CTX_new(); - if (EVP_default_properties_is_fips_enabled(NULL)) { - EVP_default_properties_enable_fips(NULL, 0); - } - EVP_DigestInit_ex(ctx,EVP_md5(), NULL); - EVP_DigestUpdate(ctx,str,strl); - EVP_DigestFinal(ctx,key,&keylen); - EVP_MD_CTX_free(ctx); + unsigned int keylen = 0; + EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + if (EVP_default_properties_is_fips_enabled(NULL)) { + EVP_default_properties_enable_fips(NULL, 0); + } + EVP_DigestInit_ex(ctx, EVP_md5(), NULL); + EVP_DigestUpdate(ctx, str, strl); + EVP_DigestFinal(ctx, key, &keylen); + EVP_MD_CTX_free(ctx); #else // OPENSSL_VERSION_NUMBER >= 0x10100000L && OPENSSL_VERSION_NUMBER < 0x30000000L - unsigned int keylen = 0; - EVP_MD_CTX *ctx = EVP_MD_CTX_new(); -#if defined EVP_MD_CTX_FLAG_NON_FIPS_ALLOW && ! defined(LIBRESSL_VERSION_NUMBER) - if (FIPS_mode()) { - EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - } + unsigned int keylen = 0; + EVP_MD_CTX *ctx = EVP_MD_CTX_new(); +#if defined EVP_MD_CTX_FLAG_NON_FIPS_ALLOW && !defined(LIBRESSL_VERSION_NUMBER) + if (FIPS_mode()) { + EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + } #endif - EVP_DigestInit_ex(ctx,EVP_md5(), NULL); - EVP_DigestUpdate(ctx,str,strl); - EVP_DigestFinal(ctx,key,&keylen); - EVP_MD_CTX_free(ctx); + EVP_DigestInit_ex(ctx, EVP_md5(), NULL); + EVP_DigestUpdate(ctx, str, strl); + EVP_DigestFinal(ctx, key, &keylen); + EVP_MD_CTX_free(ctx); #endif // OPENSSL_VERSION_NUMBER < 0X10100000L - ret = 0; - } + ret = 0; + } - free(str); + free(str); - return ret; + return ret; } #define PWD_SALT_SIZE (8) -static void readable_string(unsigned char *orig, unsigned char *out, size_t sz) -{ - size_t i = 0; - out[0]=0; +static void readable_string(unsigned char *orig, unsigned char *out, size_t sz) { + size_t i = 0; + out[0] = 0; - for(i = 0; i < sz; ++i) { - snprintf((char*)(out + (i * 2)), 4, "%02x", (unsigned int)orig[i]); - } + for (i = 0; i < sz; ++i) { + snprintf((char *)(out + (i * 2)), 4, "%02x", (unsigned int)orig[i]); + } } -static void generate_enc_password(const char* pwd, char *result, const unsigned char *orig_salt) -{ - unsigned char salt[PWD_SALT_SIZE+1]; - if(!orig_salt) { - generate_random_nonce(salt, PWD_SALT_SIZE); - } else { - memcpy(salt,orig_salt,PWD_SALT_SIZE); - salt[PWD_SALT_SIZE]=0; - } - unsigned char rsalt[PWD_SALT_SIZE*2+1]; - readable_string(salt,rsalt,PWD_SALT_SIZE); - result[0]='$'; - result[1]='5'; - result[2]='$'; - memcpy(result+3,(char*)rsalt,PWD_SALT_SIZE+PWD_SALT_SIZE); - result[3+PWD_SALT_SIZE+PWD_SALT_SIZE]='$'; - unsigned char* out = (unsigned char*)(result+3+PWD_SALT_SIZE+PWD_SALT_SIZE+1); - { +static void generate_enc_password(const char *pwd, char *result, const unsigned char *orig_salt) { + unsigned char salt[PWD_SALT_SIZE + 1]; + if (!orig_salt) { + generate_random_nonce(salt, PWD_SALT_SIZE); + } else { + memcpy(salt, orig_salt, PWD_SALT_SIZE); + salt[PWD_SALT_SIZE] = 0; + } + unsigned char rsalt[PWD_SALT_SIZE * 2 + 1]; + readable_string(salt, rsalt, PWD_SALT_SIZE); + result[0] = '$'; + result[1] = '5'; + result[2] = '$'; + memcpy(result + 3, (char *)rsalt, PWD_SALT_SIZE + PWD_SALT_SIZE); + result[3 + PWD_SALT_SIZE + PWD_SALT_SIZE] = '$'; + unsigned char *out = (unsigned char *)(result + 3 + PWD_SALT_SIZE + PWD_SALT_SIZE + 1); + { #if OPENSSL_VERSION_NUMBER < 0x10100000L - EVP_MD_CTX ctx; + EVP_MD_CTX ctx; #if !defined(OPENSSL_NO_SHA256) && defined(SHA256_DIGEST_LENGTH) - EVP_DigestInit(&ctx,EVP_sha256()); + EVP_DigestInit(&ctx, EVP_sha256()); #else - EVP_DigestInit(&ctx,EVP_sha1()); + EVP_DigestInit(&ctx, EVP_sha1()); #endif - EVP_DigestUpdate(&ctx,salt,PWD_SALT_SIZE); - EVP_DigestUpdate(&ctx,pwd,strlen(pwd)); - { - unsigned char hash[129]; - unsigned int keylen = 0; - EVP_DigestFinal(&ctx,hash,&keylen); - readable_string(hash,out,keylen); - } - EVP_MD_CTX_cleanup(&ctx); + EVP_DigestUpdate(&ctx, salt, PWD_SALT_SIZE); + EVP_DigestUpdate(&ctx, pwd, strlen(pwd)); + { + unsigned char hash[129]; + unsigned int keylen = 0; + EVP_DigestFinal(&ctx, hash, &keylen); + readable_string(hash, out, keylen); + } + EVP_MD_CTX_cleanup(&ctx); #else - EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + EVP_MD_CTX *ctx = EVP_MD_CTX_new(); #if !defined(OPENSSL_NO_SHA256) && defined(SHA256_DIGEST_LENGTH) - EVP_DigestInit(ctx,EVP_sha256()); + EVP_DigestInit(ctx, EVP_sha256()); #else - EVP_DigestInit(ctx,EVP_sha1()); + EVP_DigestInit(ctx, EVP_sha1()); #endif - EVP_DigestUpdate(ctx,salt,PWD_SALT_SIZE); - EVP_DigestUpdate(ctx,pwd,strlen(pwd)); - { - unsigned char hash[129]; - unsigned int keylen = 0; - EVP_DigestFinal(ctx,hash,&keylen); - readable_string(hash,out,keylen); - } - EVP_MD_CTX_free(ctx); + EVP_DigestUpdate(ctx, salt, PWD_SALT_SIZE); + EVP_DigestUpdate(ctx, pwd, strlen(pwd)); + { + unsigned char hash[129]; + unsigned int keylen = 0; + EVP_DigestFinal(ctx, hash, &keylen); + readable_string(hash, out, keylen); + } + EVP_MD_CTX_free(ctx); #endif - } + } } -void generate_new_enc_password(const char* pwd, char *result) -{ - generate_enc_password(pwd, result, NULL); +void generate_new_enc_password(const char *pwd, char *result) { generate_enc_password(pwd, result, NULL); } + +static int encrypted_password(const char *pin, unsigned char *salt) { + size_t min_len = 3 + PWD_SALT_SIZE + PWD_SALT_SIZE + 1 + 32; + if (strlen(pin) >= min_len) { + if ((pin[0] == '$') && (pin[1] == '5') && (pin[2] == '$') && (pin[3 + PWD_SALT_SIZE + PWD_SALT_SIZE] == '$')) { + size_t i = 0; + for (i = 0; i < PWD_SALT_SIZE; ++i) { + const char *c = pin + 3 + i + i; + char sc[3]; + sc[0] = c[0]; + sc[1] = c[1]; + sc[2] = 0; + salt[i] = (unsigned char)strtoul(sc, NULL, 16); + } + return 1; + } + } + return 0; } -static int encrypted_password(const char* pin, unsigned char* salt) -{ - size_t min_len = 3+PWD_SALT_SIZE+PWD_SALT_SIZE+1+32; - if(strlen(pin)>=min_len) { - if((pin[0]=='$') && (pin[1]=='5') && (pin[2]=='$') && (pin[3+PWD_SALT_SIZE+PWD_SALT_SIZE]=='$')) { - size_t i = 0; - for(i=0;i len) { - return -1; - } + /* Validate the size the buffer claims to be */ + size_t bufLen = (size_t)(nswap16(((const uint16_t *)(buf))[1]) + STUN_HEADER_LENGTH); + if (bufLen > len) { + return -1; + } - return bufLen; + return bufLen; } -static int stun_set_command_message_len_str(uint8_t* buf, int len) { - if(len>1) | - ((tt & 0x0E00)>>2) | ((tt & 0x3000)>>2); + uint16_t tt = nswap16(((const uint16_t *)buf)[0]); + + return (tt & 0x000F) | ((tt & 0x00E0) >> 1) | ((tt & 0x0E00) >> 2) | ((tt & 0x3000) >> 2); } uint16_t stun_get_msg_type_str(const uint8_t *buf, size_t len) { - if(!buf || len<2) return (uint16_t)-1; - return ((nswap16(((const uint16_t*)buf)[0])) & 0x3FFF); + if (!buf || len < 2) + return (uint16_t)-1; + return ((nswap16(((const uint16_t *)buf)[0])) & 0x3FFF); } -int is_channel_msg_str(const uint8_t* buf, size_t blen) { - return (buf && blen>=4 && STUN_VALID_CHANNEL(nswap16(((const uint16_t*)buf)[0]))); +int is_channel_msg_str(const uint8_t *buf, size_t blen) { + return (buf && blen >= 4 && STUN_VALID_CHANNEL(nswap16(((const uint16_t *)buf)[0]))); } /////////////// message types ///////////////////////////////// -int stun_is_command_message_str(const uint8_t* buf, size_t blen) -{ - if (buf && blen >= STUN_HEADER_LENGTH) { - if (!STUN_VALID_CHANNEL(nswap16(((const uint16_t*)buf)[0]))) { - if ((((uint8_t) buf[0]) & ((uint8_t) (0xC0))) == 0) { - if (nswap32(((const uint32_t*)(buf))[1]) - == STUN_MAGIC_COOKIE) { - uint16_t len = nswap16(((const uint16_t*)(buf))[1]); - if ((len & 0x0003) == 0) { - if ((size_t) (len + STUN_HEADER_LENGTH) == blen) { - return 1; - } - } - } - } - } - } - return 0; +int stun_is_command_message_str(const uint8_t *buf, size_t blen) { + if (buf && blen >= STUN_HEADER_LENGTH) { + if (!STUN_VALID_CHANNEL(nswap16(((const uint16_t *)buf)[0]))) { + if ((((uint8_t)buf[0]) & ((uint8_t)(0xC0))) == 0) { + if (nswap32(((const uint32_t *)(buf))[1]) == STUN_MAGIC_COOKIE) { + uint16_t len = nswap16(((const uint16_t *)(buf))[1]); + if ((len & 0x0003) == 0) { + if ((size_t)(len + STUN_HEADER_LENGTH) == blen) { + return 1; + } + } + } + } + } + } + return 0; } -int old_stun_is_command_message_str(const uint8_t* buf, size_t blen, uint32_t *cookie) -{ - if (buf && blen >= STUN_HEADER_LENGTH) { - if (!STUN_VALID_CHANNEL(nswap16(((const uint16_t*)buf)[0]))) { - if ((((uint8_t) buf[0]) & ((uint8_t) (0xC0))) == 0) { - if (nswap32(((const uint32_t*)(buf))[1]) - != STUN_MAGIC_COOKIE) { - uint16_t len = nswap16(((const uint16_t*)(buf))[1]); - if ((len & 0x0003) == 0) { - if ((size_t) (len + STUN_HEADER_LENGTH) == blen) { - *cookie = nswap32(((const uint32_t*)(buf))[1]); - return 1; - } - } - } - } - } - } - return 0; +int old_stun_is_command_message_str(const uint8_t *buf, size_t blen, uint32_t *cookie) { + if (buf && blen >= STUN_HEADER_LENGTH) { + if (!STUN_VALID_CHANNEL(nswap16(((const uint16_t *)buf)[0]))) { + if ((((uint8_t)buf[0]) & ((uint8_t)(0xC0))) == 0) { + if (nswap32(((const uint32_t *)(buf))[1]) != STUN_MAGIC_COOKIE) { + uint16_t len = nswap16(((const uint16_t *)(buf))[1]); + if ((len & 0x0003) == 0) { + if ((size_t)(len + STUN_HEADER_LENGTH) == blen) { + *cookie = nswap32(((const uint32_t *)(buf))[1]); + return 1; + } + } + } + } + } + } + return 0; } -int stun_is_command_message_full_check_str(const uint8_t* buf, size_t blen, int must_check_fingerprint, int *fingerprint_present) { - if(!stun_is_command_message_str(buf,blen)) - return 0; - stun_attr_ref sar = stun_attr_get_first_by_type_str(buf, blen, STUN_ATTRIBUTE_FINGERPRINT); - if(!sar) { - if(fingerprint_present) - *fingerprint_present = 0; - if(stun_get_method_str(buf,blen) == STUN_METHOD_BINDING) { - return 1; - } - return !must_check_fingerprint; - } - if(stun_attr_get_len(sar) != 4) - return 0; - const uint32_t* fingerprint = (const uint32_t*)stun_attr_get_value(sar); - if(!fingerprint) - return !must_check_fingerprint; - uint32_t crc32len = (uint32_t)((((const uint8_t*)fingerprint)-buf)-4); - int ret = (*fingerprint == nswap32(ns_crc32(buf,crc32len) ^ ((uint32_t)0x5354554e))); - if(ret && fingerprint_present) - *fingerprint_present = ret; - return ret; +int stun_is_command_message_full_check_str(const uint8_t *buf, size_t blen, int must_check_fingerprint, + int *fingerprint_present) { + if (!stun_is_command_message_str(buf, blen)) + return 0; + stun_attr_ref sar = stun_attr_get_first_by_type_str(buf, blen, STUN_ATTRIBUTE_FINGERPRINT); + if (!sar) { + if (fingerprint_present) + *fingerprint_present = 0; + if (stun_get_method_str(buf, blen) == STUN_METHOD_BINDING) { + return 1; + } + return !must_check_fingerprint; + } + if (stun_attr_get_len(sar) != 4) + return 0; + const uint32_t *fingerprint = (const uint32_t *)stun_attr_get_value(sar); + if (!fingerprint) + return !must_check_fingerprint; + uint32_t crc32len = (uint32_t)((((const uint8_t *)fingerprint) - buf) - 4); + int ret = (*fingerprint == nswap32(ns_crc32(buf, crc32len) ^ ((uint32_t)0x5354554e))); + if (ret && fingerprint_present) + *fingerprint_present = ret; + return ret; } -int stun_is_command_message_offset_str(const uint8_t* buf, size_t blen, int offset) { +int stun_is_command_message_offset_str(const uint8_t *buf, size_t blen, int offset) { return stun_is_command_message_str(buf + offset, blen); } -int stun_is_request_str(const uint8_t* buf, size_t len) { - if(is_channel_msg_str(buf,len)) return 0; - return IS_STUN_REQUEST(stun_get_msg_type_str(buf,len)); +int stun_is_request_str(const uint8_t *buf, size_t len) { + if (is_channel_msg_str(buf, len)) + return 0; + return IS_STUN_REQUEST(stun_get_msg_type_str(buf, len)); } -int stun_is_success_response_str(const uint8_t* buf, size_t len) { - if(is_channel_msg_str(buf,len)) return 0; - return IS_STUN_SUCCESS_RESP(stun_get_msg_type_str(buf,len)); +int stun_is_success_response_str(const uint8_t *buf, size_t len) { + if (is_channel_msg_str(buf, len)) + return 0; + return IS_STUN_SUCCESS_RESP(stun_get_msg_type_str(buf, len)); } -int stun_is_error_response_str(const uint8_t* buf, size_t len, int *err_code, uint8_t *err_msg, size_t err_msg_size) { - if(is_channel_msg_str(buf,len)) return 0; - if(IS_STUN_ERR_RESP(stun_get_msg_type_str(buf,len))) { - if(err_code) { +int stun_is_error_response_str(const uint8_t *buf, size_t len, int *err_code, uint8_t *err_msg, size_t err_msg_size) { + if (is_channel_msg_str(buf, len)) + return 0; + if (IS_STUN_ERR_RESP(stun_get_msg_type_str(buf, len))) { + if (err_code) { stun_attr_ref sar = stun_attr_get_first_by_type_str(buf, len, STUN_ATTRIBUTE_ERROR_CODE); - if(sar) { - if(stun_attr_get_len(sar)>=4) { - const uint8_t* val = (const uint8_t*)stun_attr_get_value(sar); - *err_code=(int)(val[2]*100 + val[3]); - if(err_msg && err_msg_size>0) { - err_msg[0]=0; - if(stun_attr_get_len(sar)>4) { - size_t msg_len = stun_attr_get_len(sar) - 4; - if(msg_len>(err_msg_size-1)) - msg_len=err_msg_size - 1; - memcpy(err_msg, val+4, msg_len); - err_msg[msg_len]=0; - } - } - } + if (sar) { + if (stun_attr_get_len(sar) >= 4) { + const uint8_t *val = (const uint8_t *)stun_attr_get_value(sar); + *err_code = (int)(val[2] * 100 + val[3]); + if (err_msg && err_msg_size > 0) { + err_msg[0] = 0; + if (stun_attr_get_len(sar) > 4) { + size_t msg_len = stun_attr_get_len(sar) - 4; + if (msg_len > (err_msg_size - 1)) + msg_len = err_msg_size - 1; + memcpy(err_msg, val + 4, msg_len); + err_msg[msg_len] = 0; + } + } + } } } return 1; @@ -552,558 +541,550 @@ int stun_is_error_response_str(const uint8_t* buf, size_t len, int *err_code, ui return 0; } -int stun_is_challenge_response_str(const uint8_t* buf, size_t len, int *err_code, uint8_t *err_msg, size_t err_msg_size, - uint8_t *realm, uint8_t *nonce, uint8_t *server_name, int *oauth) -{ - int ret = stun_is_error_response_str(buf, len, err_code, err_msg, err_msg_size); +int stun_is_challenge_response_str(const uint8_t *buf, size_t len, int *err_code, uint8_t *err_msg, size_t err_msg_size, + uint8_t *realm, uint8_t *nonce, uint8_t *server_name, int *oauth) { + int ret = stun_is_error_response_str(buf, len, err_code, err_msg, err_msg_size); - if(ret && (((*err_code) == 401) || ((*err_code) == 438) )) { + if (ret && (((*err_code) == 401) || ((*err_code) == 438))) { - stun_attr_ref sar = stun_attr_get_first_by_type_str(buf,len,STUN_ATTRIBUTE_REALM); - if(sar) { + stun_attr_ref sar = stun_attr_get_first_by_type_str(buf, len, STUN_ATTRIBUTE_REALM); + if (sar) { - int found_oauth = 0; + int found_oauth = 0; - const uint8_t *value = stun_attr_get_value(sar); - if(value) { - size_t vlen = (size_t)stun_attr_get_len(sar); - memcpy(realm,value,vlen); - realm[vlen]=0; + const uint8_t *value = stun_attr_get_value(sar); + if (value) { + size_t vlen = (size_t)stun_attr_get_len(sar); + memcpy(realm, value, vlen); + realm[vlen] = 0; - { - sar = stun_attr_get_first_by_type_str(buf,len,STUN_ATTRIBUTE_THIRD_PARTY_AUTHORIZATION); - if(sar) { - value = stun_attr_get_value(sar); - if(value) { - vlen = (size_t)stun_attr_get_len(sar); - if(vlen>0) { - if(server_name) { - memcpy(server_name,value,vlen); - } - found_oauth = 1; - } - } - } - } + { + sar = stun_attr_get_first_by_type_str(buf, len, STUN_ATTRIBUTE_THIRD_PARTY_AUTHORIZATION); + if (sar) { + value = stun_attr_get_value(sar); + if (value) { + vlen = (size_t)stun_attr_get_len(sar); + if (vlen > 0) { + if (server_name) { + memcpy(server_name, value, vlen); + } + found_oauth = 1; + } + } + } + } - sar = stun_attr_get_first_by_type_str(buf,len,STUN_ATTRIBUTE_NONCE); - if(sar) { - value = stun_attr_get_value(sar); - if(value) { - vlen = (size_t)stun_attr_get_len(sar); - memcpy(nonce,value,vlen); - nonce[vlen]=0; - if(oauth) { - *oauth = found_oauth; - } - return 1; - } - } - } - } - } + sar = stun_attr_get_first_by_type_str(buf, len, STUN_ATTRIBUTE_NONCE); + if (sar) { + value = stun_attr_get_value(sar); + if (value) { + vlen = (size_t)stun_attr_get_len(sar); + memcpy(nonce, value, vlen); + nonce[vlen] = 0; + if (oauth) { + *oauth = found_oauth; + } + return 1; + } + } + } + } + } - return 0; -} - -int stun_is_response_str(const uint8_t* buf, size_t len) { - if(is_channel_msg_str(buf,len)) return 0; - if(IS_STUN_SUCCESS_RESP(stun_get_msg_type_str(buf,len))) return 1; - if(IS_STUN_ERR_RESP(stun_get_msg_type_str(buf,len))) return 1; return 0; } -int stun_is_indication_str(const uint8_t* buf, size_t len) { - if(is_channel_msg_str(buf,len)) return 0; - return IS_STUN_INDICATION(stun_get_msg_type_str(buf,len)); +int stun_is_response_str(const uint8_t *buf, size_t len) { + if (is_channel_msg_str(buf, len)) + return 0; + if (IS_STUN_SUCCESS_RESP(stun_get_msg_type_str(buf, len))) + return 1; + if (IS_STUN_ERR_RESP(stun_get_msg_type_str(buf, len))) + return 1; + return 0; } -uint16_t stun_make_request(uint16_t method) { - return GET_STUN_REQUEST(stun_make_type(method)); +int stun_is_indication_str(const uint8_t *buf, size_t len) { + if (is_channel_msg_str(buf, len)) + return 0; + return IS_STUN_INDICATION(stun_get_msg_type_str(buf, len)); } -uint16_t stun_make_indication(uint16_t method) { - return GET_STUN_INDICATION(stun_make_type(method)); -} +uint16_t stun_make_request(uint16_t method) { return GET_STUN_REQUEST(stun_make_type(method)); } -uint16_t stun_make_success_response(uint16_t method) { - return GET_STUN_SUCCESS_RESP(stun_make_type(method)); -} +uint16_t stun_make_indication(uint16_t method) { return GET_STUN_INDICATION(stun_make_type(method)); } -uint16_t stun_make_error_response(uint16_t method) { - return GET_STUN_ERR_RESP(stun_make_type(method)); -} +uint16_t stun_make_success_response(uint16_t method) { return GET_STUN_SUCCESS_RESP(stun_make_type(method)); } + +uint16_t stun_make_error_response(uint16_t method) { return GET_STUN_ERR_RESP(stun_make_type(method)); } //////////////// INIT //////////////////////////////////////////// void stun_init_buffer_str(uint8_t *buf, size_t *len) { - *len=STUN_HEADER_LENGTH; + *len = STUN_HEADER_LENGTH; memset(buf, 0, *len); } -void stun_init_command_str(uint16_t message_type, uint8_t* buf, size_t *len) { - stun_init_buffer_str(buf,len); +void stun_init_command_str(uint16_t message_type, uint8_t *buf, size_t *len) { + stun_init_buffer_str(buf, len); message_type &= (uint16_t)(0x3FFF); - ((uint16_t*)buf)[0]=nswap16(message_type); - ((uint16_t*)buf)[1]=0; - ((uint32_t*)buf)[1]=nswap32(STUN_MAGIC_COOKIE); - stun_tid_generate_in_message_str(buf,NULL); + ((uint16_t *)buf)[0] = nswap16(message_type); + ((uint16_t *)buf)[1] = 0; + ((uint32_t *)buf)[1] = nswap32(STUN_MAGIC_COOKIE); + stun_tid_generate_in_message_str(buf, NULL); } -void old_stun_init_command_str(uint16_t message_type, uint8_t* buf, size_t *len, uint32_t cookie) { - stun_init_buffer_str(buf,len); +void old_stun_init_command_str(uint16_t message_type, uint8_t *buf, size_t *len, uint32_t cookie) { + stun_init_buffer_str(buf, len); message_type &= (uint16_t)(0x3FFF); - ((uint16_t*)buf)[0]=nswap16(message_type); - ((uint16_t*)buf)[1]=0; - ((uint32_t*)buf)[1]=nswap32(cookie); - stun_tid_generate_in_message_str(buf,NULL); + ((uint16_t *)buf)[0] = nswap16(message_type); + ((uint16_t *)buf)[1] = 0; + ((uint32_t *)buf)[1] = nswap32(cookie); + stun_tid_generate_in_message_str(buf, NULL); } -void stun_init_request_str(uint16_t method, uint8_t* buf, size_t *len) { +void stun_init_request_str(uint16_t method, uint8_t *buf, size_t *len) { stun_init_command_str(stun_make_request(method), buf, len); } -void stun_init_indication_str(uint16_t method, uint8_t* buf, size_t *len) { +void stun_init_indication_str(uint16_t method, uint8_t *buf, size_t *len) { stun_init_command_str(stun_make_indication(method), buf, len); } -void stun_init_success_response_str(uint16_t method, uint8_t* buf, size_t *len, stun_tid* id) { +void stun_init_success_response_str(uint16_t method, uint8_t *buf, size_t *len, stun_tid *id) { stun_init_command_str(stun_make_success_response(method), buf, len); - if(id) { + if (id) { stun_tid_message_cpy(buf, id); } } -void old_stun_init_success_response_str(uint16_t method, uint8_t* buf, size_t *len, stun_tid* id, uint32_t cookie) { +void old_stun_init_success_response_str(uint16_t method, uint8_t *buf, size_t *len, stun_tid *id, uint32_t cookie) { old_stun_init_command_str(stun_make_success_response(method), buf, len, cookie); - if(id) { + if (id) { stun_tid_message_cpy(buf, id); } } -const uint8_t* get_default_reason(int error_code) -{ - const uint8_t* reason = (const uint8_t *) "Unknown error"; +const uint8_t *get_default_reason(int error_code) { + const uint8_t *reason = (const uint8_t *)"Unknown error"; - switch (error_code){ - case 300: - reason = (const uint8_t *) "Try Alternate"; - break; - case 400: - reason = (const uint8_t *) "Bad Request"; - break; - case 401: - reason = (const uint8_t *) "Unauthorized"; - break; - case 403: - reason = (const uint8_t *) "Forbidden"; - break; - case 404: - reason = (const uint8_t *) "Not Found"; - break; - case 420: - reason = (const uint8_t *) "Unknown Attribute"; - break; - case 437: - reason = (const uint8_t *) "Allocation Mismatch"; - break; - case 438: - reason = (const uint8_t *) "Stale Nonce"; - break; - case 440: - reason = (const uint8_t *) "Address Family not Supported"; - break; - case 441: - reason = (const uint8_t *) "Wrong Credentials"; - break; - case 442: - reason = (const uint8_t *) "Unsupported Transport Protocol"; - break; - case 443: - reason = (const uint8_t *) "Peer Address Family Mismatch"; - break; - case 446: - reason = (const uint8_t *) "Connection Already Exists"; - break; - case 447: - reason = (const uint8_t *) "Connection Timeout or Failure"; - break; - case 486: - reason = (const uint8_t *) "Allocation Quota Reached"; - break; - case 487: - reason = (const uint8_t *) "Role Conflict"; - break; - case 500: - reason = (const uint8_t *) "Server Error"; - break; - case 508: - reason = (const uint8_t *) "Insufficient Capacity"; - break; - default: - ; - }; + switch (error_code) { + case 300: + reason = (const uint8_t *)"Try Alternate"; + break; + case 400: + reason = (const uint8_t *)"Bad Request"; + break; + case 401: + reason = (const uint8_t *)"Unauthorized"; + break; + case 403: + reason = (const uint8_t *)"Forbidden"; + break; + case 404: + reason = (const uint8_t *)"Not Found"; + break; + case 420: + reason = (const uint8_t *)"Unknown Attribute"; + break; + case 437: + reason = (const uint8_t *)"Allocation Mismatch"; + break; + case 438: + reason = (const uint8_t *)"Stale Nonce"; + break; + case 440: + reason = (const uint8_t *)"Address Family not Supported"; + break; + case 441: + reason = (const uint8_t *)"Wrong Credentials"; + break; + case 442: + reason = (const uint8_t *)"Unsupported Transport Protocol"; + break; + case 443: + reason = (const uint8_t *)"Peer Address Family Mismatch"; + break; + case 446: + reason = (const uint8_t *)"Connection Already Exists"; + break; + case 447: + reason = (const uint8_t *)"Connection Timeout or Failure"; + break; + case 486: + reason = (const uint8_t *)"Allocation Quota Reached"; + break; + case 487: + reason = (const uint8_t *)"Role Conflict"; + break; + case 500: + reason = (const uint8_t *)"Server Error"; + break; + case 508: + reason = (const uint8_t *)"Insufficient Capacity"; + break; + default:; + }; - return reason; + return reason; } -static void stun_init_error_response_common_str(uint8_t* buf, size_t *len, - uint16_t error_code, const uint8_t *reason, - stun_tid* id) -{ +static void stun_init_error_response_common_str(uint8_t *buf, size_t *len, uint16_t error_code, const uint8_t *reason, + stun_tid *id) { - if (!reason || !strcmp((const char*)reason,"Unknown error")) { - reason = get_default_reason(error_code); - } + if (!reason || !strcmp((const char *)reason, "Unknown error")) { + reason = get_default_reason(error_code); + } - uint8_t avalue[513]; - avalue[0] = 0; - avalue[1] = 0; - avalue[2] = (uint8_t) (error_code / 100); - avalue[3] = (uint8_t) (error_code % 100); - strncpy((char*) (avalue + 4), (const char*) reason, sizeof(avalue)-4); - avalue[sizeof(avalue)-1]=0; - int alen = 4 + (int)strlen((const char*) (avalue+4)); + uint8_t avalue[513]; + avalue[0] = 0; + avalue[1] = 0; + avalue[2] = (uint8_t)(error_code / 100); + avalue[3] = (uint8_t)(error_code % 100); + strncpy((char *)(avalue + 4), (const char *)reason, sizeof(avalue) - 4); + avalue[sizeof(avalue) - 1] = 0; + int alen = 4 + (int)strlen((const char *)(avalue + 4)); - //"Manual" padding for compatibility with classic old stun: - { - int rem = alen % 4; - if(rem) { - alen +=(4-rem); - } - } + //"Manual" padding for compatibility with classic old stun: + { + int rem = alen % 4; + if (rem) { + alen += (4 - rem); + } + } - stun_attr_add_str(buf, len, STUN_ATTRIBUTE_ERROR_CODE, (uint8_t*) avalue, alen); - if (id) { - stun_tid_message_cpy(buf, id); - } + stun_attr_add_str(buf, len, STUN_ATTRIBUTE_ERROR_CODE, (uint8_t *)avalue, alen); + if (id) { + stun_tid_message_cpy(buf, id); + } } -void old_stun_init_error_response_str(uint16_t method, uint8_t* buf, size_t *len, - uint16_t error_code, const uint8_t *reason, - stun_tid* id, uint32_t cookie) -{ +void old_stun_init_error_response_str(uint16_t method, uint8_t *buf, size_t *len, uint16_t error_code, + const uint8_t *reason, stun_tid *id, uint32_t cookie) { - old_stun_init_command_str(stun_make_error_response(method), buf, len, cookie); + old_stun_init_command_str(stun_make_error_response(method), buf, len, cookie); - stun_init_error_response_common_str(buf, len, - error_code, reason, - id); + stun_init_error_response_common_str(buf, len, error_code, reason, id); } -void stun_init_error_response_str(uint16_t method, uint8_t* buf, size_t *len, - uint16_t error_code, const uint8_t *reason, - stun_tid* id) -{ +void stun_init_error_response_str(uint16_t method, uint8_t *buf, size_t *len, uint16_t error_code, + const uint8_t *reason, stun_tid *id) { - stun_init_command_str(stun_make_error_response(method), buf, len); + stun_init_command_str(stun_make_error_response(method), buf, len); - stun_init_error_response_common_str(buf, len, - error_code, reason, - id); + stun_init_error_response_common_str(buf, len, error_code, reason, id); } /////////// CHANNEL //////////////////////////////////////////////// -int stun_init_channel_message_str(uint16_t chnumber, uint8_t* buf, size_t *len, int length, int do_padding) -{ - uint16_t rlen = (uint16_t)length; +int stun_init_channel_message_str(uint16_t chnumber, uint8_t *buf, size_t *len, int length, int do_padding) { + uint16_t rlen = (uint16_t)length; - if(length<0 || (MAX_STUN_MESSAGE_SIZE<(4+length))) return -1; - ((uint16_t*)(buf))[0]=nswap16(chnumber); - ((uint16_t*)(buf))[1]=nswap16((uint16_t)length); + if (length < 0 || (MAX_STUN_MESSAGE_SIZE < (4 + length))) + return -1; + ((uint16_t *)(buf))[0] = nswap16(chnumber); + ((uint16_t *)(buf))[1] = nswap16((uint16_t)length); - if(do_padding && (rlen & 0x0003)) - rlen = ((rlen>>2)+1)<<2; + if (do_padding && (rlen & 0x0003)) + rlen = ((rlen >> 2) + 1) << 2; - *len=4+rlen; + *len = 4 + rlen; - return 0; + return 0; } -int stun_is_channel_message_str(const uint8_t *buf, size_t *blen, uint16_t* chnumber, int mandatory_padding) -{ - uint16_t datalen_header; - uint16_t datalen_actual; +int stun_is_channel_message_str(const uint8_t *buf, size_t *blen, uint16_t *chnumber, int mandatory_padding) { + uint16_t datalen_header; + uint16_t datalen_actual; - if (!blen || (*blen < 4)) - return 0; + if (!blen || (*blen < 4)) + return 0; - uint16_t chn = nswap16(((const uint16_t*)(buf))[0]); - if (!STUN_VALID_CHANNEL(chn)) - return 0; + uint16_t chn = nswap16(((const uint16_t *)(buf))[0]); + if (!STUN_VALID_CHANNEL(chn)) + return 0; - if(*blen>(uint16_t)-1) - *blen=(uint16_t)-1; + if (*blen > (uint16_t)-1) + *blen = (uint16_t)-1; - datalen_actual = (uint16_t)(*blen) - 4; - datalen_header = ((const uint16_t*)buf)[1]; - datalen_header = nswap16(datalen_header); + datalen_actual = (uint16_t)(*blen) - 4; + datalen_header = ((const uint16_t *)buf)[1]; + datalen_header = nswap16(datalen_header); - if (datalen_header > datalen_actual) - return 0; + if (datalen_header > datalen_actual) + return 0; - if (datalen_header != datalen_actual) { + if (datalen_header != datalen_actual) { - /* maybe there are padding bytes for 32-bit alignment. Mandatory for TCP. Optional for UDP */ + /* maybe there are padding bytes for 32-bit alignment. Mandatory for TCP. Optional for UDP */ - if(datalen_actual & 0x0003) { + if (datalen_actual & 0x0003) { - if(mandatory_padding) { - return 0; - } else if (datalen_header == 0) { - return 0; - } else { - uint16_t diff = datalen_actual - datalen_header; - if (diff > 3) - return 0; - } - } - } + if (mandatory_padding) { + return 0; + } else if (datalen_header == 0) { + return 0; + } else { + uint16_t diff = datalen_actual - datalen_header; + if (diff > 3) + return 0; + } + } + } - *blen = datalen_header + 4; + *blen = datalen_header + 4; - if (chnumber) - *chnumber = chn; + if (chnumber) + *chnumber = chn; - return 1; + return 1; } ////////// STUN message /////////////////////////////// -static inline int sheadof(const char *head, const char* full, int ignore_case) -{ - while(*head) { - if(*head != *full) { - if(ignore_case && (tolower((int)*head)==tolower((int)*full))) { - //OK - } else { - return 0; - } - } - ++head;++full; - } - return 1; +static inline int sheadof(const char *head, const char *full, int ignore_case) { + while (*head) { + if (*head != *full) { + if (ignore_case && (tolower((int)*head) == tolower((int)*full))) { + // OK + } else { + return 0; + } + } + ++head; + ++full; + } + return 1; } -static inline const char* findstr(const char *hay, size_t slen, const char *needle, int ignore_case) -{ - const char *ret = NULL; +static inline const char *findstr(const char *hay, size_t slen, const char *needle, int ignore_case) { + const char *ret = NULL; - if(hay && slen && needle) { - size_t nlen=strlen(needle); - if(nlen<=slen) { - size_t smax = slen-nlen+1; - size_t i; - const char *sp = hay; - for(i=0;i=12) { - if((strstr(s,"GET ")==s) ||(strstr(s,"POST ")==s) || (strstr(s,"DELETE ")==s) || (strstr(s,"PUT ")==s)) { - const char *sp=findstr(s+4,blen-4," HTTP/",0); - if(sp) { - sp += 6; - size_t diff_blen = sp-s; - if(diff_blen+4 <= blen) { - sp=findstr(sp,blen-diff_blen,"\r\n\r\n",0); - if(sp) { - int ret_len = (int)(sp-s+4); - const char* clheader = "content-length: "; - const char* cl = findstr(s,sp-s,clheader,1); - if(cl) { - unsigned long clen = strtoul(cl+strlen(clheader),NULL,10); - if(clen>0 && clen<(0x0FFFFFFF)) { - ret_len += (int)clen; - } - } - return ret_len; - } - } - } - } - } - return 0; + if (s && blen >= 12) { + if ((strstr(s, "GET ") == s) || (strstr(s, "POST ") == s) || (strstr(s, "DELETE ") == s) || + (strstr(s, "PUT ") == s)) { + const char *sp = findstr(s + 4, blen - 4, " HTTP/", 0); + if (sp) { + sp += 6; + size_t diff_blen = sp - s; + if (diff_blen + 4 <= blen) { + sp = findstr(sp, blen - diff_blen, "\r\n\r\n", 0); + if (sp) { + int ret_len = (int)(sp - s + 4); + const char *clheader = "content-length: "; + const char *cl = findstr(s, sp - s, clheader, 1); + if (cl) { + unsigned long clen = strtoul(cl + strlen(clheader), NULL, 10); + if (clen > 0 && clen < (0x0FFFFFFF)) { + ret_len += (int)clen; + } + } + return ret_len; + } + } + } + } + } + return 0; } -int is_http(const char *s, size_t blen) { - return is_http_inline(s, blen); -} +int is_http(const char *s, size_t blen) { return is_http_inline(s, blen); } int stun_get_message_len_str(uint8_t *buf, size_t blen, int padding, size_t *app_len) { - if (buf && blen) { - /* STUN request/response ? */ - if (buf && blen >= STUN_HEADER_LENGTH) { - if (!STUN_VALID_CHANNEL(nswap16(((const uint16_t*)buf)[0]))) { - if ((((uint8_t) buf[0]) & ((uint8_t) (0xC0))) == 0) { - if (nswap32(((const uint32_t*)(buf))[1]) - == STUN_MAGIC_COOKIE) { - uint16_t len = nswap16(((const uint16_t*)(buf))[1]); - if ((len & 0x0003) == 0) { - len += STUN_HEADER_LENGTH; - if ((size_t) len <= blen) { - *app_len = (size_t)len; - return (int)len; - } - } - } - } - } - } + if (buf && blen) { + /* STUN request/response ? */ + if (buf && blen >= STUN_HEADER_LENGTH) { + if (!STUN_VALID_CHANNEL(nswap16(((const uint16_t *)buf)[0]))) { + if ((((uint8_t)buf[0]) & ((uint8_t)(0xC0))) == 0) { + if (nswap32(((const uint32_t *)(buf))[1]) == STUN_MAGIC_COOKIE) { + uint16_t len = nswap16(((const uint16_t *)(buf))[1]); + if ((len & 0x0003) == 0) { + len += STUN_HEADER_LENGTH; + if ((size_t)len <= blen) { + *app_len = (size_t)len; + return (int)len; + } + } + } + } + } + } - //HTTP request ? - { - int http_len = is_http_inline(((char*)buf), blen); - if((http_len>0) && ((size_t)http_len<=blen)) { - *app_len = (size_t)http_len; - return http_len; - } - } + // HTTP request ? + { + int http_len = is_http_inline(((char *)buf), blen); + if ((http_len > 0) && ((size_t)http_len <= blen)) { + *app_len = (size_t)http_len; + return http_len; + } + } - /* STUN channel ? */ - if(blen>=4) { - uint16_t chn=nswap16(((const uint16_t*)(buf))[0]); - if(STUN_VALID_CHANNEL(chn)) { + /* STUN channel ? */ + if (blen >= 4) { + uint16_t chn = nswap16(((const uint16_t *)(buf))[0]); + if (STUN_VALID_CHANNEL(chn)) { - uint16_t bret = (4+(nswap16(((const uint16_t*)(buf))[1]))); + uint16_t bret = (4 + (nswap16(((const uint16_t *)(buf))[1]))); - *app_len = bret; + *app_len = bret; - if(padding && (bret & 0x0003)) { - bret = ((bret>>2)+1)<<2; - } + if (padding && (bret & 0x0003)) { + bret = ((bret >> 2) + 1) << 2; + } - if(bret<=blen) { - return bret; - } - } - } + if (bret <= blen) { + return bret; + } + } + } + } - } - - return -1; + return -1; } ////////// ALLOCATE /////////////////////////////////// -int stun_set_allocate_request_str(uint8_t* buf, size_t *len, uint32_t lifetime, int af4, int af6, - uint8_t transport, int mobile, const char* rt, int ep) { +int stun_set_allocate_request_str(uint8_t *buf, size_t *len, uint32_t lifetime, int af4, int af6, uint8_t transport, + int mobile, const char *rt, int ep) { stun_init_request_str(STUN_METHOD_ALLOCATE, buf, len); - //REQUESTED-TRANSPORT + // REQUESTED-TRANSPORT { uint8_t field[4]; - field[0]=transport; - field[1]=0; - field[2]=0; - field[3]=0; - if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_REQUESTED_TRANSPORT,field,sizeof(field))<0) return -1; + field[0] = transport; + field[1] = 0; + field[2] = 0; + field[3] = 0; + if (stun_attr_add_str(buf, len, STUN_ATTRIBUTE_REQUESTED_TRANSPORT, field, sizeof(field)) < 0) + return -1; } - //LIFETIME + // LIFETIME { - if(lifetime<1) lifetime=STUN_DEFAULT_ALLOCATE_LIFETIME; - uint32_t field=nswap32(lifetime); - if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_LIFETIME,(uint8_t*)(&field),sizeof(field))<0) return -1; + if (lifetime < 1) + lifetime = STUN_DEFAULT_ALLOCATE_LIFETIME; + uint32_t field = nswap32(lifetime); + if (stun_attr_add_str(buf, len, STUN_ATTRIBUTE_LIFETIME, (uint8_t *)(&field), sizeof(field)) < 0) + return -1; } - //MICE - if(mobile) { - if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_MOBILITY_TICKET,(const uint8_t*)"",0)<0) return -1; + // MICE + if (mobile) { + if (stun_attr_add_str(buf, len, STUN_ATTRIBUTE_MOBILITY_TICKET, (const uint8_t *)"", 0) < 0) + return -1; } - if(ep>-1) { - uint8_t value = ep ? 0x80 : 0x00; - if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_EVEN_PORT,(const uint8_t*)&value,1)<0) return -1; + if (ep > -1) { + uint8_t value = ep ? 0x80 : 0x00; + if (stun_attr_add_str(buf, len, STUN_ATTRIBUTE_EVEN_PORT, (const uint8_t *)&value, 1) < 0) + return -1; } - //RESERVATION-TOKEN, EVEN-PORT and DUAL-ALLOCATION are mutually exclusive: - if(rt) { + // RESERVATION-TOKEN, EVEN-PORT and DUAL-ALLOCATION are mutually exclusive: + if (rt) { - stun_attr_add_str(buf,len, STUN_ATTRIBUTE_RESERVATION_TOKEN, (const uint8_t*) rt, 8); + stun_attr_add_str(buf, len, STUN_ATTRIBUTE_RESERVATION_TOKEN, (const uint8_t *)rt, 8); } else { - //ADRESS-FAMILY - if (af4 && !af6) { - uint8_t field[4]; - field[0] = (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4; - field[1]=0; - field[2]=0; - field[3]=0; - if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY,field,sizeof(field))<0) return -1; - } + // ADRESS-FAMILY + if (af4 && !af6) { + uint8_t field[4]; + field[0] = (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4; + field[1] = 0; + field[2] = 0; + field[3] = 0; + if (stun_attr_add_str(buf, len, STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY, field, sizeof(field)) < 0) + return -1; + } - if (af6 && !af4) { - uint8_t field[4]; - field[0] = (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; - field[1]=0; - field[2]=0; - field[3]=0; - if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY,field,sizeof(field))<0) return -1; - } + if (af6 && !af4) { + uint8_t field[4]; + field[0] = (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; + field[1] = 0; + field[2] = 0; + field[3] = 0; + if (stun_attr_add_str(buf, len, STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY, field, sizeof(field)) < 0) + return -1; + } - if (af4 && af6) { - uint8_t field[4]; - field[0] = (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; - field[1]=0; - field[2]=0; - field[3]=0; - if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_ADDITIONAL_ADDRESS_FAMILY,field,sizeof(field))<0) return -1; - } + if (af4 && af6) { + uint8_t field[4]; + field[0] = (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; + field[1] = 0; + field[2] = 0; + field[3] = 0; + if (stun_attr_add_str(buf, len, STUN_ATTRIBUTE_ADDITIONAL_ADDRESS_FAMILY, field, sizeof(field)) < 0) + return -1; + } } return 0; } -int stun_set_allocate_response_str(uint8_t* buf, size_t *len, stun_tid* tid, - const ioa_addr *relayed_addr1, const ioa_addr *relayed_addr2, - const ioa_addr *reflexive_addr, - uint32_t lifetime, uint32_t max_lifetime, int error_code, const uint8_t *reason, - uint64_t reservation_token, char* mobile_id) { +int stun_set_allocate_response_str(uint8_t *buf, size_t *len, stun_tid *tid, const ioa_addr *relayed_addr1, + const ioa_addr *relayed_addr2, const ioa_addr *reflexive_addr, uint32_t lifetime, + uint32_t max_lifetime, int error_code, const uint8_t *reason, + uint64_t reservation_token, char *mobile_id) { - if(!error_code) { + if (!error_code) { stun_init_success_response_str(STUN_METHOD_ALLOCATE, buf, len, tid); - - if(relayed_addr1) { - if(stun_attr_add_addr_str(buf,len,STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS,relayed_addr1)<0) return -1; + + if (relayed_addr1) { + if (stun_attr_add_addr_str(buf, len, STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS, relayed_addr1) < 0) + return -1; } - if(relayed_addr2) { - if(stun_attr_add_addr_str(buf,len,STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS,relayed_addr2)<0) return -1; - } - - if(reflexive_addr) { - if(stun_attr_add_addr_str(buf,len,STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS,reflexive_addr)<0) return -1; + if (relayed_addr2) { + if (stun_attr_add_addr_str(buf, len, STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS, relayed_addr2) < 0) + return -1; } - if(reservation_token) { - reservation_token=nswap64(reservation_token); - stun_attr_add_str(buf,len,STUN_ATTRIBUTE_RESERVATION_TOKEN,(uint8_t*)(&reservation_token),8); + if (reflexive_addr) { + if (stun_attr_add_addr_str(buf, len, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, reflexive_addr) < 0) + return -1; + } + + if (reservation_token) { + reservation_token = nswap64(reservation_token); + stun_attr_add_str(buf, len, STUN_ATTRIBUTE_RESERVATION_TOKEN, (uint8_t *)(&reservation_token), 8); } { - if(lifetime<1) lifetime=STUN_DEFAULT_ALLOCATE_LIFETIME; - else if(lifetime>max_lifetime) lifetime = max_lifetime; + if (lifetime < 1) + lifetime = STUN_DEFAULT_ALLOCATE_LIFETIME; + else if (lifetime > max_lifetime) + lifetime = max_lifetime; - uint32_t field=nswap32(lifetime); - if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_LIFETIME,(uint8_t*)(&field),sizeof(field))<0) return -1; + uint32_t field = nswap32(lifetime); + if (stun_attr_add_str(buf, len, STUN_ATTRIBUTE_LIFETIME, (uint8_t *)(&field), sizeof(field)) < 0) + return -1; } - if(mobile_id && *mobile_id) { - if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_MOBILITY_TICKET,(uint8_t*)mobile_id,(int)strlen(mobile_id))<0) return -1; + if (mobile_id && *mobile_id) { + if (stun_attr_add_str(buf, len, STUN_ATTRIBUTE_MOBILITY_TICKET, (uint8_t *)mobile_id, (int)strlen(mobile_id)) < 0) + return -1; } } else { @@ -1115,31 +1096,35 @@ int stun_set_allocate_response_str(uint8_t* buf, size_t *len, stun_tid* tid, /////////////// CHANNEL BIND /////////////////////////////////////// -uint16_t stun_set_channel_bind_request_str(uint8_t* buf, size_t *len, - const ioa_addr* peer_addr, uint16_t channel_number) { +uint16_t stun_set_channel_bind_request_str(uint8_t *buf, size_t *len, const ioa_addr *peer_addr, + uint16_t channel_number) { - if(!STUN_VALID_CHANNEL(channel_number)) { - channel_number = 0x4000 + ((uint16_t)(((uint32_t)turn_random())%(0x7FFF-0x4000+1))); + if (!STUN_VALID_CHANNEL(channel_number)) { + channel_number = 0x4000 + ((uint16_t)(((uint32_t)turn_random()) % (0x7FFF - 0x4000 + 1))); } - + stun_init_request_str(STUN_METHOD_CHANNEL_BIND, buf, len); - - if(stun_attr_add_channel_number_str(buf, len, channel_number)<0) return 0; - - if(!peer_addr) { + + if (stun_attr_add_channel_number_str(buf, len, channel_number) < 0) + return 0; + + if (!peer_addr) { ioa_addr ca; memset(&ca, 0, sizeof(ioa_addr)); - - if(stun_attr_add_addr_str(buf,len,STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &ca)<0) return 0; + + if (stun_attr_add_addr_str(buf, len, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &ca) < 0) + return 0; } else { - if(stun_attr_add_addr_str(buf,len,STUN_ATTRIBUTE_XOR_PEER_ADDRESS, peer_addr)<0) return 0; + if (stun_attr_add_addr_str(buf, len, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, peer_addr) < 0) + return 0; } return channel_number; } -void stun_set_channel_bind_response_str(uint8_t* buf, size_t *len, stun_tid* tid, int error_code, const uint8_t *reason) { - if(!error_code) { +void stun_set_channel_bind_response_str(uint8_t *buf, size_t *len, stun_tid *tid, int error_code, + const uint8_t *reason) { + if (!error_code) { stun_init_success_response_str(STUN_METHOD_CHANNEL_BIND, buf, len, tid); } else { stun_init_error_response_str(STUN_METHOD_CHANNEL_BIND, buf, len, error_code, reason, tid); @@ -1148,56 +1133,53 @@ void stun_set_channel_bind_response_str(uint8_t* buf, size_t *len, stun_tid* tid /////////////// BINDING /////////////////////////////////////// -void stun_set_binding_request_str(uint8_t* buf, size_t *len) { - stun_init_request_str(STUN_METHOD_BINDING, buf, len); -} +void stun_set_binding_request_str(uint8_t *buf, size_t *len) { stun_init_request_str(STUN_METHOD_BINDING, buf, len); } -int stun_set_binding_response_str(uint8_t* buf, size_t *len, stun_tid* tid, - const ioa_addr *reflexive_addr, int error_code, const uint8_t *reason, - uint32_t cookie, int old_stun, int no_stun_backward_compatibility) +int stun_set_binding_response_str(uint8_t *buf, size_t *len, stun_tid *tid, const ioa_addr *reflexive_addr, + int error_code, const uint8_t *reason, uint32_t cookie, int old_stun, + int no_stun_backward_compatibility) { - if (!error_code) { - if (!old_stun) { - stun_init_success_response_str(STUN_METHOD_BINDING, buf, len, tid); - } else { - old_stun_init_success_response_str(STUN_METHOD_BINDING, buf, len, tid, cookie); - } - if(!old_stun && reflexive_addr) { - if (stun_attr_add_addr_str(buf, len, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, reflexive_addr) < 0) - return -1; - } - if(reflexive_addr) { - if (!no_stun_backward_compatibility && stun_attr_add_addr_str(buf, len, STUN_ATTRIBUTE_MAPPED_ADDRESS, reflexive_addr) < 0) - return -1; - } - } else if (!old_stun) { - stun_init_error_response_str(STUN_METHOD_BINDING, buf, len, error_code, reason, tid); - } else { - old_stun_init_error_response_str(STUN_METHOD_BINDING, buf, len, error_code, reason, tid, cookie); - } + if (!error_code) { + if (!old_stun) { + stun_init_success_response_str(STUN_METHOD_BINDING, buf, len, tid); + } else { + old_stun_init_success_response_str(STUN_METHOD_BINDING, buf, len, tid, cookie); + } + if (!old_stun && reflexive_addr) { + if (stun_attr_add_addr_str(buf, len, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, reflexive_addr) < 0) + return -1; + } + if (reflexive_addr) { + if (!no_stun_backward_compatibility && + stun_attr_add_addr_str(buf, len, STUN_ATTRIBUTE_MAPPED_ADDRESS, reflexive_addr) < 0) + return -1; + } + } else if (!old_stun) { + stun_init_error_response_str(STUN_METHOD_BINDING, buf, len, error_code, reason, tid); + } else { + old_stun_init_error_response_str(STUN_METHOD_BINDING, buf, len, error_code, reason, tid, cookie); + } - return 0; + return 0; } -int stun_is_binding_request_str(const uint8_t* buf, size_t len, size_t offset) -{ - if(offset < len) { +int stun_is_binding_request_str(const uint8_t *buf, size_t len, size_t offset) { + if (offset < len) { buf += offset; len -= offset; if (stun_is_command_message_str(buf, len)) { if (stun_is_request_str(buf, len) && (stun_get_method_str(buf, len) == STUN_METHOD_BINDING)) { - return 1; + return 1; } } } return 0; } -int stun_is_binding_response_str(const uint8_t* buf, size_t len) { - if(stun_is_command_message_str(buf,len) && - (stun_get_method_str(buf,len)==STUN_METHOD_BINDING)) { - if(stun_is_response_str(buf,len)) { +int stun_is_binding_response_str(const uint8_t *buf, size_t len) { + if (stun_is_command_message_str(buf, len) && (stun_get_method_str(buf, len) == STUN_METHOD_BINDING)) { + if (stun_is_response_str(buf, len)) { return 1; } } @@ -1206,72 +1188,82 @@ int stun_is_binding_response_str(const uint8_t* buf, size_t len) { /////////////////////////////// TID /////////////////////////////// - int stun_tid_equals(const stun_tid *id1, const stun_tid *id2) { - if(id1==id2) return 1; - if(!id1) return 0; - if(!id2) return 0; + if (id1 == id2) + return 1; + if (!id1) + return 0; + if (!id2) + return 0; { - unsigned int i=0; - for(i=0;itsx_id[i]!=id2->tsx_id[i]) return 0; + unsigned int i = 0; + for (i = 0; i < STUN_TID_SIZE; ++i) { + if (id1->tsx_id[i] != id2->tsx_id[i]) + return 0; } } return 1; } void stun_tid_cpy(stun_tid *id1, const stun_tid *id2) { - if(!id1) return; - if(!id2) return; - memcpy((void*)(id1->tsx_id),(const void*)(id2->tsx_id),STUN_TID_SIZE); + if (!id1) + return; + if (!id2) + return; + memcpy((void *)(id1->tsx_id), (const void *)(id2->tsx_id), STUN_TID_SIZE); } -static void stun_tid_string_cpy(uint8_t* s, const stun_tid* id) { - if(s && id) { - memcpy(s,(const void*)(id->tsx_id),STUN_TID_SIZE); +static void stun_tid_string_cpy(uint8_t *s, const stun_tid *id) { + if (s && id) { + memcpy(s, (const void *)(id->tsx_id), STUN_TID_SIZE); } } -static void stun_tid_from_string(const uint8_t* s, stun_tid* id) { - if(s && id) { - memcpy((void*)(id->tsx_id),s,STUN_TID_SIZE); +static void stun_tid_from_string(const uint8_t *s, stun_tid *id) { + if (s && id) { + memcpy((void *)(id->tsx_id), s, STUN_TID_SIZE); } } -void stun_tid_from_message_str(const uint8_t* buf, size_t len, stun_tid* id) { - UNUSED_ARG(len); - stun_tid_from_string(buf+8, id); +void stun_tid_from_message_str(const uint8_t *buf, size_t len, stun_tid *id) { + UNUSED_ARG(len); + stun_tid_from_string(buf + 8, id); } -void stun_tid_message_cpy(uint8_t* buf, const stun_tid* id) { - if(buf && id) { - stun_tid_string_cpy(buf+8, id); +void stun_tid_message_cpy(uint8_t *buf, const stun_tid *id) { + if (buf && id) { + stun_tid_string_cpy(buf + 8, id); } } -void stun_tid_generate(stun_tid* id) { - if(id) { +void stun_tid_generate(stun_tid *id) { + if (id) { turn_random_tid_size(id->tsx_id); } } -void stun_tid_generate_in_message_str(uint8_t* buf, stun_tid* id) { +void stun_tid_generate_in_message_str(uint8_t *buf, stun_tid *id) { stun_tid tmp; - if(!id) id=&tmp; + if (!id) + id = &tmp; stun_tid_generate(id); stun_tid_message_cpy(buf, id); } /////////////////// TIME //////////////////////////////////////////////////////// -turn_time_t stun_adjust_allocate_lifetime(turn_time_t lifetime, turn_time_t max_allowed_lifetime, turn_time_t max_lifetime) { +turn_time_t stun_adjust_allocate_lifetime(turn_time_t lifetime, turn_time_t max_allowed_lifetime, + turn_time_t max_lifetime) { - if(!lifetime) lifetime = STUN_DEFAULT_ALLOCATE_LIFETIME; - else if(lifetimemax_allowed_lifetime) lifetime = max_allowed_lifetime; + if (!lifetime) + lifetime = STUN_DEFAULT_ALLOCATE_LIFETIME; + else if (lifetime < STUN_MIN_ALLOCATE_LIFETIME) + lifetime = STUN_MIN_ALLOCATE_LIFETIME; + else if (lifetime > max_allowed_lifetime) + lifetime = max_allowed_lifetime; - if(max_lifetime && (max_lifetime < lifetime)) { - lifetime = max_lifetime; + if (max_lifetime && (max_lifetime < lifetime)) { + lifetime = max_lifetime; } return lifetime; @@ -1280,71 +1272,72 @@ turn_time_t stun_adjust_allocate_lifetime(turn_time_t lifetime, turn_time_t max_ ////////////// ATTR ///////////////////////////////////////////////////////////// int stun_attr_get_type(stun_attr_ref attr) { - if(attr) - return (int)(nswap16(((const uint16_t*)attr)[0])); + if (attr) + return (int)(nswap16(((const uint16_t *)attr)[0])); return -1; } int stun_attr_get_len(stun_attr_ref attr) { - if(attr) - return (int)(nswap16(((const uint16_t*)attr)[1])); + if (attr) + return (int)(nswap16(((const uint16_t *)attr)[1])); return -1; } -const uint8_t* stun_attr_get_value(stun_attr_ref attr) { - if(attr) { - int len = (int)(nswap16(((const uint16_t*)attr)[1])); - if(len<1) return NULL; - return ((const uint8_t*)attr)+4; +const uint8_t *stun_attr_get_value(stun_attr_ref attr) { + if (attr) { + int len = (int)(nswap16(((const uint16_t *)attr)[1])); + if (len < 1) + return NULL; + return ((const uint8_t *)attr) + 4; } return NULL; } -int stun_get_requested_address_family(stun_attr_ref attr) -{ - if (attr) { - int len = (int) (nswap16(((const uint16_t*)attr)[1])); - if (len != 4) - return STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_INVALID; - int val = ((const uint8_t*) attr)[4]; - switch (val){ - case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4: - return val; - case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6: - return val; - default: - return STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_INVALID; - }; - } - return STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT; +int stun_get_requested_address_family(stun_attr_ref attr) { + if (attr) { + int len = (int)(nswap16(((const uint16_t *)attr)[1])); + if (len != 4) + return STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_INVALID; + int val = ((const uint8_t *)attr)[4]; + switch (val) { + case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4: + return val; + case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6: + return val; + default: + return STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_INVALID; + }; + } + return STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT; } uint16_t stun_attr_get_channel_number(stun_attr_ref attr) { - if(attr) { - const uint8_t* value = stun_attr_get_value(attr); - if(value && (stun_attr_get_len(attr) >= 2)) { - uint16_t cn=nswap16(((const uint16_t*)value)[0]); - if(STUN_VALID_CHANNEL(cn)) return cn; + if (attr) { + const uint8_t *value = stun_attr_get_value(attr); + if (value && (stun_attr_get_len(attr) >= 2)) { + uint16_t cn = nswap16(((const uint16_t *)value)[0]); + if (STUN_VALID_CHANNEL(cn)) + return cn; } } return 0; } band_limit_t stun_attr_get_bandwidth(stun_attr_ref attr) { - if(attr) { - const uint8_t* value = stun_attr_get_value(attr); - if(value && (stun_attr_get_len(attr) >= 4)) { - uint32_t bps=nswap32(((const uint32_t*)value)[0]); + if (attr) { + const uint8_t *value = stun_attr_get_value(attr); + if (value && (stun_attr_get_len(attr) >= 4)) { + uint32_t bps = nswap32(((const uint32_t *)value)[0]); return (band_limit_t)(bps << 7); } } return 0; } -uint64_t stun_attr_get_reservation_token_value(stun_attr_ref attr) { - if(attr) { - const uint8_t* value = stun_attr_get_value(attr); - if(value && (stun_attr_get_len(attr) == 8)) { +uint64_t stun_attr_get_reservation_token_value(stun_attr_ref attr) { + if (attr) { + const uint8_t *value = stun_attr_get_value(attr); + if (value && (stun_attr_get_len(attr) == 8)) { uint64_t token; memcpy(&token, value, sizeof(uint64_t)); return nswap64(token); @@ -1355,8 +1348,8 @@ uint64_t stun_attr_get_reservation_token_value(stun_attr_ref attr) { int stun_attr_is_addr(stun_attr_ref attr) { - if(attr) { - switch(stun_attr_get_type(attr)) { + if (attr) { + switch (stun_attr_get_type(attr)) { case STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS: case STUN_ATTRIBUTE_XOR_PEER_ADDRESS: case STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS: @@ -1370,31 +1363,31 @@ int stun_attr_is_addr(stun_attr_ref attr) { case STUN_ATTRIBUTE_OTHER_ADDRESS: return 1; break; - default: - ; + default:; }; } return 0; } uint8_t stun_attr_get_even_port(stun_attr_ref attr) { - if(attr) { - const uint8_t* value=stun_attr_get_value(attr); - if(value) { - if((uint8_t)(value[0]) > 0x7F) return 1; + if (attr) { + const uint8_t *value = stun_attr_get_value(attr); + if (value) { + if ((uint8_t)(value[0]) > 0x7F) + return 1; } } return 0; } -stun_attr_ref stun_attr_get_first_by_type_str(const uint8_t* buf, size_t len, uint16_t attr_type) { +stun_attr_ref stun_attr_get_first_by_type_str(const uint8_t *buf, size_t len, uint16_t attr_type) { - stun_attr_ref attr=stun_attr_get_first_str(buf,len); - while(attr) { - if(stun_attr_get_type(attr) == attr_type) { + stun_attr_ref attr = stun_attr_get_first_str(buf, len); + while (attr) { + if (stun_attr_get_type(attr) == attr_type) { return attr; } - attr=stun_attr_get_next_str(buf,len,attr); + attr = stun_attr_get_next_str(buf, len, attr); } return NULL; @@ -1402,19 +1395,19 @@ stun_attr_ref stun_attr_get_first_by_type_str(const uint8_t* buf, size_t len, ui static stun_attr_ref stun_attr_check_valid(stun_attr_ref attr, size_t remaining) { - if(remaining >= 4) { + if (remaining >= 4) { /* Read the size of the attribute */ size_t attrlen = stun_attr_get_len(attr); remaining -= 4; /* Round to boundary */ uint16_t rem4 = ((uint16_t)attrlen) & 0x0003; - if(rem4) { - attrlen = attrlen+4-(int)rem4; + if (rem4) { + attrlen = attrlen + 4 - (int)rem4; } /* Check that there's enough space remaining */ - if(attrlen <= remaining) { + if (attrlen <= remaining) { return attr; } } @@ -1422,102 +1415,107 @@ static stun_attr_ref stun_attr_check_valid(stun_attr_ref attr, size_t remaining) return NULL; } -stun_attr_ref stun_attr_get_first_str(const uint8_t* buf, size_t len) { +stun_attr_ref stun_attr_get_first_str(const uint8_t *buf, size_t len) { - int bufLen = stun_get_command_message_len_str(buf,len); - if(bufLen > STUN_HEADER_LENGTH) { - stun_attr_ref attr = (stun_attr_ref)(buf+STUN_HEADER_LENGTH); + int bufLen = stun_get_command_message_len_str(buf, len); + if (bufLen > STUN_HEADER_LENGTH) { + stun_attr_ref attr = (stun_attr_ref)(buf + STUN_HEADER_LENGTH); return stun_attr_check_valid(attr, bufLen - STUN_HEADER_LENGTH); } return NULL; } -stun_attr_ref stun_attr_get_next_str(const uint8_t* buf, size_t len, stun_attr_ref prev) { +stun_attr_ref stun_attr_get_next_str(const uint8_t *buf, size_t len, stun_attr_ref prev) { - if(!prev) return stun_attr_get_first_str(buf,len); + if (!prev) + return stun_attr_get_first_str(buf, len); else { - const uint8_t* end = buf + stun_get_command_message_len_str(buf,len); - int attrlen=stun_attr_get_len(prev); + const uint8_t *end = buf + stun_get_command_message_len_str(buf, len); + int attrlen = stun_attr_get_len(prev); uint16_t rem4 = ((uint16_t)attrlen) & 0x0003; - if(rem4) { - attrlen = attrlen+4-(int)rem4; + if (rem4) { + attrlen = attrlen + 4 - (int)rem4; } /* Note the order here: operations on attrlen are untrusted as they may overflow */ - if(attrlen < end - (const uint8_t*)prev - 4) { - const uint8_t* attr_end=(const uint8_t*)prev+4+attrlen; + if (attrlen < end - (const uint8_t *)prev - 4) { + const uint8_t *attr_end = (const uint8_t *)prev + 4 + attrlen; return stun_attr_check_valid(attr_end, end - attr_end); } return NULL; } } -int stun_attr_add_str(uint8_t* buf, size_t *len, uint16_t attr, const uint8_t* avalue, int alen) { - if(alen<0) alen=0; +int stun_attr_add_str(uint8_t *buf, size_t *len, uint16_t attr, const uint8_t *avalue, int alen) { + if (alen < 0) + alen = 0; uint8_t tmp[1]; - if(!avalue) { - alen=0; - avalue=tmp; + if (!avalue) { + alen = 0; + avalue = tmp; } - int clen = stun_get_command_message_len_str(buf,*len); + int clen = stun_get_command_message_len_str(buf, *len); int newlen = clen + 4 + alen; - int newlenrem4=newlen & 0x00000003; + int newlenrem4 = newlen & 0x00000003; int paddinglen = 0; - if(newlenrem4) { - paddinglen=4-newlenrem4; - newlen=newlen+paddinglen; + if (newlenrem4) { + paddinglen = 4 - newlenrem4; + newlen = newlen + paddinglen; } - if(newlen>=MAX_STUN_MESSAGE_SIZE) return -1; + if (newlen >= MAX_STUN_MESSAGE_SIZE) + return -1; else { - uint8_t* attr_start=buf+clen; - - uint16_t *attr_start_16t=(uint16_t*)attr_start; - - stun_set_command_message_len_str(buf,newlen); + uint8_t *attr_start = buf + clen; + + uint16_t *attr_start_16t = (uint16_t *)attr_start; + + stun_set_command_message_len_str(buf, newlen); *len = newlen; - - attr_start_16t[0]=nswap16(attr); - attr_start_16t[1]=nswap16(alen); - if(alen>0) memcpy(attr_start+4,avalue,alen); - - // Write 0 padding to not leak data + + attr_start_16t[0] = nswap16(attr); + attr_start_16t[1] = nswap16(alen); + if (alen > 0) + memcpy(attr_start + 4, avalue, alen); + + // Write 0 padding to not leak data memset(attr_start + 4 + alen, 0, paddinglen); return 0; } } -int stun_attr_add_addr_str(uint8_t *buf, size_t *len, uint16_t attr_type, const ioa_addr* ca) { +int stun_attr_add_addr_str(uint8_t *buf, size_t *len, uint16_t attr_type, const ioa_addr *ca) { stun_tid tid; stun_tid_from_message_str(buf, *len, &tid); - int xor_ed=0; - switch(attr_type) { + int xor_ed = 0; + switch (attr_type) { case STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS: case STUN_ATTRIBUTE_XOR_PEER_ADDRESS: case STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS: - xor_ed=1; + xor_ed = 1; break; - default: - ; + default:; }; ioa_addr public_addr; - map_addr_from_private_to_public(ca,&public_addr); + map_addr_from_private_to_public(ca, &public_addr); uint8_t cfield[64]; - int clen=0; - if(stun_addr_encode(&public_addr, cfield, &clen, xor_ed, STUN_MAGIC_COOKIE, tid.tsx_id)<0) { + int clen = 0; + if (stun_addr_encode(&public_addr, cfield, &clen, xor_ed, STUN_MAGIC_COOKIE, tid.tsx_id) < 0) { return -1; } - if(stun_attr_add_str(buf,len,attr_type,(uint8_t*)(&cfield),clen)<0) return -1; + if (stun_attr_add_str(buf, len, attr_type, (uint8_t *)(&cfield), clen) < 0) + return -1; return 0; } -int stun_attr_get_addr_str(const uint8_t *buf, size_t len, stun_attr_ref attr, ioa_addr* ca, const ioa_addr *default_addr) { +int stun_attr_get_addr_str(const uint8_t *buf, size_t len, stun_attr_ref attr, ioa_addr *ca, + const ioa_addr *default_addr) { stun_tid tid; stun_tid_from_message_str(buf, len, &tid); @@ -1527,140 +1525,140 @@ int stun_attr_get_addr_str(const uint8_t *buf, size_t len, stun_attr_ref attr, i addr_set_any(&public_addr); int attr_type = stun_attr_get_type(attr); - if(attr_type<0) return -1; + if (attr_type < 0) + return -1; - int xor_ed=0; - switch(attr_type) { + int xor_ed = 0; + switch (attr_type) { case STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS: case STUN_ATTRIBUTE_XOR_PEER_ADDRESS: case STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS: - xor_ed=1; + xor_ed = 1; break; - default: - ; + default:; }; - const uint8_t *cfield=stun_attr_get_value(attr); - if(!cfield) return -1; + const uint8_t *cfield = stun_attr_get_value(attr); + if (!cfield) + return -1; - if(stun_addr_decode(&public_addr, cfield, stun_attr_get_len(attr), xor_ed, STUN_MAGIC_COOKIE, tid.tsx_id)<0) { + if (stun_addr_decode(&public_addr, cfield, stun_attr_get_len(attr), xor_ed, STUN_MAGIC_COOKIE, tid.tsx_id) < 0) { return -1; } map_addr_from_public_to_private(&public_addr, ca); - if(default_addr && addr_any_no_port(ca) && !addr_any_no_port(default_addr)) { + if (default_addr && addr_any_no_port(ca) && !addr_any_no_port(default_addr)) { int port = addr_get_port(ca); - addr_cpy(ca,default_addr); - addr_set_port(ca,port); + addr_cpy(ca, default_addr); + addr_set_port(ca, port); } return 0; } -int stun_attr_get_first_addr_str(const uint8_t *buf, size_t len, uint16_t attr_type, ioa_addr* ca, const ioa_addr *default_addr) { +int stun_attr_get_first_addr_str(const uint8_t *buf, size_t len, uint16_t attr_type, ioa_addr *ca, + const ioa_addr *default_addr) { - stun_attr_ref attr=stun_attr_get_first_str(buf,len); + stun_attr_ref attr = stun_attr_get_first_str(buf, len); - while(attr) { - if(stun_attr_is_addr(attr) && (attr_type == stun_attr_get_type(attr))) { - if(stun_attr_get_addr_str(buf,len,attr,ca,default_addr)==0) { - return 0; + while (attr) { + if (stun_attr_is_addr(attr) && (attr_type == stun_attr_get_type(attr))) { + if (stun_attr_get_addr_str(buf, len, attr, ca, default_addr) == 0) { + return 0; } } - attr=stun_attr_get_next_str(buf,len,attr); + attr = stun_attr_get_next_str(buf, len, attr); } return -1; } -int stun_attr_add_channel_number_str(uint8_t* buf, size_t *len, uint16_t chnumber) { +int stun_attr_add_channel_number_str(uint8_t *buf, size_t *len, uint16_t chnumber) { uint16_t field[2]; - field[0]=nswap16(chnumber); - field[1]=0; - - return stun_attr_add_str(buf,len,STUN_ATTRIBUTE_CHANNEL_NUMBER,(uint8_t*)(field),sizeof(field)); + field[0] = nswap16(chnumber); + field[1] = 0; + + return stun_attr_add_str(buf, len, STUN_ATTRIBUTE_CHANNEL_NUMBER, (uint8_t *)(field), sizeof(field)); } -int stun_attr_add_bandwidth_str(uint8_t* buf, size_t *len, band_limit_t bps0) { +int stun_attr_add_bandwidth_str(uint8_t *buf, size_t *len, band_limit_t bps0) { - uint32_t bps = (uint32_t)(band_limit_t)(bps0 >> 7); + uint32_t bps = (uint32_t)(band_limit_t)(bps0 >> 7); - uint32_t field=nswap32(bps); + uint32_t field = nswap32(bps); - return stun_attr_add_str(buf,len,STUN_ATTRIBUTE_NEW_BANDWIDTH,(uint8_t*)(&field),sizeof(field)); + return stun_attr_add_str(buf, len, STUN_ATTRIBUTE_NEW_BANDWIDTH, (uint8_t *)(&field), sizeof(field)); } -int stun_attr_add_address_error_code(uint8_t* buf, size_t *len, int requested_address_family, int error_code) -{ - const uint8_t *reason = get_default_reason(error_code); +int stun_attr_add_address_error_code(uint8_t *buf, size_t *len, int requested_address_family, int error_code) { + const uint8_t *reason = get_default_reason(error_code); - uint8_t avalue[513]; - avalue[0] = (uint8_t)requested_address_family; - avalue[1] = 0; - avalue[2] = (uint8_t) (error_code / 100); - avalue[3] = (uint8_t) (error_code % 100); - strncpy((char*) (avalue + 4), (const char*) reason, sizeof(avalue)-4); - avalue[sizeof(avalue)-1]=0; - int alen = 4 + (int)strlen((const char*) (avalue+4)); + uint8_t avalue[513]; + avalue[0] = (uint8_t)requested_address_family; + avalue[1] = 0; + avalue[2] = (uint8_t)(error_code / 100); + avalue[3] = (uint8_t)(error_code % 100); + strncpy((char *)(avalue + 4), (const char *)reason, sizeof(avalue) - 4); + avalue[sizeof(avalue) - 1] = 0; + int alen = 4 + (int)strlen((const char *)(avalue + 4)); - //"Manual" padding for compatibility with classic old stun: - { - int rem = alen % 4; - if(rem) { - alen +=(4-rem); - } - } + //"Manual" padding for compatibility with classic old stun: + { + int rem = alen % 4; + if (rem) { + alen += (4 - rem); + } + } - stun_attr_add_str(buf, len, STUN_ATTRIBUTE_ADDRESS_ERROR_CODE, (uint8_t*) avalue, alen); + stun_attr_add_str(buf, len, STUN_ATTRIBUTE_ADDRESS_ERROR_CODE, (uint8_t *)avalue, alen); - return 0; + return 0; } -int stun_attr_get_address_error_code(uint8_t* buf, size_t len, int *requested_address_family, int *error_code) -{ - if(requested_address_family) { - *requested_address_family = 0; - } - if(error_code) { - *error_code = 0; - } - if(buf && len) { - stun_attr_ref sar = stun_attr_get_first_by_type_str(buf, len, STUN_ATTRIBUTE_ADDRESS_ERROR_CODE); - if(sar) { - const uint8_t* value = stun_attr_get_value(sar); - if(!value) { - return -1; - } else { - int alen = stun_attr_get_len(sar); - if(alen != 4) { - return -1; - } - if(requested_address_family) { - *requested_address_family = value[0]; - } - if(error_code) { - *error_code = (int)(value[2]*100+value[3]); - } - return 0; - } - } - } - return 0; +int stun_attr_get_address_error_code(uint8_t *buf, size_t len, int *requested_address_family, int *error_code) { + if (requested_address_family) { + *requested_address_family = 0; + } + if (error_code) { + *error_code = 0; + } + if (buf && len) { + stun_attr_ref sar = stun_attr_get_first_by_type_str(buf, len, STUN_ATTRIBUTE_ADDRESS_ERROR_CODE); + if (sar) { + const uint8_t *value = stun_attr_get_value(sar); + if (!value) { + return -1; + } else { + int alen = stun_attr_get_len(sar); + if (alen != 4) { + return -1; + } + if (requested_address_family) { + *requested_address_family = value[0]; + } + if (error_code) { + *error_code = (int)(value[2] * 100 + value[3]); + } + return 0; + } + } + } + return 0; } uint16_t stun_attr_get_first_channel_number_str(const uint8_t *buf, size_t len) { - stun_attr_ref attr=stun_attr_get_first_str(buf,len); - while(attr) { - if(stun_attr_get_type(attr) == STUN_ATTRIBUTE_CHANNEL_NUMBER) { + stun_attr_ref attr = stun_attr_get_first_str(buf, len); + while (attr) { + if (stun_attr_get_type(attr) == STUN_ATTRIBUTE_CHANNEL_NUMBER) { uint16_t ret = stun_attr_get_channel_number(attr); - if(STUN_VALID_CHANNEL(ret)) { - return ret; + if (STUN_VALID_CHANNEL(ret)) { + return ret; } } - attr=stun_attr_get_next_str(buf,len,attr); + attr = stun_attr_get_next_str(buf, len, attr); } return 0; @@ -1668,85 +1666,49 @@ uint16_t stun_attr_get_first_channel_number_str(const uint8_t *buf, size_t len) ////////////// FINGERPRINT //////////////////////////// -int stun_attr_add_fingerprint_str(uint8_t *buf, size_t *len) -{ - uint32_t crc32 = 0; - stun_attr_add_str(buf, len, STUN_ATTRIBUTE_FINGERPRINT, (uint8_t*)&crc32, 4); - crc32 = ns_crc32(buf,(int)*len-8); - *((uint32_t*)(buf+*len-4)) = nswap32(crc32 ^ ((uint32_t)0x5354554e)); - return 0; +int stun_attr_add_fingerprint_str(uint8_t *buf, size_t *len) { + uint32_t crc32 = 0; + stun_attr_add_str(buf, len, STUN_ATTRIBUTE_FINGERPRINT, (uint8_t *)&crc32, 4); + crc32 = ns_crc32(buf, (int)*len - 8); + *((uint32_t *)(buf + *len - 4)) = nswap32(crc32 ^ ((uint32_t)0x5354554e)); + return 0; } ////////////// CRC /////////////////////////////////////////////// -#define CRC_MASK 0xFFFFFFFFUL +#define CRC_MASK 0xFFFFFFFFUL -#define UPDATE_CRC(crc, c) crc = crctable[(uint8_t)crc ^ (uint8_t)(c)] ^ (crc >> 8) +#define UPDATE_CRC(crc, c) crc = crctable[(uint8_t)crc ^ (uint8_t)(c)] ^ (crc >> 8) static const uint32_t crctable[256] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, - 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, - 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, - 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, - 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, - 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, - 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, - 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, - 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, - 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, - 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, - 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, - 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, - 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, - 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, - 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, - 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, - 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, + 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, + 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, + 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, + 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, + 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, + 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, + 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, + 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, + 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, + 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, + 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, }; /* @@ -1757,992 +1719,978 @@ reversed 0x04C11DB7 static void make_crctable(void) { - uint i, j; - uint32_t r; + uint i, j; + uint32_t r; - for (i = 0; i < 256; ++i) { - r = i; - for (j = 8; j > 0; --j) { - if (r & 1) - r = (r >> 1) ^ CRCPOLY; - else - r >>= 1; - } - crctable[i] = r; - } + for (i = 0; i < 256; ++i) { + r = i; + for (j = 8; j > 0; --j) { + if (r & 1) + r = (r >> 1) ^ CRCPOLY; + else + r >>= 1; + } + crctable[i] = r; + } } */ -static uint32_t ns_crc32(const uint8_t *buffer, uint32_t len) -{ - uint32_t crc = CRC_MASK; - while ( len-- ) UPDATE_CRC( crc, *buffer++ ); - return (~crc); +static uint32_t ns_crc32(const uint8_t *buffer, uint32_t len) { + uint32_t crc = CRC_MASK; + while (len--) + UPDATE_CRC(crc, *buffer++); + return (~crc); } //////////// SASLprep RFC 4013 ///////////////////////////////////////// /* We support only basic ASCII table */ -int SASLprep(uint8_t *s) -{ - if(s) { - uint8_t *strin = s; - uint8_t *strout = s; - for(;;) { - uint8_t c = *strin; - if(!c) { - *strout=0; - break; - } +int SASLprep(uint8_t *s) { + if (s) { + uint8_t *strin = s; + uint8_t *strout = s; + for (;;) { + uint8_t c = *strin; + if (!c) { + *strout = 0; + break; + } - switch(c) { - case 0xAD: - ++strin; - break; - case 0xA0: - case 0x20: - *strout=0x20; - ++strout; - ++strin; - break; - case 0x7F: - return -1; - default: - if(c<0x1F) - return -1; - if(c>=0x80 && c<=0x9F) - return -1; - *strout=c; - ++strout; - ++strin; - }; - } - } + switch (c) { + case 0xAD: + ++strin; + break; + case 0xA0: + case 0x20: + *strout = 0x20; + ++strout; + ++strin; + break; + case 0x7F: + return -1; + default: + if (c < 0x1F) + return -1; + if (c >= 0x80 && c <= 0x9F) + return -1; + *strout = c; + ++strout; + ++strin; + }; + } + } - return 0; + return 0; } //////////////// Message Integrity //////////////////////////// -size_t get_hmackey_size(SHATYPE shatype) -{ - if(shatype == SHATYPE_SHA256) - return 32; - if(shatype == SHATYPE_SHA384) - return 48; - if(shatype == SHATYPE_SHA512) - return 64; - return 16; +size_t get_hmackey_size(SHATYPE shatype) { + if (shatype == SHATYPE_SHA256) + return 32; + if (shatype == SHATYPE_SHA384) + return 48; + if (shatype == SHATYPE_SHA512) + return 64; + return 16; } -void print_bin_func(const char *name, size_t len, const void *s, const char *func) -{ - printf("<%s>:<%s>:len=%d:[",func,name,(int)len); - size_t i; - for(i=0;i:<%s>:len=%d:[", func, name, (int)len); + size_t i; + for (i = 0; i < len; i++) { + printf("%02x", (int)((const uint8_t *)s)[i]); + } + printf("]\n"); } -int stun_attr_add_integrity_str(turn_credential_type ct, uint8_t *buf, size_t *len, hmackey_t key, password_t pwd, SHATYPE shatype) -{ - uint8_t hmac[MAXSHASIZE]; +int stun_attr_add_integrity_str(turn_credential_type ct, uint8_t *buf, size_t *len, hmackey_t key, password_t pwd, + SHATYPE shatype) { + uint8_t hmac[MAXSHASIZE]; - unsigned int shasize; + unsigned int shasize; - switch(shatype) { - case SHATYPE_SHA256: - shasize = SHA256SIZEBYTES; - break; - case SHATYPE_SHA384: - shasize = SHA384SIZEBYTES; - break; - case SHATYPE_SHA512: - shasize = SHA512SIZEBYTES; - break; - default: - shasize = SHA1SIZEBYTES; - }; + switch (shatype) { + case SHATYPE_SHA256: + shasize = SHA256SIZEBYTES; + break; + case SHATYPE_SHA384: + shasize = SHA384SIZEBYTES; + break; + case SHATYPE_SHA512: + shasize = SHA512SIZEBYTES; + break; + default: + shasize = SHA1SIZEBYTES; + }; - if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, hmac, shasize)<0) - return -1; + if (stun_attr_add_str(buf, len, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, hmac, shasize) < 0) + return -1; - if(ct == TURN_CREDENTIALS_SHORT_TERM) { - if(stun_calculate_hmac(buf, *len-4-shasize, pwd, strlen((char*)pwd), buf+*len-shasize, &shasize, shatype)<0) - return -1; - } else { - if(stun_calculate_hmac(buf, *len-4-shasize, key, get_hmackey_size(shatype), buf+*len-shasize, &shasize, shatype)<0) - return -1; - } + if (ct == TURN_CREDENTIALS_SHORT_TERM) { + if (stun_calculate_hmac(buf, *len - 4 - shasize, pwd, strlen((char *)pwd), buf + *len - shasize, &shasize, + shatype) < 0) + return -1; + } else { + if (stun_calculate_hmac(buf, *len - 4 - shasize, key, get_hmackey_size(shatype), buf + *len - shasize, &shasize, + shatype) < 0) + return -1; + } - return 0; + return 0; } -int stun_attr_add_integrity_by_key_str(uint8_t *buf, size_t *len, const uint8_t *uname, const uint8_t *realm, hmackey_t key, const uint8_t *nonce, SHATYPE shatype) -{ - if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_USERNAME, uname, (int)strlen((const char*)uname))<0) - return -1; +int stun_attr_add_integrity_by_key_str(uint8_t *buf, size_t *len, const uint8_t *uname, const uint8_t *realm, + hmackey_t key, const uint8_t *nonce, SHATYPE shatype) { + if (stun_attr_add_str(buf, len, STUN_ATTRIBUTE_USERNAME, uname, (int)strlen((const char *)uname)) < 0) + return -1; - if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_NONCE, nonce, (int)strlen((const char*)nonce))<0) - return -1; + if (stun_attr_add_str(buf, len, STUN_ATTRIBUTE_NONCE, nonce, (int)strlen((const char *)nonce)) < 0) + return -1; - if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_REALM, realm, (int)strlen((const char*)realm))<0) - return -1; + if (stun_attr_add_str(buf, len, STUN_ATTRIBUTE_REALM, realm, (int)strlen((const char *)realm)) < 0) + return -1; - password_t p; - return stun_attr_add_integrity_str(TURN_CREDENTIALS_LONG_TERM, buf, len, key, p, shatype); + password_t p; + return stun_attr_add_integrity_str(TURN_CREDENTIALS_LONG_TERM, buf, len, key, p, shatype); } -int stun_attr_add_integrity_by_user_str(uint8_t *buf, size_t *len, const uint8_t *uname, const uint8_t *realm, const uint8_t *upwd, const uint8_t *nonce, SHATYPE shatype) -{ - hmackey_t key; +int stun_attr_add_integrity_by_user_str(uint8_t *buf, size_t *len, const uint8_t *uname, const uint8_t *realm, + const uint8_t *upwd, const uint8_t *nonce, SHATYPE shatype) { + hmackey_t key; - if(stun_produce_integrity_key_str(uname, realm, upwd, key, shatype)<0) - return -1; + if (stun_produce_integrity_key_str(uname, realm, upwd, key, shatype) < 0) + return -1; - return stun_attr_add_integrity_by_key_str(buf, len, uname, realm, key, nonce, shatype); + return stun_attr_add_integrity_by_key_str(buf, len, uname, realm, key, nonce, shatype); } -int stun_attr_add_integrity_by_user_short_term_str(uint8_t *buf, size_t *len, const uint8_t *uname, password_t pwd, SHATYPE shatype) -{ - if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_USERNAME, uname, (int)strlen((const char*)uname))<0) - return -1; +int stun_attr_add_integrity_by_user_short_term_str(uint8_t *buf, size_t *len, const uint8_t *uname, password_t pwd, + SHATYPE shatype) { + if (stun_attr_add_str(buf, len, STUN_ATTRIBUTE_USERNAME, uname, (int)strlen((const char *)uname)) < 0) + return -1; - hmackey_t key; - return stun_attr_add_integrity_str(TURN_CREDENTIALS_SHORT_TERM, buf, len, key, pwd, shatype); + hmackey_t key; + return stun_attr_add_integrity_str(TURN_CREDENTIALS_SHORT_TERM, buf, len, key, pwd, shatype); } -void print_hmac(const char *name, const void *s, size_t len) -{ - printf("%s:len=%d:[",name,(int)len); - size_t i; - for(i=0;i orig_len) - return -1; + int new_len = (int)((const uint8_t *)sar - buf) + 4 + shasize; + if (new_len > orig_len) + return -1; - if (stun_set_command_message_len_str(buf, new_len) < 0) - return -1; + if (stun_set_command_message_len_str(buf, new_len) < 0) + return -1; - if(ct == TURN_CREDENTIALS_SHORT_TERM) { - res = stun_calculate_hmac(buf, (size_t) new_len - 4 - shasize, pwd, strlen((char*)pwd), new_hmac, &shasize, shatype); - } else { - res = stun_calculate_hmac(buf, (size_t) new_len - 4 - shasize, key, get_hmackey_size(shatype), new_hmac, &shasize, shatype); - } + if (ct == TURN_CREDENTIALS_SHORT_TERM) { + res = + stun_calculate_hmac(buf, (size_t)new_len - 4 - shasize, pwd, strlen((char *)pwd), new_hmac, &shasize, shatype); + } else { + res = stun_calculate_hmac(buf, (size_t)new_len - 4 - shasize, key, get_hmackey_size(shatype), new_hmac, &shasize, + shatype); + } - stun_set_command_message_len_str(buf, orig_len); - if(res<0) - return -1; + stun_set_command_message_len_str(buf, orig_len); + if (res < 0) + return -1; - old_hmac = stun_attr_get_value(sar); - if(!old_hmac) - return -1; + old_hmac = stun_attr_get_value(sar); + if (!old_hmac) + return -1; - if(memcmp(old_hmac,new_hmac,shasize)) - return 0; + if (memcmp(old_hmac, new_hmac, shasize)) + return 0; - return +1; + return +1; } /* * Return -1 if failure, 0 if the integrity is not correct, 1 if OK */ -int stun_check_message_integrity_str(turn_credential_type ct, uint8_t *buf, size_t len, const uint8_t *uname, const uint8_t *realm, const uint8_t *upwd, SHATYPE shatype) -{ - hmackey_t key; - password_t pwd; +int stun_check_message_integrity_str(turn_credential_type ct, uint8_t *buf, size_t len, const uint8_t *uname, + const uint8_t *realm, const uint8_t *upwd, SHATYPE shatype) { + hmackey_t key; + password_t pwd; - if(ct == TURN_CREDENTIALS_SHORT_TERM) - strncpy((char*)pwd,(const char*)upwd,sizeof(password_t)); - else if (stun_produce_integrity_key_str(uname, realm, upwd, key, shatype) < 0) - return -1; + if (ct == TURN_CREDENTIALS_SHORT_TERM) + strncpy((char *)pwd, (const char *)upwd, sizeof(password_t)); + else if (stun_produce_integrity_key_str(uname, realm, upwd, key, shatype) < 0) + return -1; - return stun_check_message_integrity_by_key_str(ct, buf, len, key, pwd, shatype); + return stun_check_message_integrity_by_key_str(ct, buf, len, key, pwd, shatype); } /* RFC 5780 */ -int stun_attr_get_change_request_str(stun_attr_ref attr, int *change_ip, int *change_port) -{ - if(stun_attr_get_len(attr) == 4) { - const uint8_t* value = stun_attr_get_value(attr); - if(value) { - *change_ip = (value[3] & (uint8_t)0x04); - *change_port = (value[3] & (uint8_t)0x02); - return 0; - } - } - return -1; +int stun_attr_get_change_request_str(stun_attr_ref attr, int *change_ip, int *change_port) { + if (stun_attr_get_len(attr) == 4) { + const uint8_t *value = stun_attr_get_value(attr); + if (value) { + *change_ip = (value[3] & (uint8_t)0x04); + *change_port = (value[3] & (uint8_t)0x02); + return 0; + } + } + return -1; } -int stun_attr_add_change_request_str(uint8_t *buf, size_t *len, int change_ip, int change_port) -{ - uint8_t avalue[4]={0,0,0,0}; +int stun_attr_add_change_request_str(uint8_t *buf, size_t *len, int change_ip, int change_port) { + uint8_t avalue[4] = {0, 0, 0, 0}; - if(change_ip) { - if(change_port) { - avalue[3] = 0x06; - } else { - avalue[3] = 0x04; - } - } else if(change_port) { - avalue[3]=0x02; - } + if (change_ip) { + if (change_port) { + avalue[3] = 0x06; + } else { + avalue[3] = 0x04; + } + } else if (change_port) { + avalue[3] = 0x02; + } - return stun_attr_add_str(buf, len, STUN_ATTRIBUTE_CHANGE_REQUEST, avalue, 4); + return stun_attr_add_str(buf, len, STUN_ATTRIBUTE_CHANGE_REQUEST, avalue, 4); } -int stun_attr_get_response_port_str(stun_attr_ref attr) -{ - if(stun_attr_get_len(attr) >= 2) { - const uint8_t* value = stun_attr_get_value(attr); - if(value) { - return nswap16(((const uint16_t*)value)[0]); - } - } - return -1; +int stun_attr_get_response_port_str(stun_attr_ref attr) { + if (stun_attr_get_len(attr) >= 2) { + const uint8_t *value = stun_attr_get_value(attr); + if (value) { + return nswap16(((const uint16_t *)value)[0]); + } + } + return -1; } -int stun_attr_add_response_port_str(uint8_t *buf, size_t *len, uint16_t port) -{ - uint8_t avalue[4]={0,0,0,0}; - uint16_t *port_ptr = (uint16_t*)avalue; +int stun_attr_add_response_port_str(uint8_t *buf, size_t *len, uint16_t port) { + uint8_t avalue[4] = {0, 0, 0, 0}; + uint16_t *port_ptr = (uint16_t *)avalue; - *port_ptr = nswap16(port); + *port_ptr = nswap16(port); - return stun_attr_add_str(buf, len, STUN_ATTRIBUTE_RESPONSE_PORT, avalue, 4); + return stun_attr_add_str(buf, len, STUN_ATTRIBUTE_RESPONSE_PORT, avalue, 4); } int stun_attr_get_padding_len_str(stun_attr_ref attr) { - int len = stun_attr_get_len(attr); - if(len<0) - return -1; - return (uint16_t)len; + int len = stun_attr_get_len(attr); + if (len < 0) + return -1; + return (uint16_t)len; } -int stun_attr_add_padding_str(uint8_t *buf, size_t *len, uint16_t padding_len) -{ - uint8_t avalue[0xFFFF]; - memset(avalue, 0, padding_len); +int stun_attr_add_padding_str(uint8_t *buf, size_t *len, uint16_t padding_len) { + uint8_t avalue[0xFFFF]; + memset(avalue, 0, padding_len); - return stun_attr_add_str(buf, len, STUN_ATTRIBUTE_PADDING, avalue, padding_len); + return stun_attr_add_str(buf, len, STUN_ATTRIBUTE_PADDING, avalue, padding_len); } /* OAUTH */ -#define OAUTH_ERROR(...) fprintf(stderr,__VA_ARGS__) +#define OAUTH_ERROR(...) fprintf(stderr, __VA_ARGS__) -static void remove_spaces(char *s) -{ - char *sfns = s; - while(*sfns) { - if(*sfns != ' ') - break; - ++sfns; - } - if(*sfns) { - if(sfns != s) { - while(*sfns && (*sfns != ' ')) { - *s = *sfns; - ++s; - ++sfns; - }; - *s = 0; - } else { - while(*s) { - if(*s == ' ') { - *s = 0; - break; - } - ++s; - } - } - } +static void remove_spaces(char *s) { + char *sfns = s; + while (*sfns) { + if (*sfns != ' ') + break; + ++sfns; + } + if (*sfns) { + if (sfns != s) { + while (*sfns && (*sfns != ' ')) { + *s = *sfns; + ++s; + ++sfns; + }; + *s = 0; + } else { + while (*s) { + if (*s == ' ') { + *s = 0; + break; + } + ++s; + } + } + } } -static void normalize_algorithm(char *s) -{ - char c = *s; - while(c) { - if(c=='_') *s='-'; - else if((c>='a')&&(c<='z')) { - *s = c - 'a' + 'A'; - } - ++s; - c = *s; - } +static void normalize_algorithm(char *s) { + char c = *s; + while (c) { + if (c == '_') + *s = '-'; + else if ((c >= 'a') && (c <= 'z')) { + *s = c - 'a' + 'A'; + } + ++s; + c = *s; + } } size_t calculate_enc_key_length(ENC_ALG a); -size_t calculate_enc_key_length(ENC_ALG a) -{ - switch(a) { +size_t calculate_enc_key_length(ENC_ALG a) { + switch (a) { #if !defined(TURN_NO_GCM) - case A128GCM: - return 16; + case A128GCM: + return 16; #endif - default: - break; - }; + default: + break; + }; - return 32; + return 32; } size_t calculate_auth_key_length(ENC_ALG a); -size_t calculate_auth_key_length(ENC_ALG a) -{ - switch(a) { +size_t calculate_auth_key_length(ENC_ALG a) { + switch (a) { #if !defined(TURN_NO_GCM) - case A256GCM: - case A128GCM: - return 0; + case A256GCM: + case A128GCM: + return 0; #endif - default: - break; - }; + default: + break; + }; - return 0; + return 0; } -int calculate_key(char *key, size_t key_size, - char *new_key, size_t new_key_size); -int calculate_key(char *key, size_t key_size, - char *new_key, size_t new_key_size) -{ - UNUSED_ARG(key_size); +int calculate_key(char *key, size_t key_size, char *new_key, size_t new_key_size); +int calculate_key(char *key, size_t key_size, char *new_key, size_t new_key_size) { + UNUSED_ARG(key_size); - memcpy(new_key,key,new_key_size); + memcpy(new_key, key, new_key_size); - return 0; + return 0; } -int convert_oauth_key_data(const oauth_key_data *oakd0, oauth_key *key, char *err_msg, size_t err_msg_size) -{ - if(oakd0 && key) { +int convert_oauth_key_data(const oauth_key_data *oakd0, oauth_key *key, char *err_msg, size_t err_msg_size) { + if (oakd0 && key) { - oauth_key_data oakd_obj; - memcpy(&oakd_obj,oakd0,sizeof(oauth_key_data)); - oauth_key_data *oakd = &oakd_obj; + oauth_key_data oakd_obj; + memcpy(&oakd_obj, oakd0, sizeof(oauth_key_data)); + oauth_key_data *oakd = &oakd_obj; - if(!(oakd->ikm_key_size)) { - if(err_msg) { - snprintf(err_msg,err_msg_size,"key is not defined"); - } - } + if (!(oakd->ikm_key_size)) { + if (err_msg) { + snprintf(err_msg, err_msg_size, "key is not defined"); + } + } - remove_spaces(oakd->kid); + remove_spaces(oakd->kid); - remove_spaces(oakd->as_rs_alg); + remove_spaces(oakd->as_rs_alg); - normalize_algorithm(oakd->as_rs_alg); + normalize_algorithm(oakd->as_rs_alg); - if(!(oakd->kid[0])) { - if(err_msg) { - snprintf(err_msg,err_msg_size,"KID is not defined"); - } - OAUTH_ERROR("KID is not defined\n"); - return -1; - } + if (!(oakd->kid[0])) { + if (err_msg) { + snprintf(err_msg, err_msg_size, "KID is not defined"); + } + OAUTH_ERROR("KID is not defined\n"); + return -1; + } - memset(key, 0, sizeof(oauth_key)); + memset(key, 0, sizeof(oauth_key)); - STRCPY(key->kid,oakd->kid); + STRCPY(key->kid, oakd->kid); - memcpy(key->ikm_key,oakd->ikm_key,sizeof(key->ikm_key)); - key->ikm_key_size = oakd->ikm_key_size; + memcpy(key->ikm_key, oakd->ikm_key, sizeof(key->ikm_key)); + key->ikm_key_size = oakd->ikm_key_size; - key->timestamp = oakd->timestamp; - key->lifetime = oakd->lifetime; + key->timestamp = oakd->timestamp; + key->lifetime = oakd->lifetime; - if(!(key->timestamp)) key->timestamp = OAUTH_DEFAULT_TIMESTAMP; - if(!(key->lifetime)) key->lifetime = OAUTH_DEFAULT_LIFETIME; + if (!(key->timestamp)) + key->timestamp = OAUTH_DEFAULT_TIMESTAMP; + if (!(key->lifetime)) + key->lifetime = OAUTH_DEFAULT_LIFETIME; - key->as_rs_alg = ENC_ALG_ERROR; + key->as_rs_alg = ENC_ALG_ERROR; #if !defined(TURN_NO_GCM) - key->as_rs_alg = ENC_ALG_DEFAULT; - if(!strcmp(oakd->as_rs_alg,"A128GCM")) { - key->as_rs_alg = A128GCM; - key->auth_key_size = 0; - key->auth_key[0] = 0; - } else if(!strcmp(oakd->as_rs_alg,"A256GCM")) { - key->as_rs_alg = A256GCM; - key->auth_key_size = 0; - key->auth_key[0] = 0; - } else + key->as_rs_alg = ENC_ALG_DEFAULT; + if (!strcmp(oakd->as_rs_alg, "A128GCM")) { + key->as_rs_alg = A128GCM; + key->auth_key_size = 0; + key->auth_key[0] = 0; + } else if (!strcmp(oakd->as_rs_alg, "A256GCM")) { + key->as_rs_alg = A256GCM; + key->auth_key_size = 0; + key->auth_key[0] = 0; + } else #endif - { - if(err_msg) { - snprintf(err_msg,err_msg_size,"Wrong oAuth token encryption algorithm: %s (2)\n",oakd->as_rs_alg); - } - OAUTH_ERROR("Wrong oAuth token encryption algorithm: %s (3)\n",oakd->as_rs_alg); - return -1; - } + { + if (err_msg) { + snprintf(err_msg, err_msg_size, "Wrong oAuth token encryption algorithm: %s (2)\n", oakd->as_rs_alg); + } + OAUTH_ERROR("Wrong oAuth token encryption algorithm: %s (3)\n", oakd->as_rs_alg); + return -1; + } #if !defined(TURN_NO_GCM) - key->auth_key_size = calculate_auth_key_length(key->as_rs_alg); - if(key->auth_key_size) { - if(calculate_key(key->ikm_key,key->ikm_key_size,key->auth_key,key->auth_key_size)<0) { - return -1; - } - } + key->auth_key_size = calculate_auth_key_length(key->as_rs_alg); + if (key->auth_key_size) { + if (calculate_key(key->ikm_key, key->ikm_key_size, key->auth_key, key->auth_key_size) < 0) { + return -1; + } + } - key->as_rs_key_size = calculate_enc_key_length(key->as_rs_alg); - if(calculate_key(key->ikm_key,key->ikm_key_size,key->as_rs_key,key->as_rs_key_size)<0) { - return -1; - } + key->as_rs_key_size = calculate_enc_key_length(key->as_rs_alg); + if (calculate_key(key->ikm_key, key->ikm_key_size, key->as_rs_key, key->as_rs_key_size) < 0) { + return -1; + } #endif - } + } - return 0; + return 0; } const EVP_CIPHER *get_cipher_type(ENC_ALG enc_alg); -const EVP_CIPHER *get_cipher_type(ENC_ALG enc_alg) -{ - switch(enc_alg) { +const EVP_CIPHER *get_cipher_type(ENC_ALG enc_alg) { + switch (enc_alg) { #if !defined(TURN_NO_GCM) - case A128GCM: - return EVP_aes_128_gcm(); - case A256GCM: - return EVP_aes_256_gcm(); + case A128GCM: + return EVP_aes_128_gcm(); + case A256GCM: + return EVP_aes_256_gcm(); #endif - default: - break; - } - OAUTH_ERROR("%s: Unsupported enc algorithm: %d\n",__FUNCTION__,(int)enc_alg); - return NULL; + default: + break; + } + OAUTH_ERROR("%s: Unsupported enc algorithm: %d\n", __FUNCTION__, (int)enc_alg); + return NULL; } -int my_EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, - int *outl, const unsigned char *in, int inl); -int my_EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, - int *outl, const unsigned char *in, int inl) -{ - int cycle = 0; - int out_len = 0; - while((out_len>\n",name); - size_t i; - for(i = 0;i",(unsigned int)f[i]); - } - printf("\n<<==field %s\n",name); +void print_field(const char *name, const unsigned char *f, size_t len); +void print_field(const char *name, const unsigned char *f, size_t len) { + printf("\nfield %s==>>\n", name); + size_t i; + for (i = 0; i < len; ++i) { + printf("<0x%x>", (unsigned int)f[i]); + } + printf("\n<<==field %s\n", name); } -int encode_oauth_token_normal(const uint8_t *server_name, encoded_oauth_token *etoken, const oauth_key *key, const oauth_token *dtoken); -int encode_oauth_token_normal(const uint8_t *server_name, encoded_oauth_token *etoken, const oauth_key *key, const oauth_token *dtoken) -{ - UNUSED_ARG(server_name); - UNUSED_ARG(etoken); - UNUSED_ARG(key); - UNUSED_ARG(dtoken); +int encode_oauth_token_normal(const uint8_t *server_name, encoded_oauth_token *etoken, const oauth_key *key, + const oauth_token *dtoken); +int encode_oauth_token_normal(const uint8_t *server_name, encoded_oauth_token *etoken, const oauth_key *key, + const oauth_token *dtoken) { + UNUSED_ARG(server_name); + UNUSED_ARG(etoken); + UNUSED_ARG(key); + UNUSED_ARG(dtoken); - /* - if(server_name && etoken && key && dtoken && (dtoken->enc_block.key_length<=128)) { + /* + if(server_name && etoken && key && dtoken && (dtoken->enc_block.key_length<=128)) { - unsigned char orig_field[MAX_ENCODED_OAUTH_TOKEN_SIZE]; - memset(orig_field, 0, sizeof(orig_field)); + unsigned char orig_field[MAX_ENCODED_OAUTH_TOKEN_SIZE]; + memset(orig_field, 0, sizeof(orig_field)); - size_t len = 0; - *((uint16_t*)(orig_field+len)) = nswap16(dtoken->enc_block.key_length); - len +=2; + size_t len = 0; + *((uint16_t*)(orig_field+len)) = nswap16(dtoken->enc_block.key_length); + len +=2; - memcpy(orig_field+len,dtoken->enc_block.mac_key,dtoken->enc_block.key_length); - len += dtoken->enc_block.key_length; + memcpy(orig_field+len,dtoken->enc_block.mac_key,dtoken->enc_block.key_length); + len += dtoken->enc_block.key_length; - *((uint64_t*)(orig_field+len)) = nswap64(dtoken->enc_block.timestamp); - len += 8; + *((uint64_t*)(orig_field+len)) = nswap64(dtoken->enc_block.timestamp); + len += 8; - *((uint32_t*)(orig_field+len)) = nswap32(dtoken->enc_block.lifetime); - len += 4; + *((uint32_t*)(orig_field+len)) = nswap32(dtoken->enc_block.lifetime); + len += 4; - const EVP_CIPHER * cipher = get_cipher_type(key->as_rs_alg); - if(!cipher) - return -1; + const EVP_CIPHER * cipher = get_cipher_type(key->as_rs_alg); + if(!cipher) + return -1; - unsigned char *encoded_field = (unsigned char*)etoken->token; + unsigned char *encoded_field = (unsigned char*)etoken->token; - EVP_CIPHER_CTX ctx; - EVP_CIPHER_CTX_init(&ctx); - EVP_EncryptInit_ex(&ctx, cipher, NULL, (const unsigned char *)key->as_rs_key, NULL); - EVP_CIPHER_CTX_set_padding(&ctx,1); - int outl=0; - my_EVP_EncryptUpdate(&ctx, encoded_field, &outl, orig_field, (int)len); - if(outl % OAUTH_ENC_ALG_BLOCK_SIZE) { - int tmp_outl = 0; - EVP_EncryptFinal_ex(&ctx, encoded_field + outl, &tmp_outl); - outl += tmp_outl; - } + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + EVP_EncryptInit_ex(&ctx, cipher, NULL, (const unsigned char *)key->as_rs_key, NULL); + EVP_CIPHER_CTX_set_padding(&ctx,1); + int outl=0; + my_EVP_EncryptUpdate(&ctx, encoded_field, &outl, orig_field, (int)len); + if(outl % OAUTH_ENC_ALG_BLOCK_SIZE) { + int tmp_outl = 0; + EVP_EncryptFinal_ex(&ctx, encoded_field + outl, &tmp_outl); + outl += tmp_outl; + } - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_cleanup(&ctx); - size_t sn_len = strlen((const char*)server_name); - memcpy(encoded_field+outl,server_name,sn_len); - outl += sn_len; + size_t sn_len = strlen((const char*)server_name); + memcpy(encoded_field+outl,server_name,sn_len); + outl += sn_len; - const EVP_MD *md = get_auth_type(key->auth_alg); - if(!md) - return -1; + const EVP_MD *md = get_auth_type(key->auth_alg); + if(!md) + return -1; - unsigned int hmac_len = EVP_MD_size(md); - if (!HMAC(md, key->auth_key, key->auth_key_size, encoded_field, outl, encoded_field + outl, &hmac_len)) { - return -1; - } + unsigned int hmac_len = EVP_MD_size(md); + if (!HMAC(md, key->auth_key, key->auth_key_size, encoded_field, outl, encoded_field + outl, &hmac_len)) { + return -1; + } - update_hmac_len(key->auth_alg, &hmac_len); + update_hmac_len(key->auth_alg, &hmac_len); - memcpy(encoded_field + outl - sn_len, encoded_field + outl, hmac_len); - outl -= sn_len; - outl += hmac_len; //encoded+hmac + memcpy(encoded_field + outl - sn_len, encoded_field + outl, hmac_len); + outl -= sn_len; + outl += hmac_len; //encoded+hmac - etoken->size = outl; + etoken->size = outl; - return 0; - } - */ - return -1; + return 0; + } + */ + return -1; } -int decode_oauth_token_normal(const uint8_t *server_name, const encoded_oauth_token *etoken, const oauth_key *key, oauth_token *dtoken); -int decode_oauth_token_normal(const uint8_t *server_name, const encoded_oauth_token *etoken, const oauth_key *key, oauth_token *dtoken) -{ - UNUSED_ARG(server_name); - UNUSED_ARG(etoken); - UNUSED_ARG(key); - UNUSED_ARG(dtoken); +int decode_oauth_token_normal(const uint8_t *server_name, const encoded_oauth_token *etoken, const oauth_key *key, + oauth_token *dtoken); +int decode_oauth_token_normal(const uint8_t *server_name, const encoded_oauth_token *etoken, const oauth_key *key, + oauth_token *dtoken) { + UNUSED_ARG(server_name); + UNUSED_ARG(etoken); + UNUSED_ARG(key); + UNUSED_ARG(dtoken); - /* - if(server_name && etoken && key && dtoken) { + /* + if(server_name && etoken && key && dtoken) { - size_t mac_size = calculate_auth_output_length(key->auth_alg); - size_t min_encoded_field_size = 2+4+8+1; - if(etoken->size < mac_size+min_encoded_field_size) { - OAUTH_ERROR("%s: token size too small: %d, mac_size=%d, min_encoded_field_size=%d\n",__FUNCTION__,(int)etoken->size,(int)mac_size,(int)min_encoded_field_size); - return -1; - } + size_t mac_size = calculate_auth_output_length(key->auth_alg); + size_t min_encoded_field_size = 2+4+8+1; + if(etoken->size < mac_size+min_encoded_field_size) { + OAUTH_ERROR("%s: token size too small: %d, mac_size=%d, + min_encoded_field_size=%d\n",__FUNCTION__,(int)etoken->size,(int)mac_size,(int)min_encoded_field_size); return -1; + } - const unsigned char* encoded_field = (const unsigned char*)etoken->token; - unsigned int encoded_field_size = (unsigned int)etoken->size-mac_size; - const unsigned char* mac = ((const unsigned char*)etoken->token) + etoken->size - mac_size; + const unsigned char* encoded_field = (const unsigned char*)etoken->token; + unsigned int encoded_field_size = (unsigned int)etoken->size-mac_size; + const unsigned char* mac = ((const unsigned char*)etoken->token) + etoken->size - mac_size; - { - const EVP_MD *md = get_auth_type(key->auth_alg); - if(!md) - return -1; - unsigned int hmac_len = EVP_MD_size(md); - update_hmac_len(key->auth_alg,&hmac_len); - if(hmac_len != mac_size) { - OAUTH_ERROR("%s: mac size is wrong: %d, must be %d\n",__FUNCTION__,(int)mac_size,(int)hmac_len); - return -1; - } - unsigned char efield[MAX_ENCODED_OAUTH_TOKEN_SIZE]; - unsigned char check_mac[MAXSHASIZE]; - memcpy(efield,encoded_field,encoded_field_size); - size_t sn_len = strlen((const char*)server_name); - memcpy(efield+encoded_field_size,server_name,sn_len); - if (!HMAC(md, key->auth_key, key->auth_key_size, efield, encoded_field_size+sn_len, check_mac, &hmac_len)) { - return -1; - } + { + const EVP_MD *md = get_auth_type(key->auth_alg); + if(!md) + return -1; + unsigned int hmac_len = EVP_MD_size(md); + update_hmac_len(key->auth_alg,&hmac_len); + if(hmac_len != mac_size) { + OAUTH_ERROR("%s: mac size is wrong: %d, must be %d\n",__FUNCTION__,(int)mac_size,(int)hmac_len); + return -1; + } + unsigned char efield[MAX_ENCODED_OAUTH_TOKEN_SIZE]; + unsigned char check_mac[MAXSHASIZE]; + memcpy(efield,encoded_field,encoded_field_size); + size_t sn_len = strlen((const char*)server_name); + memcpy(efield+encoded_field_size,server_name,sn_len); + if (!HMAC(md, key->auth_key, key->auth_key_size, efield, encoded_field_size+sn_len, check_mac, &hmac_len)) + { return -1; + } - if(memcmp(check_mac,mac,mac_size)) { - OAUTH_ERROR("%s: token integrity check failed\n",__FUNCTION__); - return -1; - } - } + if(memcmp(check_mac,mac,mac_size)) { + OAUTH_ERROR("%s: token integrity check failed\n",__FUNCTION__); + return -1; + } + } - unsigned char decoded_field[MAX_ENCODED_OAUTH_TOKEN_SIZE]; + unsigned char decoded_field[MAX_ENCODED_OAUTH_TOKEN_SIZE]; - const EVP_CIPHER * cipher = get_cipher_type(key->as_rs_alg); - if(!cipher) - return -1; + const EVP_CIPHER * cipher = get_cipher_type(key->as_rs_alg); + if(!cipher) + return -1; - EVP_CIPHER_CTX ctx; - EVP_CIPHER_CTX_init(&ctx); - EVP_DecryptInit_ex(&ctx, cipher, NULL, (const unsigned char *)key->as_rs_key, NULL); - EVP_CIPHER_CTX_set_padding(&ctx,1); - int outl=0; - my_EVP_DecryptUpdate(&ctx, decoded_field, &outl, encoded_field, (int)encoded_field_size); + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + EVP_DecryptInit_ex(&ctx, cipher, NULL, (const unsigned char *)key->as_rs_key, NULL); + EVP_CIPHER_CTX_set_padding(&ctx,1); + int outl=0; + my_EVP_DecryptUpdate(&ctx, decoded_field, &outl, encoded_field, (int)encoded_field_size); - int tmp_outl = 0; - EVP_DecryptFinal_ex(&ctx, decoded_field + outl, &tmp_outl); - outl += tmp_outl; + int tmp_outl = 0; + EVP_DecryptFinal_ex(&ctx, decoded_field + outl, &tmp_outl); + outl += tmp_outl; - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_cleanup(&ctx); - size_t len = 0; + size_t len = 0; - dtoken->enc_block.key_length = nswap16(*((uint16_t*)(decoded_field+len))); - len += 2; + dtoken->enc_block.key_length = nswap16(*((uint16_t*)(decoded_field+len))); + len += 2; - memcpy(dtoken->enc_block.mac_key,decoded_field+len,dtoken->enc_block.key_length); - len += dtoken->enc_block.key_length; + memcpy(dtoken->enc_block.mac_key,decoded_field+len,dtoken->enc_block.key_length); + len += dtoken->enc_block.key_length; - dtoken->enc_block.timestamp = nswap64(*((uint64_t*)(decoded_field+len))); - len += 8; + dtoken->enc_block.timestamp = nswap64(*((uint64_t*)(decoded_field+len))); + len += 8; - dtoken->enc_block.lifetime = nswap32(*((uint32_t*)(decoded_field+len))); - len += 4; + dtoken->enc_block.lifetime = nswap32(*((uint32_t*)(decoded_field+len))); + len += 4; - return 0; - } - */ - return -1; + return 0; + } + */ + return -1; } static void generate_random_nonce(unsigned char *nonce, size_t sz) { - if(!RAND_bytes(nonce, (int)sz)) { - size_t i; - for(i=0;ienc_block.key_length<=MAXSHASIZE)) { +static int encode_oauth_token_gcm(const uint8_t *server_name, encoded_oauth_token *etoken, const oauth_key *key, + const oauth_token *dtoken, const uint8_t *nonce0) { + if (server_name && etoken && key && dtoken && (dtoken->enc_block.key_length <= MAXSHASIZE)) { - unsigned char orig_field[MAX_ENCODED_OAUTH_TOKEN_SIZE]; - memset(orig_field, 0, sizeof(orig_field)); + unsigned char orig_field[MAX_ENCODED_OAUTH_TOKEN_SIZE]; + memset(orig_field, 0, sizeof(orig_field)); - unsigned char nonce[OAUTH_GCM_NONCE_SIZE]; - if(nonce0) { - memcpy(nonce,nonce0,sizeof(nonce)); - } else { - generate_random_nonce(nonce, sizeof(nonce)); - } + unsigned char nonce[OAUTH_GCM_NONCE_SIZE]; + if (nonce0) { + memcpy(nonce, nonce0, sizeof(nonce)); + } else { + generate_random_nonce(nonce, sizeof(nonce)); + } - size_t len = 0; + size_t len = 0; - *((uint16_t*)(orig_field+len)) = nswap16(OAUTH_GCM_NONCE_SIZE); - len +=2; + *((uint16_t *)(orig_field + len)) = nswap16(OAUTH_GCM_NONCE_SIZE); + len += 2; - memcpy(orig_field+len,nonce,OAUTH_GCM_NONCE_SIZE); - len += OAUTH_GCM_NONCE_SIZE; + memcpy(orig_field + len, nonce, OAUTH_GCM_NONCE_SIZE); + len += OAUTH_GCM_NONCE_SIZE; - *((uint16_t*)(orig_field+len)) = nswap16(dtoken->enc_block.key_length); - len +=2; + *((uint16_t *)(orig_field + len)) = nswap16(dtoken->enc_block.key_length); + len += 2; - memcpy(orig_field+len,dtoken->enc_block.mac_key,dtoken->enc_block.key_length); - len += dtoken->enc_block.key_length; + memcpy(orig_field + len, dtoken->enc_block.mac_key, dtoken->enc_block.key_length); + len += dtoken->enc_block.key_length; - uint64_t ts = nswap64(dtoken->enc_block.timestamp); - memcpy( (orig_field+len), &ts, sizeof(ts)); - len += sizeof(ts); + uint64_t ts = nswap64(dtoken->enc_block.timestamp); + memcpy((orig_field + len), &ts, sizeof(ts)); + len += sizeof(ts); - *((uint32_t*)(orig_field+len)) = nswap32(dtoken->enc_block.lifetime); - len += 4; + *((uint32_t *)(orig_field + len)) = nswap32(dtoken->enc_block.lifetime); + len += 4; - const EVP_CIPHER * cipher = get_cipher_type(key->as_rs_alg); - if(!cipher) - return -1; + const EVP_CIPHER *cipher = get_cipher_type(key->as_rs_alg); + if (!cipher) + return -1; #if OPENSSL_VERSION_NUMBER < 0x10100000L - EVP_CIPHER_CTX ctx; - EVP_CIPHER_CTX *ctxp = &ctx; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctxp = &ctx; #else - EVP_CIPHER_CTX *ctxp = EVP_CIPHER_CTX_new(); + EVP_CIPHER_CTX *ctxp = EVP_CIPHER_CTX_new(); #endif - EVP_CIPHER_CTX_init(ctxp); + EVP_CIPHER_CTX_init(ctxp); - /* Initialize the encryption operation. */ - if(1 != EVP_EncryptInit_ex(ctxp, cipher, NULL, NULL, NULL)) - return -1; + /* Initialize the encryption operation. */ + if (1 != EVP_EncryptInit_ex(ctxp, cipher, NULL, NULL, NULL)) + return -1; - EVP_CIPHER_CTX_set_padding(ctxp,1); + EVP_CIPHER_CTX_set_padding(ctxp, 1); - /* Set IV length if default 12 bytes (96 bits) is not appropriate */ - if(1 != EVP_CIPHER_CTX_ctrl(ctxp, EVP_CTRL_GCM_SET_IVLEN, OAUTH_GCM_NONCE_SIZE, NULL)) - return -1; + /* Set IV length if default 12 bytes (96 bits) is not appropriate */ + if (1 != EVP_CIPHER_CTX_ctrl(ctxp, EVP_CTRL_GCM_SET_IVLEN, OAUTH_GCM_NONCE_SIZE, NULL)) + return -1; - /* Initialize key and IV */ - if(1 != EVP_EncryptInit_ex(ctxp, NULL, NULL, (const unsigned char *)key->as_rs_key, nonce)) - return -1; + /* Initialize key and IV */ + if (1 != EVP_EncryptInit_ex(ctxp, NULL, NULL, (const unsigned char *)key->as_rs_key, nonce)) + return -1; - int outl=0; - size_t sn_len = strlen((const char*)server_name); + int outl = 0; + size_t sn_len = strlen((const char *)server_name); - /* Provide any AAD data. This can be called zero or more times as - * required - */ - if(1 != my_EVP_EncryptUpdate(ctxp, NULL, &outl, server_name, (int)sn_len)) - return -1; + /* Provide any AAD data. This can be called zero or more times as + * required + */ + if (1 != my_EVP_EncryptUpdate(ctxp, NULL, &outl, server_name, (int)sn_len)) + return -1; - outl=0; - unsigned char *encoded_field = (unsigned char*)etoken->token; - memcpy(encoded_field,orig_field,OAUTH_GCM_NONCE_SIZE + 2); - encoded_field += OAUTH_GCM_NONCE_SIZE + 2; - unsigned char *start_field = orig_field + OAUTH_GCM_NONCE_SIZE + 2; - len -= OAUTH_GCM_NONCE_SIZE + 2; + outl = 0; + unsigned char *encoded_field = (unsigned char *)etoken->token; + memcpy(encoded_field, orig_field, OAUTH_GCM_NONCE_SIZE + 2); + encoded_field += OAUTH_GCM_NONCE_SIZE + 2; + unsigned char *start_field = orig_field + OAUTH_GCM_NONCE_SIZE + 2; + len -= OAUTH_GCM_NONCE_SIZE + 2; - if(1 != my_EVP_EncryptUpdate(ctxp, encoded_field, &outl, start_field, (int)len)) - return -1; + if (1 != my_EVP_EncryptUpdate(ctxp, encoded_field, &outl, start_field, (int)len)) + return -1; - int tmp_outl = 0; - EVP_EncryptFinal_ex(ctxp, encoded_field + outl, &tmp_outl); - outl += tmp_outl; + int tmp_outl = 0; + EVP_EncryptFinal_ex(ctxp, encoded_field + outl, &tmp_outl); + outl += tmp_outl; - EVP_CIPHER_CTX_ctrl(ctxp, EVP_CTRL_GCM_GET_TAG, OAUTH_GCM_TAG_SIZE, encoded_field + outl); - outl += OAUTH_GCM_TAG_SIZE; + EVP_CIPHER_CTX_ctrl(ctxp, EVP_CTRL_GCM_GET_TAG, OAUTH_GCM_TAG_SIZE, encoded_field + outl); + outl += OAUTH_GCM_TAG_SIZE; - etoken->size = 2 + OAUTH_GCM_NONCE_SIZE + outl; + etoken->size = 2 + OAUTH_GCM_NONCE_SIZE + outl; #if OPENSSL_VERSION_NUMBER < 0x10100000L - EVP_CIPHER_CTX_cleanup(ctxp); + EVP_CIPHER_CTX_cleanup(ctxp); #else - EVP_CIPHER_CTX_free(ctxp); + EVP_CIPHER_CTX_free(ctxp); #endif - return 0; - } - return -1; + return 0; + } + return -1; } -static int decode_oauth_token_gcm(const uint8_t *server_name, const encoded_oauth_token *etoken, const oauth_key *key, oauth_token *dtoken) -{ - if(server_name && etoken && key && dtoken) { +static int decode_oauth_token_gcm(const uint8_t *server_name, const encoded_oauth_token *etoken, const oauth_key *key, + oauth_token *dtoken) { + if (server_name && etoken && key && dtoken) { - unsigned char snl[2]; - memcpy(snl,(const unsigned char*)(etoken->token),2); - const unsigned char *csnl = snl; + unsigned char snl[2]; + memcpy(snl, (const unsigned char *)(etoken->token), 2); + const unsigned char *csnl = snl; - uint16_t nonce_len = nswap16(*((const uint16_t*)csnl)); - dtoken->enc_block.nonce_length = nonce_len; + uint16_t nonce_len = nswap16(*((const uint16_t *)csnl)); + dtoken->enc_block.nonce_length = nonce_len; - size_t min_encoded_field_size = 2+4+8+nonce_len+2+OAUTH_GCM_TAG_SIZE+1; - if(etoken->size < min_encoded_field_size) { - OAUTH_ERROR("%s: token size too small: %d\n",__FUNCTION__,(int)etoken->size); - return -1; - } + size_t min_encoded_field_size = 2 + 4 + 8 + nonce_len + 2 + OAUTH_GCM_TAG_SIZE + 1; + if (etoken->size < min_encoded_field_size) { + OAUTH_ERROR("%s: token size too small: %d\n", __FUNCTION__, (int)etoken->size); + return -1; + } - const unsigned char* encoded_field = (const unsigned char*)(etoken->token + nonce_len + 2); - unsigned int encoded_field_size = (unsigned int)etoken->size - nonce_len - 2 - OAUTH_GCM_TAG_SIZE; - const unsigned char* nonce = ((const unsigned char*)etoken->token + 2); - memcpy(dtoken->enc_block.nonce,nonce,nonce_len); + const unsigned char *encoded_field = (const unsigned char *)(etoken->token + nonce_len + 2); + unsigned int encoded_field_size = (unsigned int)etoken->size - nonce_len - 2 - OAUTH_GCM_TAG_SIZE; + const unsigned char *nonce = ((const unsigned char *)etoken->token + 2); + memcpy(dtoken->enc_block.nonce, nonce, nonce_len); - unsigned char tag[OAUTH_GCM_TAG_SIZE]; - memcpy(tag, ((const unsigned char*)etoken->token) + nonce_len + 2 + encoded_field_size, sizeof(tag)); + unsigned char tag[OAUTH_GCM_TAG_SIZE]; + memcpy(tag, ((const unsigned char *)etoken->token) + nonce_len + 2 + encoded_field_size, sizeof(tag)); - unsigned char decoded_field[MAX_ENCODED_OAUTH_TOKEN_SIZE]; + unsigned char decoded_field[MAX_ENCODED_OAUTH_TOKEN_SIZE]; - const EVP_CIPHER * cipher = get_cipher_type(key->as_rs_alg); - if(!cipher) { - OAUTH_ERROR("%s: Cannot find cipher for algorithm: %d\n",__FUNCTION__,(int)key->as_rs_alg); - return -1; - } + const EVP_CIPHER *cipher = get_cipher_type(key->as_rs_alg); + if (!cipher) { + OAUTH_ERROR("%s: Cannot find cipher for algorithm: %d\n", __FUNCTION__, (int)key->as_rs_alg); + return -1; + } #if OPENSSL_VERSION_NUMBER < 0x10100000L - EVP_CIPHER_CTX ctx; - EVP_CIPHER_CTX *ctxp = &ctx; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctxp = &ctx; #else - EVP_CIPHER_CTX *ctxp = EVP_CIPHER_CTX_new(); + EVP_CIPHER_CTX *ctxp = EVP_CIPHER_CTX_new(); #endif - EVP_CIPHER_CTX_init(ctxp); - /* Initialize the decryption operation. */ - if(1 != EVP_DecryptInit_ex(ctxp, cipher, NULL, NULL, NULL)) { - OAUTH_ERROR("%s: Cannot initialize decryption\n",__FUNCTION__); - return -1; - } + EVP_CIPHER_CTX_init(ctxp); + /* Initialize the decryption operation. */ + if (1 != EVP_DecryptInit_ex(ctxp, cipher, NULL, NULL, NULL)) { + OAUTH_ERROR("%s: Cannot initialize decryption\n", __FUNCTION__); + return -1; + } - //EVP_CIPHER_CTX_set_padding(&ctx,1); + // EVP_CIPHER_CTX_set_padding(&ctx,1); - /* Set IV length if default 12 bytes (96 bits) is not appropriate */ - if(1 != EVP_CIPHER_CTX_ctrl(ctxp, EVP_CTRL_GCM_SET_IVLEN, nonce_len, NULL)) { - OAUTH_ERROR("%s: Cannot set nonce length\n",__FUNCTION__); - return -1; - } + /* Set IV length if default 12 bytes (96 bits) is not appropriate */ + if (1 != EVP_CIPHER_CTX_ctrl(ctxp, EVP_CTRL_GCM_SET_IVLEN, nonce_len, NULL)) { + OAUTH_ERROR("%s: Cannot set nonce length\n", __FUNCTION__); + return -1; + } - /* Initialize key and IV */ - if(1 != EVP_DecryptInit_ex(ctxp, NULL, NULL, (const unsigned char *)key->as_rs_key, nonce)) { - OAUTH_ERROR("%s: Cannot set nonce\n",__FUNCTION__); - return -1; - } + /* Initialize key and IV */ + if (1 != EVP_DecryptInit_ex(ctxp, NULL, NULL, (const unsigned char *)key->as_rs_key, nonce)) { + OAUTH_ERROR("%s: Cannot set nonce\n", __FUNCTION__); + return -1; + } - /* Set expected tag value. A restriction in OpenSSL 1.0.1c and earlier - + * required the tag before any AAD or ciphertext */ - EVP_CIPHER_CTX_ctrl (ctxp, EVP_CTRL_GCM_SET_TAG, OAUTH_GCM_TAG_SIZE, tag); + /* Set expected tag value. A restriction in OpenSSL 1.0.1c and earlier + + * required the tag before any AAD or ciphertext */ + EVP_CIPHER_CTX_ctrl(ctxp, EVP_CTRL_GCM_SET_TAG, OAUTH_GCM_TAG_SIZE, tag); - int outl=0; - size_t sn_len = strlen((const char*)server_name); + int outl = 0; + size_t sn_len = strlen((const char *)server_name); - /* Provide any AAD data. This can be called zero or more times as - * required - */ - if(1 != my_EVP_DecryptUpdate(ctxp, NULL, &outl, server_name, (int)sn_len)) { - OAUTH_ERROR("%s: Cannot decrypt update server_name: %s, len=%d\n",__FUNCTION__,server_name,(int)sn_len); - return -1; - } - if(1 != my_EVP_DecryptUpdate(ctxp, decoded_field, &outl, encoded_field, (int)encoded_field_size)) { - OAUTH_ERROR("%s: Cannot decrypt update\n",__FUNCTION__); - return -1; - } + /* Provide any AAD data. This can be called zero or more times as + * required + */ + if (1 != my_EVP_DecryptUpdate(ctxp, NULL, &outl, server_name, (int)sn_len)) { + OAUTH_ERROR("%s: Cannot decrypt update server_name: %s, len=%d\n", __FUNCTION__, server_name, (int)sn_len); + return -1; + } + if (1 != my_EVP_DecryptUpdate(ctxp, decoded_field, &outl, encoded_field, (int)encoded_field_size)) { + OAUTH_ERROR("%s: Cannot decrypt update\n", __FUNCTION__); + return -1; + } - int tmp_outl = 0; - if(EVP_DecryptFinal_ex(ctxp, decoded_field + outl, &tmp_outl)<1) { + int tmp_outl = 0; + if (EVP_DecryptFinal_ex(ctxp, decoded_field + outl, &tmp_outl) < 1) { #if OPENSSL_VERSION_NUMBER < 0x10100000L - EVP_CIPHER_CTX_cleanup(ctxp); + EVP_CIPHER_CTX_cleanup(ctxp); #else - EVP_CIPHER_CTX_free(ctxp); + EVP_CIPHER_CTX_free(ctxp); #endif - OAUTH_ERROR("%s: token integrity check failed\n",__FUNCTION__); - return -1; - } - outl += tmp_outl; + OAUTH_ERROR("%s: token integrity check failed\n", __FUNCTION__); + return -1; + } + outl += tmp_outl; #if OPENSSL_VERSION_NUMBER < 0x10100000L - EVP_CIPHER_CTX_cleanup(ctxp); + EVP_CIPHER_CTX_cleanup(ctxp); #else - EVP_CIPHER_CTX_free(ctxp); + EVP_CIPHER_CTX_free(ctxp); #endif - size_t len = 0; + size_t len = 0; - dtoken->enc_block.key_length = nswap16(*((uint16_t*)(decoded_field+len))); - len += 2; + dtoken->enc_block.key_length = nswap16(*((uint16_t *)(decoded_field + len))); + len += 2; - memcpy(dtoken->enc_block.mac_key,decoded_field+len,dtoken->enc_block.key_length); - len += dtoken->enc_block.key_length; + memcpy(dtoken->enc_block.mac_key, decoded_field + len, dtoken->enc_block.key_length); + len += dtoken->enc_block.key_length; - uint64_t ts; - memcpy(&ts,(decoded_field+len),sizeof(ts)); - dtoken->enc_block.timestamp = nswap64(ts); - len += sizeof(ts); + uint64_t ts; + memcpy(&ts, (decoded_field + len), sizeof(ts)); + dtoken->enc_block.timestamp = nswap64(ts); + len += sizeof(ts); - uint32_t lt; - memcpy(<,(decoded_field+len),sizeof(lt)); - dtoken->enc_block.lifetime = nswap32(lt); - len += sizeof(lt); + uint32_t lt; + memcpy(<, (decoded_field + len), sizeof(lt)); + dtoken->enc_block.lifetime = nswap32(lt); + len += sizeof(lt); - return 0; - } - return -1; + return 0; + } + return -1; } #endif -int encode_oauth_token(const uint8_t *server_name, encoded_oauth_token *etoken, const oauth_key *key, const oauth_token *dtoken, const uint8_t *nonce) -{ - UNUSED_ARG(nonce); - if(server_name && etoken && key && dtoken) { - switch(key->as_rs_alg) { +int encode_oauth_token(const uint8_t *server_name, encoded_oauth_token *etoken, const oauth_key *key, + const oauth_token *dtoken, const uint8_t *nonce) { + UNUSED_ARG(nonce); + if (server_name && etoken && key && dtoken) { + switch (key->as_rs_alg) { #if !defined(TURN_NO_GCM) - case A256GCM: - case A128GCM: - return encode_oauth_token_gcm(server_name, etoken,key,dtoken,nonce); + case A256GCM: + case A128GCM: + return encode_oauth_token_gcm(server_name, etoken, key, dtoken, nonce); #endif - default: - fprintf(stderr,"Unsupported AS_RS algorithm: %d\n",(int)key->as_rs_alg); - break; - }; - } - return -1; + default: + fprintf(stderr, "Unsupported AS_RS algorithm: %d\n", (int)key->as_rs_alg); + break; + }; + } + return -1; } -int decode_oauth_token(const uint8_t *server_name, const encoded_oauth_token *etoken, const oauth_key *key, oauth_token *dtoken) -{ - if(server_name && etoken && key && dtoken) { - switch(key->as_rs_alg) { +int decode_oauth_token(const uint8_t *server_name, const encoded_oauth_token *etoken, const oauth_key *key, + oauth_token *dtoken) { + if (server_name && etoken && key && dtoken) { + switch (key->as_rs_alg) { #if !defined(TURN_NO_GCM) - case A256GCM: - case A128GCM: - return decode_oauth_token_gcm(server_name, etoken,key,dtoken); + case A256GCM: + case A128GCM: + return decode_oauth_token_gcm(server_name, etoken, key, dtoken); #endif - default: - fprintf(stderr,"Unsupported AS_RS algorithm: %d\n",(int)key->as_rs_alg); - break; - }; - } - return -1; + default: + fprintf(stderr, "Unsupported AS_RS algorithm: %d\n", (int)key->as_rs_alg); + break; + }; + } + return -1; } /////////////////////////////////////////////////////////////// diff --git a/src/client/ns_turn_msg.h b/src/client/ns_turn_msg.h index 759c091..75186b3 100644 --- a/src/client/ns_turn_msg.h +++ b/src/client/ns_turn_msg.h @@ -45,17 +45,17 @@ extern "C" { */ #define STUN_TID_SIZE (12) typedef struct { - /** - * Binary array - */ + /** + * Binary array + */ uint8_t tsx_id[STUN_TID_SIZE]; } stun_tid; typedef enum { - TURN_CREDENTIALS_NONE = 0, - TURN_CREDENTIALS_LONG_TERM, - TURN_CREDENTIALS_SHORT_TERM, - TURN_CREDENTIALS_UNDEFINED + TURN_CREDENTIALS_NONE = 0, + TURN_CREDENTIALS_LONG_TERM, + TURN_CREDENTIALS_SHORT_TERM, + TURN_CREDENTIALS_UNDEFINED } turn_credential_type; /** @@ -63,18 +63,18 @@ typedef enum { */ typedef uint8_t hmackey_t[64]; -typedef uint8_t password_t[STUN_MAX_PWD_SIZE+1]; +typedef uint8_t password_t[STUN_MAX_PWD_SIZE + 1]; typedef unsigned long band_limit_t; /////////////////////////////////// -typedef const void* stun_attr_ref; +typedef const void *stun_attr_ref; ////////////////////////////////////////////////////////////// int stun_tid_equals(const stun_tid *id1, const stun_tid *id2); void stun_tid_cpy(stun_tid *id_dst, const stun_tid *id_src); -void stun_tid_generate(stun_tid* id); +void stun_tid_generate(stun_tid *id); /////////////////////////////////////////////////////////////// @@ -86,7 +86,8 @@ uint16_t stun_make_error_response(uint16_t method); /////////////////////////////////////////////////////////////// -turn_time_t stun_adjust_allocate_lifetime(turn_time_t lifetime, turn_time_t max_allowed_lifetime, turn_time_t max_lifetime); +turn_time_t stun_adjust_allocate_lifetime(turn_time_t lifetime, turn_time_t max_allowed_lifetime, + turn_time_t max_lifetime); ///////////// STR //////////////////////////////////////////////// @@ -95,79 +96,85 @@ int stun_method_str(uint16_t method, char *smethod); int stun_get_message_len_str(uint8_t *buf, size_t len, int padding, size_t *app_len); void stun_init_buffer_str(uint8_t *buf, size_t *len); -void stun_init_command_str(uint16_t message_type, uint8_t* buf, size_t *len); -void old_stun_init_command_str(uint16_t message_type, uint8_t* buf, size_t *len, uint32_t cookie); -void stun_init_request_str(uint16_t method, uint8_t* buf, size_t *len); -void stun_init_indication_str(uint16_t method, uint8_t* buf, size_t *len); -void stun_init_success_response_str(uint16_t method, uint8_t* buf, size_t *len, stun_tid* id); -void old_stun_init_success_response_str(uint16_t method, uint8_t* buf, size_t *len, stun_tid* id, uint32_t cookie); -void stun_init_error_response_str(uint16_t method, uint8_t* buf, size_t *len, uint16_t error_code, const uint8_t *reason, stun_tid* id); -void old_stun_init_error_response_str(uint16_t method, uint8_t* buf, size_t *len, uint16_t error_code, const uint8_t *reason, stun_tid* id, uint32_t cookie); -int stun_init_channel_message_str(uint16_t chnumber, uint8_t* buf, size_t *len, int length, int do_padding); +void stun_init_command_str(uint16_t message_type, uint8_t *buf, size_t *len); +void old_stun_init_command_str(uint16_t message_type, uint8_t *buf, size_t *len, uint32_t cookie); +void stun_init_request_str(uint16_t method, uint8_t *buf, size_t *len); +void stun_init_indication_str(uint16_t method, uint8_t *buf, size_t *len); +void stun_init_success_response_str(uint16_t method, uint8_t *buf, size_t *len, stun_tid *id); +void old_stun_init_success_response_str(uint16_t method, uint8_t *buf, size_t *len, stun_tid *id, uint32_t cookie); +void stun_init_error_response_str(uint16_t method, uint8_t *buf, size_t *len, uint16_t error_code, + const uint8_t *reason, stun_tid *id); +void old_stun_init_error_response_str(uint16_t method, uint8_t *buf, size_t *len, uint16_t error_code, + const uint8_t *reason, stun_tid *id, uint32_t cookie); +int stun_init_channel_message_str(uint16_t chnumber, uint8_t *buf, size_t *len, int length, int do_padding); -int stun_is_command_message_str(const uint8_t* buf, size_t blen); -int old_stun_is_command_message_str(const uint8_t* buf, size_t blen, uint32_t *cookie); -int stun_is_command_message_full_check_str(const uint8_t* buf, size_t blen, int must_check_fingerprint, int *fingerprint_present); -int stun_is_command_message_offset_str(const uint8_t* buf, size_t blen, int offset); -int stun_is_request_str(const uint8_t* buf, size_t len); -int stun_is_success_response_str(const uint8_t* buf, size_t len); -int stun_is_error_response_str(const uint8_t* buf, size_t len, int *err_code, uint8_t *err_msg, size_t err_msg_size); -int stun_is_challenge_response_str(const uint8_t* buf, size_t len, int *err_code, uint8_t *err_msg, size_t err_msg_size, uint8_t *realm, uint8_t *nonce, uint8_t *server_name, int *oauth); -int stun_is_response_str(const uint8_t* buf, size_t len); -int stun_is_indication_str(const uint8_t* buf, size_t len); +int stun_is_command_message_str(const uint8_t *buf, size_t blen); +int old_stun_is_command_message_str(const uint8_t *buf, size_t blen, uint32_t *cookie); +int stun_is_command_message_full_check_str(const uint8_t *buf, size_t blen, int must_check_fingerprint, + int *fingerprint_present); +int stun_is_command_message_offset_str(const uint8_t *buf, size_t blen, int offset); +int stun_is_request_str(const uint8_t *buf, size_t len); +int stun_is_success_response_str(const uint8_t *buf, size_t len); +int stun_is_error_response_str(const uint8_t *buf, size_t len, int *err_code, uint8_t *err_msg, size_t err_msg_size); +int stun_is_challenge_response_str(const uint8_t *buf, size_t len, int *err_code, uint8_t *err_msg, size_t err_msg_size, + uint8_t *realm, uint8_t *nonce, uint8_t *server_name, int *oauth); +int stun_is_response_str(const uint8_t *buf, size_t len); +int stun_is_indication_str(const uint8_t *buf, size_t len); uint16_t stun_get_method_str(const uint8_t *buf, size_t len); uint16_t stun_get_msg_type_str(const uint8_t *buf, size_t len); -int stun_is_channel_message_str(const uint8_t *buf, size_t *blen, uint16_t* chnumber, int mandatory_padding); -int is_channel_msg_str(const uint8_t* buf, size_t blen); +int stun_is_channel_message_str(const uint8_t *buf, size_t *blen, uint16_t *chnumber, int mandatory_padding); +int is_channel_msg_str(const uint8_t *buf, size_t blen); -void stun_set_binding_request_str(uint8_t* buf, size_t *len); -int stun_set_binding_response_str(uint8_t* buf, size_t *len, stun_tid* tid, - const ioa_addr *reflexive_addr, int error_code, - const uint8_t *reason, - uint32_t cookie, int old_stun, int no_stun_backward_compatibility); -int stun_is_binding_request_str(const uint8_t* buf, size_t len, size_t offset); -int stun_is_binding_response_str(const uint8_t* buf, size_t len); +void stun_set_binding_request_str(uint8_t *buf, size_t *len); +int stun_set_binding_response_str(uint8_t *buf, size_t *len, stun_tid *tid, const ioa_addr *reflexive_addr, + int error_code, const uint8_t *reason, uint32_t cookie, int old_stun, + int no_stun_backward_compatibility); +int stun_is_binding_request_str(const uint8_t *buf, size_t len, size_t offset); +int stun_is_binding_response_str(const uint8_t *buf, size_t len); -void stun_tid_from_message_str(const uint8_t* buf, size_t len, stun_tid* id); -void stun_tid_message_cpy(uint8_t *buf, const stun_tid* id); -void stun_tid_generate_in_message_str(uint8_t* buf, stun_tid* id); +void stun_tid_from_message_str(const uint8_t *buf, size_t len, stun_tid *id); +void stun_tid_message_cpy(uint8_t *buf, const stun_tid *id); +void stun_tid_generate_in_message_str(uint8_t *buf, stun_tid *id); -int stun_get_command_message_len_str(const uint8_t* buf, size_t len); +int stun_get_command_message_len_str(const uint8_t *buf, size_t len); -const uint8_t* get_default_reason(int error_code); +const uint8_t *get_default_reason(int error_code); int stun_attr_is_addr(stun_attr_ref attr); int stun_attr_get_type(stun_attr_ref attr); int stun_attr_get_len(stun_attr_ref attr); -const uint8_t* stun_attr_get_value(stun_attr_ref attr); +const uint8_t *stun_attr_get_value(stun_attr_ref attr); uint16_t stun_attr_get_channel_number(stun_attr_ref attr); band_limit_t stun_attr_get_bandwidth(stun_attr_ref attr); uint8_t stun_attr_get_even_port(stun_attr_ref attr); uint64_t stun_attr_get_reservation_token_value(stun_attr_ref attr); -stun_attr_ref stun_attr_get_first_by_type_str(const uint8_t* buf, size_t len, uint16_t attr_type); -stun_attr_ref stun_attr_get_first_str(const uint8_t* buf, size_t len); -stun_attr_ref stun_attr_get_next_str(const uint8_t* buf, size_t len, stun_attr_ref prev); -int stun_attr_add_str(uint8_t* buf, size_t *len, uint16_t attr, const uint8_t* avalue, int alen); -int stun_attr_add_addr_str(uint8_t *buf, size_t *len, uint16_t attr_type, const ioa_addr* ca); -int stun_attr_get_addr_str(const uint8_t *buf, size_t len, stun_attr_ref attr, ioa_addr* ca, const ioa_addr *default_addr); -int stun_attr_get_first_addr_str(const uint8_t *buf, size_t len, uint16_t attr_type, ioa_addr* ca, const ioa_addr *default_addr); -int stun_attr_add_channel_number_str(uint8_t* buf, size_t *len, uint16_t chnumber); -int stun_attr_add_bandwidth_str(uint8_t* buf, size_t *len, band_limit_t bps); -int stun_attr_add_address_error_code(uint8_t* buf, size_t *len, int requested_address_family, int error_code); +stun_attr_ref stun_attr_get_first_by_type_str(const uint8_t *buf, size_t len, uint16_t attr_type); +stun_attr_ref stun_attr_get_first_str(const uint8_t *buf, size_t len); +stun_attr_ref stun_attr_get_next_str(const uint8_t *buf, size_t len, stun_attr_ref prev); +int stun_attr_add_str(uint8_t *buf, size_t *len, uint16_t attr, const uint8_t *avalue, int alen); +int stun_attr_add_addr_str(uint8_t *buf, size_t *len, uint16_t attr_type, const ioa_addr *ca); +int stun_attr_get_addr_str(const uint8_t *buf, size_t len, stun_attr_ref attr, ioa_addr *ca, + const ioa_addr *default_addr); +int stun_attr_get_first_addr_str(const uint8_t *buf, size_t len, uint16_t attr_type, ioa_addr *ca, + const ioa_addr *default_addr); +int stun_attr_add_channel_number_str(uint8_t *buf, size_t *len, uint16_t chnumber); +int stun_attr_add_bandwidth_str(uint8_t *buf, size_t *len, band_limit_t bps); +int stun_attr_add_address_error_code(uint8_t *buf, size_t *len, int requested_address_family, int error_code); /* return +1 if present, 0 if not, -1 if error: */ -int stun_attr_get_address_error_code(uint8_t* buf, size_t len, int *requested_address_family, int *error_code); +int stun_attr_get_address_error_code(uint8_t *buf, size_t len, int *requested_address_family, int *error_code); uint16_t stun_attr_get_first_channel_number_str(const uint8_t *buf, size_t len); -int stun_set_allocate_request_str(uint8_t* buf, size_t *len, uint32_t lifetime, int af4, int af6, uint8_t transport, int mobile, const char* rt, int ep); -int stun_set_allocate_response_str(uint8_t* buf, size_t *len, stun_tid* tid, - const ioa_addr *relayed_addr1, const ioa_addr *relayed_addr2, - const ioa_addr *reflexive_addr, - uint32_t lifetime, uint32_t max_lifetime, int error_code, const uint8_t *reason, - uint64_t reservation_token, char *mobile_id); +int stun_set_allocate_request_str(uint8_t *buf, size_t *len, uint32_t lifetime, int af4, int af6, uint8_t transport, + int mobile, const char *rt, int ep); +int stun_set_allocate_response_str(uint8_t *buf, size_t *len, stun_tid *tid, const ioa_addr *relayed_addr1, + const ioa_addr *relayed_addr2, const ioa_addr *reflexive_addr, uint32_t lifetime, + uint32_t max_lifetime, int error_code, const uint8_t *reason, + uint64_t reservation_token, char *mobile_id); -uint16_t stun_set_channel_bind_request_str(uint8_t* buf, size_t *len, - const ioa_addr* peer_addr, uint16_t channel_number); -void stun_set_channel_bind_response_str(uint8_t* buf, size_t *len, stun_tid* tid, int error_code, const uint8_t *reason); +uint16_t stun_set_channel_bind_request_str(uint8_t *buf, size_t *len, const ioa_addr *peer_addr, + uint16_t channel_number); +void stun_set_channel_bind_response_str(uint8_t *buf, size_t *len, stun_tid *tid, int error_code, + const uint8_t *reason); int stun_get_requested_address_family(stun_attr_ref attr); @@ -175,18 +182,24 @@ int stun_attr_add_fingerprint_str(uint8_t *buf, size_t *len); int SASLprep(uint8_t *s); -#define print_bin(str, len, field) print_bin_func(str,len,field,__FUNCTION__) +#define print_bin(str, len, field) print_bin_func(str, len, field, __FUNCTION__) void print_bin_func(const char *name, size_t len, const void *s, const char *func); /* * Return -1 if failure, 0 if the integrity is not correct, 1 if OK */ -int stun_check_message_integrity_by_key_str(turn_credential_type ct, uint8_t *buf, size_t len, hmackey_t key, password_t pwd, SHATYPE shatype); -int stun_check_message_integrity_str(turn_credential_type ct, uint8_t *buf, size_t len, const uint8_t *uname, const uint8_t *realm, const uint8_t *upwd, SHATYPE shatype); -int stun_attr_add_integrity_str(turn_credential_type ct, uint8_t *buf, size_t *len, hmackey_t key, password_t pwd, SHATYPE shatype); -int stun_attr_add_integrity_by_key_str(uint8_t *buf, size_t *len, const uint8_t *uname, const uint8_t *realm, hmackey_t key, const uint8_t *nonce, SHATYPE shatype); -int stun_attr_add_integrity_by_user_str(uint8_t *buf, size_t *len, const uint8_t *uname, const uint8_t *realm, const uint8_t *upwd, const uint8_t *nonce, SHATYPE shatype); -int stun_attr_add_integrity_by_user_short_term_str(uint8_t *buf, size_t *len, const uint8_t *uname, password_t pwd, SHATYPE shatype); +int stun_check_message_integrity_by_key_str(turn_credential_type ct, uint8_t *buf, size_t len, hmackey_t key, + password_t pwd, SHATYPE shatype); +int stun_check_message_integrity_str(turn_credential_type ct, uint8_t *buf, size_t len, const uint8_t *uname, + const uint8_t *realm, const uint8_t *upwd, SHATYPE shatype); +int stun_attr_add_integrity_str(turn_credential_type ct, uint8_t *buf, size_t *len, hmackey_t key, password_t pwd, + SHATYPE shatype); +int stun_attr_add_integrity_by_key_str(uint8_t *buf, size_t *len, const uint8_t *uname, const uint8_t *realm, + hmackey_t key, const uint8_t *nonce, SHATYPE shatype); +int stun_attr_add_integrity_by_user_str(uint8_t *buf, size_t *len, const uint8_t *uname, const uint8_t *realm, + const uint8_t *upwd, const uint8_t *nonce, SHATYPE shatype); +int stun_attr_add_integrity_by_user_short_term_str(uint8_t *buf, size_t *len, const uint8_t *uname, password_t pwd, + SHATYPE shatype); size_t get_hmackey_size(SHATYPE shatype); /* @@ -196,8 +209,10 @@ size_t get_hmackey_size(SHATYPE shatype); #define TURN_RANDOM_SIZE (sizeof(long)) long turn_random(void); -int stun_produce_integrity_key_str(const uint8_t *uname, const uint8_t *realm, const uint8_t *upwd, hmackey_t key, SHATYPE shatype); -int stun_calculate_hmac(const uint8_t *buf, size_t len, const uint8_t *key, size_t sz, uint8_t *hmac, unsigned int *hmac_len, SHATYPE shatype); +int stun_produce_integrity_key_str(const uint8_t *uname, const uint8_t *realm, const uint8_t *upwd, hmackey_t key, + SHATYPE shatype); +int stun_calculate_hmac(const uint8_t *buf, size_t len, const uint8_t *key, size_t sz, uint8_t *hmac, + unsigned int *hmac_len, SHATYPE shatype); /* RFC 5780 */ int stun_attr_get_change_request_str(stun_attr_ref attr, int *change_ip, int *change_port); @@ -212,12 +227,14 @@ int is_http(const char *s, size_t blen); /* OAUTH */ int convert_oauth_key_data(const oauth_key_data *oakd, oauth_key *key, char *err_msg, size_t err_msg_size); -int decode_oauth_token(const uint8_t *server_name, const encoded_oauth_token *etoken, const oauth_key *key, oauth_token *dtoken); -int encode_oauth_token(const uint8_t *server_name, encoded_oauth_token *etoken, const oauth_key *key, const oauth_token *dtoken, const uint8_t *nonce); +int decode_oauth_token(const uint8_t *server_name, const encoded_oauth_token *etoken, const oauth_key *key, + oauth_token *dtoken); +int encode_oauth_token(const uint8_t *server_name, encoded_oauth_token *etoken, const oauth_key *key, + const oauth_token *dtoken, const uint8_t *nonce); /* Encrypted password */ -void generate_new_enc_password(const char* pwd, char *result); -int check_password(const char* pin, const char* pwd); +void generate_new_enc_password(const char *pwd, char *result); +int check_password(const char *pin, const char *pwd); /////////////////////////////////////////////////////////////// diff --git a/src/client/ns_turn_msg_addr.c b/src/client/ns_turn_msg_addr.c index 6e7b4c1..ea27b93 100644 --- a/src/client/ns_turn_msg_addr.c +++ b/src/client/ns_turn_msg_addr.c @@ -32,71 +32,72 @@ ////////////////////////////////////////////////////////////////////////////// -int stun_addr_encode(const ioa_addr* ca, uint8_t *cfield, int *clen, int xor_ed, uint32_t mc, const uint8_t *tsx_id) { +int stun_addr_encode(const ioa_addr *ca, uint8_t *cfield, int *clen, int xor_ed, uint32_t mc, const uint8_t *tsx_id) { - if(!cfield || !clen || !ca || !tsx_id) return -1; + if (!cfield || !clen || !ca || !tsx_id) + return -1; - if (ca->ss.sa_family == AF_INET || ca->ss.sa_family==0) { + if (ca->ss.sa_family == AF_INET || ca->ss.sa_family == 0) { /* IPv4 address */ - *clen=8; - - cfield[0]=0; - cfield[1]=1; //IPv4 family - + *clen = 8; + + cfield[0] = 0; + cfield[1] = 1; // IPv4 family + if (xor_ed) { /* Port */ - ((uint16_t*)cfield)[1] = (ca->s4.sin_port) ^ nswap16(mc >> 16); + ((uint16_t *)cfield)[1] = (ca->s4.sin_port) ^ nswap16(mc >> 16); /* Address */ - ((uint32_t*)cfield)[1] = (ca->s4.sin_addr.s_addr) ^ nswap32(mc); + ((uint32_t *)cfield)[1] = (ca->s4.sin_addr.s_addr) ^ nswap32(mc); } else { /* Port */ - ((uint16_t*)cfield)[1]=ca->s4.sin_port; + ((uint16_t *)cfield)[1] = ca->s4.sin_port; /* Address */ - ((uint32_t*)cfield)[1]=ca->s4.sin_addr.s_addr; + ((uint32_t *)cfield)[1] = ca->s4.sin_addr.s_addr; } } else if (ca->ss.sa_family == AF_INET6) { /* IPv6 address */ - *clen=20; + *clen = 20; + + cfield[0] = 0; + cfield[1] = 2; // IPv6 family - cfield[0]=0; - cfield[1]=2; //IPv6 family - if (xor_ed) { unsigned int i; - uint8_t *dst = ((uint8_t*)cfield)+4; - const uint8_t *src = (const uint8_t*)&(ca->s6.sin6_addr); + uint8_t *dst = ((uint8_t *)cfield) + 4; + const uint8_t *src = (const uint8_t *)&(ca->s6.sin6_addr); uint32_t magic = nswap32(mc); /* Port */ - ((uint16_t*)cfield)[1] = ca->s6.sin6_port ^ nswap16(mc >> 16); + ((uint16_t *)cfield)[1] = ca->s6.sin6_port ^ nswap16(mc >> 16); /* Address */ - for (i=0; i<4; ++i) { - dst[i] = (uint8_t)(src[i] ^ ((const uint8_t*)&magic)[i]); + for (i = 0; i < 4; ++i) { + dst[i] = (uint8_t)(src[i] ^ ((const uint8_t *)&magic)[i]); } - for (i=0; i<12; ++i) { - dst[i+4] = (uint8_t)(src[i+4] ^ tsx_id[i]); + for (i = 0; i < 12; ++i) { + dst[i + 4] = (uint8_t)(src[i + 4] ^ tsx_id[i]); } } else { /* Port */ - ((uint16_t*)cfield)[1]=ca->s6.sin6_port; - + ((uint16_t *)cfield)[1] = ca->s6.sin6_port; + /* Address */ - memcpy(((uint8_t*)cfield)+4, &ca->s6.sin6_addr, 16); + memcpy(((uint8_t *)cfield) + 4, &ca->s6.sin6_addr, 16); } } else { @@ -106,34 +107,39 @@ int stun_addr_encode(const ioa_addr* ca, uint8_t *cfield, int *clen, int xor_ed, return 0; } -int stun_addr_decode(ioa_addr* ca, const uint8_t *cfield, int len, int xor_ed, uint32_t mc, const uint8_t *tsx_id) { +int stun_addr_decode(ioa_addr *ca, const uint8_t *cfield, int len, int xor_ed, uint32_t mc, const uint8_t *tsx_id) { - if(!cfield || !len || !ca || !tsx_id || (len<8)) return -1; + if (!cfield || !len || !ca || !tsx_id || (len < 8)) + return -1; - if(cfield[0]!=0) { + if (cfield[0] != 0) { return -1; } int sa_family; - if(cfield[1]==1) sa_family=AF_INET; - else if(cfield[1]==2) sa_family=AF_INET6; - else return -1; - - ca->ss.sa_family=sa_family; + if (cfield[1] == 1) + sa_family = AF_INET; + else if (cfield[1] == 2) + sa_family = AF_INET6; + else + return -1; + + ca->ss.sa_family = sa_family; if (sa_family == AF_INET) { - if(len!=8) return -1; + if (len != 8) + return -1; /* IPv4 address */ /* Port */ - ca->s4.sin_port=((const uint16_t*)cfield)[1]; + ca->s4.sin_port = ((const uint16_t *)cfield)[1]; /* Address */ - ca->s4.sin_addr.s_addr=((const uint32_t*)cfield)[1]; - + ca->s4.sin_addr.s_addr = ((const uint32_t *)cfield)[1]; + if (xor_ed) { ca->s4.sin_port ^= nswap16(mc >> 16); ca->s4.sin_addr.s_addr ^= nswap32(mc); @@ -143,13 +149,14 @@ int stun_addr_decode(ioa_addr* ca, const uint8_t *cfield, int len, int xor_ed, u /* IPv6 address */ - if(len!=20) return -1; + if (len != 20) + return -1; /* Port */ - ca->s6.sin6_port = ((const uint16_t*)cfield)[1]; + ca->s6.sin6_port = ((const uint16_t *)cfield)[1]; /* Address */ - memcpy(&ca->s6.sin6_addr, ((const uint8_t*)cfield)+4, 16); + memcpy(&ca->s6.sin6_addr, ((const uint8_t *)cfield) + 4, 16); if (xor_ed) { @@ -162,13 +169,13 @@ int stun_addr_decode(ioa_addr* ca, const uint8_t *cfield, int len, int xor_ed, u ca->s6.sin6_port ^= nswap16(mc >> 16); /* Address */ - src = ((const uint8_t*)cfield)+4; - dst = (uint8_t*)&ca->s6.sin6_addr; - for (i=0; i<4; ++i) { - dst[i] = (uint8_t)(src[i] ^ ((const uint8_t*)&magic)[i]); + src = ((const uint8_t *)cfield) + 4; + dst = (uint8_t *)&ca->s6.sin6_addr; + for (i = 0; i < 4; ++i) { + dst[i] = (uint8_t)(src[i] ^ ((const uint8_t *)&magic)[i]); } - for (i=0; i<12; ++i) { - dst[i+4] = (uint8_t)(src[i+4] ^ tsx_id[i]); + for (i = 0; i < 12; ++i) { + dst[i + 4] = (uint8_t)(src[i + 4] ^ tsx_id[i]); } } @@ -180,4 +187,3 @@ int stun_addr_decode(ioa_addr* ca, const uint8_t *cfield, int len, int xor_ed, u } ////////////////////////////////////////////////////////////////////////////// - diff --git a/src/client/ns_turn_msg_addr.h b/src/client/ns_turn_msg_addr.h index da10a48..c984fc5 100644 --- a/src/client/ns_turn_msg_addr.h +++ b/src/client/ns_turn_msg_addr.h @@ -39,8 +39,8 @@ extern "C" { /////////////////////////////////////////// -int stun_addr_encode(const ioa_addr* ca, uint8_t *cfield, int *clen, int xor_ed, uint32_t mc, const uint8_t *tsx_id); -int stun_addr_decode(ioa_addr* ca, const uint8_t *cfield, int len, int xor_ed, uint32_t mc, const uint8_t *tsx_id); +int stun_addr_encode(const ioa_addr *ca, uint8_t *cfield, int *clen, int xor_ed, uint32_t mc, const uint8_t *tsx_id); +int stun_addr_decode(ioa_addr *ca, const uint8_t *cfield, int len, int xor_ed, uint32_t mc, const uint8_t *tsx_id); /////////////////////////////////////////// diff --git a/src/client/ns_turn_msg_defs.h b/src/client/ns_turn_msg_defs.h index 867babc..214deb9 100644 --- a/src/client/ns_turn_msg_defs.h +++ b/src/client/ns_turn_msg_defs.h @@ -49,15 +49,15 @@ #define STUN_MAGIC_COOKIE (0x2112A442) -#define IS_STUN_REQUEST(msg_type) (((msg_type) & 0x0110) == 0x0000) -#define IS_STUN_INDICATION(msg_type) (((msg_type) & 0x0110) == 0x0010) -#define IS_STUN_SUCCESS_RESP(msg_type) (((msg_type) & 0x0110) == 0x0100) -#define IS_STUN_ERR_RESP(msg_type) (((msg_type) & 0x0110) == 0x0110) +#define IS_STUN_REQUEST(msg_type) (((msg_type)&0x0110) == 0x0000) +#define IS_STUN_INDICATION(msg_type) (((msg_type)&0x0110) == 0x0010) +#define IS_STUN_SUCCESS_RESP(msg_type) (((msg_type)&0x0110) == 0x0100) +#define IS_STUN_ERR_RESP(msg_type) (((msg_type)&0x0110) == 0x0110) -#define GET_STUN_REQUEST(msg_type) (msg_type & 0xFEEF) -#define GET_STUN_INDICATION(msg_type) ((msg_type & 0xFEEF)|0x0010) -#define GET_STUN_SUCCESS_RESP(msg_type) ((msg_type & 0xFEEF)|0x0100) -#define GET_STUN_ERR_RESP(msg_type) (msg_type | 0x0110) +#define GET_STUN_REQUEST(msg_type) (msg_type & 0xFEEF) +#define GET_STUN_INDICATION(msg_type) ((msg_type & 0xFEEF) | 0x0010) +#define GET_STUN_SUCCESS_RESP(msg_type) ((msg_type & 0xFEEF) | 0x0100) +#define GET_STUN_ERR_RESP(msg_type) (msg_type | 0x0110) /* Lifetimes: */ #define STUN_DEFAULT_ALLOCATE_LIFETIME (600) @@ -130,7 +130,7 @@ #define STUN_ATTRIBUTE_CONNECTION_ID (0x002A) /* <<== RFC 6062 */ -#define STUN_VALID_CHANNEL(chn) ((chn)>=0x4000 && (chn)<=0x7FFF) +#define STUN_VALID_CHANNEL(chn) ((chn) >= 0x4000 && (chn) <= 0x7FFF) ///////// extra values ////////////////// @@ -158,30 +158,32 @@ #define MAXSHASIZE (128) enum _SHATYPE { - SHATYPE_ERROR = -1, - SHATYPE_DEFAULT=0, - SHATYPE_SHA1=SHATYPE_DEFAULT, - SHATYPE_SHA256, - SHATYPE_SHA384, - SHATYPE_SHA512 + SHATYPE_ERROR = -1, + SHATYPE_DEFAULT = 0, + SHATYPE_SHA1 = SHATYPE_DEFAULT, + SHATYPE_SHA256, + SHATYPE_SHA384, + SHATYPE_SHA512 }; typedef enum _SHATYPE SHATYPE; -#define shatype_name(sht) ((sht == SHATYPE_SHA1) ? "SHA1" : ((sht == SHATYPE_SHA256) ? "SHA256" : ((sht == SHATYPE_SHA384) ? "SHA384" : "SHA512"))) +#define shatype_name(sht) \ + ((sht == SHATYPE_SHA1) ? "SHA1" \ + : ((sht == SHATYPE_SHA256) ? "SHA256" : ((sht == SHATYPE_SHA384) ? "SHA384" : "SHA512"))) /* <<== SHA */ /* OAUTH TOKEN ENC ALG ==> */ enum _ENC_ALG { - ENC_ALG_ERROR=-1, + ENC_ALG_ERROR = -1, #if !defined(TURN_NO_GCM) - ENC_ALG_DEFAULT=0, - A256GCM=ENC_ALG_DEFAULT, - A128GCM, + ENC_ALG_DEFAULT = 0, + A256GCM = ENC_ALG_DEFAULT, + A128GCM, #endif - ENC_ALG_NUM + ENC_ALG_NUM }; typedef enum _ENC_ALG ENC_ALG; @@ -210,44 +212,44 @@ typedef enum _ENC_ALG ENC_ALG; #define OAUTH_TIME_DELTA (5) struct _oauth_key_data { - char kid[OAUTH_KID_SIZE+1]; - char ikm_key[OAUTH_KEY_SIZE+1]; - size_t ikm_key_size; - turn_time_t timestamp; - turn_time_t lifetime; - char as_rs_alg[OAUTH_ALG_SIZE+1]; + char kid[OAUTH_KID_SIZE + 1]; + char ikm_key[OAUTH_KEY_SIZE + 1]; + size_t ikm_key_size; + turn_time_t timestamp; + turn_time_t lifetime; + char as_rs_alg[OAUTH_ALG_SIZE + 1]; }; typedef struct _oauth_key_data oauth_key_data; struct _oauth_key { - char kid[OAUTH_KID_SIZE+1]; - char ikm_key[OAUTH_KEY_SIZE+1]; - size_t ikm_key_size; - turn_time_t timestamp; - turn_time_t lifetime; - ENC_ALG as_rs_alg; - char as_rs_key[OAUTH_KEY_SIZE+1]; - size_t as_rs_key_size; - char auth_key[OAUTH_KEY_SIZE+1]; - size_t auth_key_size; + char kid[OAUTH_KID_SIZE + 1]; + char ikm_key[OAUTH_KEY_SIZE + 1]; + size_t ikm_key_size; + turn_time_t timestamp; + turn_time_t lifetime; + ENC_ALG as_rs_alg; + char as_rs_key[OAUTH_KEY_SIZE + 1]; + size_t as_rs_key_size; + char auth_key[OAUTH_KEY_SIZE + 1]; + size_t auth_key_size; }; typedef struct _oauth_key oauth_key; struct _oauth_encrypted_block { - uint16_t nonce_length; - uint8_t nonce[OAUTH_MAX_NONCE_SIZE]; - uint16_t key_length; - uint8_t mac_key[MAXSHASIZE]; - uint64_t timestamp; - uint32_t lifetime; + uint16_t nonce_length; + uint8_t nonce[OAUTH_MAX_NONCE_SIZE]; + uint16_t key_length; + uint8_t mac_key[MAXSHASIZE]; + uint64_t timestamp; + uint32_t lifetime; }; typedef struct _oauth_encrypted_block oauth_encrypted_block; struct _oauth_token { - oauth_encrypted_block enc_block; + oauth_encrypted_block enc_block; }; typedef struct _oauth_token oauth_token; @@ -255,8 +257,8 @@ typedef struct _oauth_token oauth_token; #define MAX_ENCODED_OAUTH_TOKEN_SIZE (1024) struct _encoded_oauth_token { - char token[MAX_ENCODED_OAUTH_TOKEN_SIZE]; - size_t size; + char token[MAX_ENCODED_OAUTH_TOKEN_SIZE]; + size_t size; }; typedef struct _encoded_oauth_token encoded_oauth_token; diff --git a/src/ns_turn_defs.h b/src/ns_turn_defs.h index eacf736..96bfd3d 100644 --- a/src/ns_turn_defs.h +++ b/src/ns_turn_defs.h @@ -44,29 +44,29 @@ #endif #if defined(WINDOWS) -#include -#include #include +#include +#include #else -#include -#include -#include #include #include +#include +#include #include +#include #include #endif -#include #include +#include +#include +#include #include #include #include #include -#include +#include #include -#include -#include #ifdef __cplusplus extern "C" { @@ -76,22 +76,21 @@ extern "C" { #define nswap32(ul) ntohl(ul) #define nswap64(ull) ioa_ntoh64(ull) -static inline uint64_t _ioa_ntoh64(uint64_t v) -{ +static inline uint64_t _ioa_ntoh64(uint64_t v) { #if BYTE_ORDER == LITTLE_ENDIAN - uint8_t *src = (uint8_t*) &v; - uint8_t* dst = src + 7; - while (src < dst) { - uint8_t vdst = *dst; - *(dst--) = *src; - *(src++) = vdst; - } + uint8_t *src = (uint8_t *)&v; + uint8_t *dst = src + 7; + while (src < dst) { + uint8_t vdst = *dst; + *(dst--) = *src; + *(src++) = vdst; + } #elif BYTE_ORDER == BIG_ENDIAN - /* OK */ + /* OK */ #else #error WRONG BYTE_ORDER SETTING #endif - return v; + return v; } /* TTL */ @@ -105,24 +104,35 @@ static inline uint64_t _ioa_ntoh64(uint64_t v) #define ioa_ntoh64 _ioa_ntoh64 #define ioa_hton64 _ioa_ntoh64 -#define BUFFEREVENT_FREE(be) do { if(be) { bufferevent_flush(be,EV_READ|EV_WRITE,BEV_FLUSH); bufferevent_disable(be,EV_READ|EV_WRITE); bufferevent_free(be); be = NULL;} } while(0) +#define BUFFEREVENT_FREE(be) \ + do { \ + if (be) { \ + bufferevent_flush(be, EV_READ | EV_WRITE, BEV_FLUSH); \ + bufferevent_disable(be, EV_READ | EV_WRITE); \ + bufferevent_free(be); \ + be = NULL; \ + } \ + } while (0) #define turn_time() ((turn_time_t)time(NULL)) typedef int vint; -typedef vint* vintp; +typedef vint *vintp; typedef uint32_t turn_time_t; -#define turn_time_before(t1,t2) ((((int32_t)(t1))-((int32_t)(t2))) < 0) +#define turn_time_before(t1, t2) ((((int32_t)(t1)) - ((int32_t)(t2))) < 0) #if !defined(UNUSED_ARG) -#define UNUSED_ARG(A) do { A=A; } while(0) +#define UNUSED_ARG(A) \ + do { \ + A = A; \ + } while (0) #endif #define MAX_STUN_MESSAGE_SIZE (65507) #define STUN_BUFFER_SIZE (MAX_STUN_MESSAGE_SIZE) -#define UDP_STUN_BUFFER_SIZE (1024<<4) +#define UDP_STUN_BUFFER_SIZE (1024 << 4) #define NONCE_LENGTH_32BITS (4) @@ -137,16 +147,18 @@ typedef uint32_t turn_time_t; #error WRONG BYTE_ORDER SETTING #endif -#define STRCPY(dst,src) \ - do { if((const char*)(dst) != (const char*)(src)) { \ - if(sizeof(dst)==sizeof(char*))\ - strcpy(((char*)(dst)),(const char*)(src));\ - else {\ - size_t szdst = sizeof((dst));\ - strncpy((char*)(dst),(const char*)(src),szdst);\ - ((char*)(dst))[szdst-1] = 0;\ - }\ - } } while(0) +#define STRCPY(dst, src) \ + do { \ + if ((const char *)(dst) != (const char *)(src)) { \ + if (sizeof(dst) == sizeof(char *)) \ + strcpy(((char *)(dst)), (const char *)(src)); \ + else { \ + size_t szdst = sizeof((dst)); \ + strncpy((char *)(dst), (const char *)(src), szdst); \ + ((char *)(dst))[szdst - 1] = 0; \ + } \ + } \ + } while (0) //////////////// Bufferevents ///////////////////// @@ -155,11 +167,13 @@ typedef uint32_t turn_time_t; //////////////// KERNEL-LEVEL CHANNEL HANDLERS ///////// #if !defined(TURN_CHANNEL_HANDLER_KERNEL) -#define TURN_CHANNEL_HANDLER_KERNEL void* +#define TURN_CHANNEL_HANDLER_KERNEL void * #endif #if !defined(CREATE_TURN_CHANNEL_KERNEL) -#define CREATE_TURN_CHANNEL_KERNEL(channel_number, address_family_client, address_family_peer, protocol_client, client_addr, local_addr, local_relay_addr, peer_addr) ((TURN_CHANNEL_HANDLER_KERNEL)(1)) +#define CREATE_TURN_CHANNEL_KERNEL(channel_number, address_family_client, address_family_peer, protocol_client, \ + client_addr, local_addr, local_relay_addr, peer_addr) \ + ((TURN_CHANNEL_HANDLER_KERNEL)(1)) #endif #if !defined(DELETE_TURN_CHANNEL_KERNEL) @@ -200,5 +214,5 @@ typedef uint32_t turn_time_t; } #endif -#endif +#endif /* __IODEFS__ */ diff --git a/src/server/ns_turn_allocation.c b/src/server/ns_turn_allocation.c index d9512b0..0e87f69 100644 --- a/src/server/ns_turn_allocation.c +++ b/src/server/ns_turn_allocation.c @@ -35,12 +35,12 @@ static void init_turn_permission_hashtable(turn_permission_hashtable *map); static void free_turn_permission_hashtable(turn_permission_hashtable *map); -static turn_permission_info* get_from_turn_permission_hashtable(turn_permission_hashtable *map, const ioa_addr *addr); +static turn_permission_info *get_from_turn_permission_hashtable(turn_permission_hashtable *map, const ioa_addr *addr); /////////////// ALLOCATION ////////////////////////////////////// -void init_allocation(void *owner, allocation* a, ur_map *tcp_connections) { - if(a) { +void init_allocation(void *owner, allocation *a, ur_map *tcp_connections) { + if (a) { memset(a, 0, sizeof(allocation)); a->owner = owner; a->tcp_connections = tcp_connections; @@ -48,118 +48,114 @@ void init_allocation(void *owner, allocation* a, ur_map *tcp_connections) { } } -void clear_allocation(allocation *a, SOCKET_TYPE socket_type) -{ - if (a) { +void clear_allocation(allocation *a, SOCKET_TYPE socket_type) { + if (a) { - if(a->is_valid) - turn_report_allocation_delete(a, socket_type); + if (a->is_valid) + turn_report_allocation_delete(a, socket_type); - if(a->tcs.elems) { - size_t i; - size_t sz = a->tcs.sz; - for(i=0;itcs.elems[i]; - if(tc) { - delete_tcp_connection(tc); - a->tcs.elems[i] = NULL; - } - } - free(a->tcs.elems); - a->tcs.elems = NULL; - } - a->tcs.sz = 0; + if (a->tcs.elems) { + size_t i; + size_t sz = a->tcs.sz; + for (i = 0; i < sz; ++i) { + tcp_connection *tc = a->tcs.elems[i]; + if (tc) { + delete_tcp_connection(tc); + a->tcs.elems[i] = NULL; + } + } + free(a->tcs.elems); + a->tcs.elems = NULL; + } + a->tcs.sz = 0; - { - int i; - for(i = 0;irelay_sessions[i].s, a->owner); - clear_relay_endpoint_session_data(&(a->relay_sessions[i])); - IOA_EVENT_DEL(a->relay_sessions[i].lifetime_ev); - } - } + { + int i; + for (i = 0; i < ALLOC_PROTOCOLS_NUMBER; ++i) { + clear_ioa_socket_session_if(a->relay_sessions[i].s, a->owner); + clear_relay_endpoint_session_data(&(a->relay_sessions[i])); + IOA_EVENT_DEL(a->relay_sessions[i].lifetime_ev); + } + } - /* The order is important here: */ - free_turn_permission_hashtable(&(a->addr_to_perm)); - ch_map_clean(&(a->chns)); + /* The order is important here: */ + free_turn_permission_hashtable(&(a->addr_to_perm)); + ch_map_clean(&(a->chns)); - a->is_valid=0; - } + a->is_valid = 0; + } } -relay_endpoint_session *get_relay_session(allocation *a, int family) -{ - if(a) - return &(a->relay_sessions[ALLOC_INDEX(family)]); - return NULL; +relay_endpoint_session *get_relay_session(allocation *a, int family) { + if (a) + return &(a->relay_sessions[ALLOC_INDEX(family)]); + return NULL; } -int get_relay_session_failure(allocation *a, int family) -{ - if(a) - return a->relay_sessions_failure[ALLOC_INDEX(family)]; - return 0; +int get_relay_session_failure(allocation *a, int family) { + if (a) + return a->relay_sessions_failure[ALLOC_INDEX(family)]; + return 0; } -void set_relay_session_failure(allocation *a, int family) -{ - if(a) - a->relay_sessions_failure[ALLOC_INDEX(family)] = 1; +void set_relay_session_failure(allocation *a, int family) { + if (a) + a->relay_sessions_failure[ALLOC_INDEX(family)] = 1; } -ioa_socket_handle get_relay_socket(allocation *a, int family) -{ - if(a) - return a->relay_sessions[ALLOC_INDEX(family)].s; - return NULL; +ioa_socket_handle get_relay_socket(allocation *a, int family) { + if (a) + return a->relay_sessions[ALLOC_INDEX(family)].s; + return NULL; } -void set_allocation_family_invalid(allocation *a, int family) -{ - if(a) { - size_t index = ALLOC_INDEX(family); - if(a->relay_sessions[index].s) { - if(a->tcs.elems) { - size_t i; - size_t sz = a->tcs.sz; - for(i=0;itcs.elems[i]; - if(tc) { - if(tc->peer_s && (get_ioa_socket_address_family(tc->peer_s) == family)) { - delete_tcp_connection(tc); - a->tcs.elems[i] = NULL; - } - } - } - } +void set_allocation_family_invalid(allocation *a, int family) { + if (a) { + size_t index = ALLOC_INDEX(family); + if (a->relay_sessions[index].s) { + if (a->tcs.elems) { + size_t i; + size_t sz = a->tcs.sz; + for (i = 0; i < sz; ++i) { + tcp_connection *tc = a->tcs.elems[i]; + if (tc) { + if (tc->peer_s && (get_ioa_socket_address_family(tc->peer_s) == family)) { + delete_tcp_connection(tc); + a->tcs.elems[i] = NULL; + } + } + } + } - clear_ioa_socket_session_if(a->relay_sessions[index].s, a->owner); - clear_relay_endpoint_session_data(&(a->relay_sessions[index])); - IOA_EVENT_DEL(a->relay_sessions[index].lifetime_ev); - } - } + clear_ioa_socket_session_if(a->relay_sessions[index].s, a->owner); + clear_relay_endpoint_session_data(&(a->relay_sessions[index])); + IOA_EVENT_DEL(a->relay_sessions[index].lifetime_ev); + } + } } -void set_allocation_lifetime_ev(allocation *a, turn_time_t exp_time, ioa_timer_handle ev, int family) -{ - if (a) { - IOA_EVENT_DEL(a->relay_sessions[ALLOC_INDEX(family)].lifetime_ev); - a->relay_sessions[ALLOC_INDEX(family)].expiration_time = exp_time; - a->relay_sessions[ALLOC_INDEX(family)].lifetime_ev = ev; - } +void set_allocation_lifetime_ev(allocation *a, turn_time_t exp_time, ioa_timer_handle ev, int family) { + if (a) { + IOA_EVENT_DEL(a->relay_sessions[ALLOC_INDEX(family)].lifetime_ev); + a->relay_sessions[ALLOC_INDEX(family)].expiration_time = exp_time; + a->relay_sessions[ALLOC_INDEX(family)].lifetime_ev = ev; + } } -int is_allocation_valid(const allocation* a) { - if(a) return a->is_valid; - else return 0; +int is_allocation_valid(const allocation *a) { + if (a) + return a->is_valid; + else + return 0; } -void set_allocation_valid(allocation* a, int value) { - if(a) a->is_valid=value; +void set_allocation_valid(allocation *a, int value) { + if (a) + a->is_valid = value; } -turn_permission_info* allocation_get_permission(allocation* a, const ioa_addr *addr) { - if(a) { +turn_permission_info *allocation_get_permission(allocation *a, const ioa_addr *addr) { + if (a) { return get_from_turn_permission_hashtable(&(a->addr_to_perm), addr); } return NULL; @@ -169,592 +165,568 @@ turn_permission_info* allocation_get_permission(allocation* a, const ioa_addr *a static int delete_channel_info_from_allocation_map(ur_map_key_type key, ur_map_value_type value); -void turn_permission_clean(turn_permission_info* tinfo) -{ - if (tinfo && tinfo->allocated) { +void turn_permission_clean(turn_permission_info *tinfo) { + if (tinfo && tinfo->allocated) { - if(tinfo->verbose) { - char s[257]="\0"; - addr_to_string(&(tinfo->addr),(uint8_t*)s); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "session %018llu: peer %s deleted\n",tinfo->session_id,s); - } + if (tinfo->verbose) { + char s[257] = "\0"; + addr_to_string(&(tinfo->addr), (uint8_t *)s); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "session %018llu: peer %s deleted\n", tinfo->session_id, s); + } - if(!(tinfo->lifetime_ev)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: strange (1) permission to be cleaned\n",__FUNCTION__); - } + if (!(tinfo->lifetime_ev)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: strange (1) permission to be cleaned\n", __FUNCTION__); + } - IOA_EVENT_DEL(tinfo->lifetime_ev); - lm_map_foreach(&(tinfo->chns), (foreachcb_type) delete_channel_info_from_allocation_map); - lm_map_clean(&(tinfo->chns)); - memset(tinfo, 0, sizeof(turn_permission_info)); - } + IOA_EVENT_DEL(tinfo->lifetime_ev); + lm_map_foreach(&(tinfo->chns), (foreachcb_type)delete_channel_info_from_allocation_map); + lm_map_clean(&(tinfo->chns)); + memset(tinfo, 0, sizeof(turn_permission_info)); + } } -static void init_turn_permission_hashtable(turn_permission_hashtable *map) -{ - if (map) - memset(map, 0, sizeof(turn_permission_hashtable)); +static void init_turn_permission_hashtable(turn_permission_hashtable *map) { + if (map) + memset(map, 0, sizeof(turn_permission_hashtable)); } -static void free_turn_permission_hashtable(turn_permission_hashtable *map) -{ - if(map) { +static void free_turn_permission_hashtable(turn_permission_hashtable *map) { + if (map) { - size_t i; - for(i=0;itable[i]); + turn_permission_array *parray = &(map->table[i]); - { - size_t j; - for(j=0;jmain_slots[j]); - if(slot->info.allocated) { - turn_permission_clean(&(slot->info)); - } - } - } + { + size_t j; + for (j = 0; j < TURN_PERMISSION_ARRAY_SIZE; ++j) { + turn_permission_slot *slot = &(parray->main_slots[j]); + if (slot->info.allocated) { + turn_permission_clean(&(slot->info)); + } + } + } - if(parray->extra_slots) { - size_t j; - for(j=0;jextra_sz;++j) { - turn_permission_slot *slot = parray->extra_slots[j]; - if(slot) { - if(slot->info.allocated) { - turn_permission_clean(&(slot->info)); - } - free(slot); - } - } - free(parray->extra_slots); - parray->extra_slots = NULL; - } - parray->extra_sz = 0; - } - } + if (parray->extra_slots) { + size_t j; + for (j = 0; j < parray->extra_sz; ++j) { + turn_permission_slot *slot = parray->extra_slots[j]; + if (slot) { + if (slot->info.allocated) { + turn_permission_clean(&(slot->info)); + } + free(slot); + } + } + free(parray->extra_slots); + parray->extra_slots = NULL; + } + parray->extra_sz = 0; + } + } } -static turn_permission_info* get_from_turn_permission_hashtable(turn_permission_hashtable *map, const ioa_addr *addr) -{ - if (!addr || !map) - return NULL; +static turn_permission_info *get_from_turn_permission_hashtable(turn_permission_hashtable *map, const ioa_addr *addr) { + if (!addr || !map) + return NULL; - uint32_t index = addr_hash_no_port(addr) & (TURN_PERMISSION_HASHTABLE_SIZE-1); - turn_permission_array *parray = &(map->table[index]); + uint32_t index = addr_hash_no_port(addr) & (TURN_PERMISSION_HASHTABLE_SIZE - 1); + turn_permission_array *parray = &(map->table[index]); - { - size_t i; - for (i = 0; i < TURN_PERMISSION_ARRAY_SIZE; ++i) { - turn_permission_slot *slot = &(parray->main_slots[i]); - if (slot->info.allocated && addr_eq_no_port(&(slot->info.addr), addr)) { - return &(slot->info); - } - } - } + { + size_t i; + for (i = 0; i < TURN_PERMISSION_ARRAY_SIZE; ++i) { + turn_permission_slot *slot = &(parray->main_slots[i]); + if (slot->info.allocated && addr_eq_no_port(&(slot->info.addr), addr)) { + return &(slot->info); + } + } + } - if(parray->extra_slots) { + if (parray->extra_slots) { - size_t i; - size_t sz = parray->extra_sz; - for (i = 0; i < sz; ++i) { - turn_permission_slot *slot = parray->extra_slots[i]; - if (slot->info.allocated && addr_eq_no_port(&(slot->info.addr), addr)) { - return &(slot->info); - } - } - } + size_t i; + size_t sz = parray->extra_sz; + for (i = 0; i < sz; ++i) { + turn_permission_slot *slot = parray->extra_slots[i]; + if (slot->info.allocated && addr_eq_no_port(&(slot->info.addr), addr)) { + return &(slot->info); + } + } + } - return NULL; + return NULL; } -static void ch_info_clean(ch_info* c) { +static void ch_info_clean(ch_info *c) { if (c) { - if (c->kernel_channel) { - DELETE_TURN_CHANNEL_KERNEL(c->kernel_channel); - c->kernel_channel = 0; - } - IOA_EVENT_DEL(c->lifetime_ev); - memset(c, 0, sizeof(ch_info)); - } + if (c->kernel_channel) { + DELETE_TURN_CHANNEL_KERNEL(c->kernel_channel); + c->kernel_channel = 0; + } + IOA_EVENT_DEL(c->lifetime_ev); + memset(c, 0, sizeof(ch_info)); + } } -static int delete_channel_info_from_allocation_map(ur_map_key_type key, ur_map_value_type value) -{ - UNUSED_ARG(key); +static int delete_channel_info_from_allocation_map(ur_map_key_type key, ur_map_value_type value) { + UNUSED_ARG(key); - if(value) { - ch_info* chn = (ch_info*)value; + if (value) { + ch_info *chn = (ch_info *)value; - if(chn->chnum <1) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: strange (0) channel to be cleaned: chnum<1\n",__FUNCTION__); - } + if (chn->chnum < 1) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: strange (0) channel to be cleaned: chnum<1\n", __FUNCTION__); + } - ch_info_clean(chn); - } + ch_info_clean(chn); + } - return 0; + return 0; } -void turn_channel_delete(ch_info* chn) -{ - if(chn) { - int port = addr_get_port(&(chn->peer_addr)); - if(port<1) { - char s[129]; - addr_to_string(&(chn->peer_addr),(uint8_t*)s); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: strange (1) channel to be cleaned: port is empty: %s\n",__FUNCTION__,s); - } - { - turn_permission_info* tinfo = (turn_permission_info*)chn->owner; - if(tinfo) { - lm_map_del(&(tinfo->chns), (ur_map_key_type)port,NULL); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: strange (2) channel to be cleaned: permission is empty\n",__FUNCTION__); - } - } - delete_channel_info_from_allocation_map((ur_map_key_type)port,(ur_map_value_type)chn); - } +void turn_channel_delete(ch_info *chn) { + if (chn) { + int port = addr_get_port(&(chn->peer_addr)); + if (port < 1) { + char s[129]; + addr_to_string(&(chn->peer_addr), (uint8_t *)s); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: strange (1) channel to be cleaned: port is empty: %s\n", + __FUNCTION__, s); + } + { + turn_permission_info *tinfo = (turn_permission_info *)chn->owner; + if (tinfo) { + lm_map_del(&(tinfo->chns), (ur_map_key_type)port, NULL); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: strange (2) channel to be cleaned: permission is empty\n", + __FUNCTION__); + } + } + delete_channel_info_from_allocation_map((ur_map_key_type)port, (ur_map_value_type)chn); + } } -ch_info* allocation_get_new_ch_info(allocation* a, uint16_t chnum, ioa_addr* peer_addr) -{ +ch_info *allocation_get_new_ch_info(allocation *a, uint16_t chnum, ioa_addr *peer_addr) { - turn_permission_info* tinfo = get_from_turn_permission_hashtable(&(a->addr_to_perm), peer_addr); + turn_permission_info *tinfo = get_from_turn_permission_hashtable(&(a->addr_to_perm), peer_addr); - if (!tinfo) - tinfo = allocation_add_permission(a, peer_addr); + if (!tinfo) + tinfo = allocation_add_permission(a, peer_addr); - ch_info* chn = ch_map_get(&(a->chns), chnum, 1); + ch_info *chn = ch_map_get(&(a->chns), chnum, 1); - chn->allocated = 1; - chn->chnum = chnum; - chn->port = addr_get_port(peer_addr); - addr_cpy(&(chn->peer_addr), peer_addr); - chn->owner = tinfo; + chn->allocated = 1; + chn->chnum = chnum; + chn->port = addr_get_port(peer_addr); + addr_cpy(&(chn->peer_addr), peer_addr); + chn->owner = tinfo; - lm_map_put(&(tinfo->chns), (ur_map_key_type) addr_get_port(peer_addr), (ur_map_value_type) chn); + lm_map_put(&(tinfo->chns), (ur_map_key_type)addr_get_port(peer_addr), (ur_map_value_type)chn); - return chn; + return chn; } -ch_info* allocation_get_ch_info(allocation* a, uint16_t chnum) { - return ch_map_get(&(a->chns), chnum, 0); +ch_info *allocation_get_ch_info(allocation *a, uint16_t chnum) { return ch_map_get(&(a->chns), chnum, 0); } + +ch_info *allocation_get_ch_info_by_peer_addr(allocation *a, ioa_addr *peer_addr) { + turn_permission_info *tinfo = get_from_turn_permission_hashtable(&(a->addr_to_perm), peer_addr); + if (tinfo) { + return get_turn_channel(tinfo, peer_addr); + } + return NULL; } -ch_info* allocation_get_ch_info_by_peer_addr(allocation* a, ioa_addr* peer_addr) { - turn_permission_info* tinfo = get_from_turn_permission_hashtable(&(a->addr_to_perm), peer_addr); - if(tinfo) { - return get_turn_channel(tinfo,peer_addr); - } - return NULL; +uint16_t get_turn_channel_number(turn_permission_info *tinfo, ioa_addr *addr) { + if (tinfo) { + ur_map_value_type t = 0; + if (lm_map_get(&(tinfo->chns), (ur_map_key_type)addr_get_port(addr), &t) && t) { + ch_info *chn = (ch_info *)t; + if (STUN_VALID_CHANNEL(chn->chnum)) { + return chn->chnum; + } + } + } + + return 0; } -uint16_t get_turn_channel_number(turn_permission_info* tinfo, ioa_addr *addr) -{ - if (tinfo) { - ur_map_value_type t = 0; - if (lm_map_get(&(tinfo->chns), (ur_map_key_type)addr_get_port(addr), &t) && t) { - ch_info* chn = (ch_info*) t; - if (STUN_VALID_CHANNEL(chn->chnum)) { - return chn->chnum; - } - } - } +ch_info *get_turn_channel(turn_permission_info *tinfo, ioa_addr *addr) { + if (tinfo) { + ur_map_value_type t = 0; + if (lm_map_get(&(tinfo->chns), (ur_map_key_type)addr_get_port(addr), &t) && t) { + ch_info *chn = (ch_info *)t; + if (STUN_VALID_CHANNEL(chn->chnum)) { + return chn; + } + } + } - return 0; + return NULL; } -ch_info *get_turn_channel(turn_permission_info* tinfo, ioa_addr *addr) -{ - if (tinfo) { - ur_map_value_type t = 0; - if (lm_map_get(&(tinfo->chns), (ur_map_key_type)addr_get_port(addr), &t) && t) { - ch_info* chn = (ch_info*) t; - if (STUN_VALID_CHANNEL(chn->chnum)) { - return chn; - } - } - } +turn_permission_hashtable *allocation_get_turn_permission_hashtable(allocation *a) { return &(a->addr_to_perm); } - return NULL; +turn_permission_info *allocation_add_permission(allocation *a, const ioa_addr *addr) { + if (a && addr) { + + turn_permission_hashtable *map = &(a->addr_to_perm); + uint32_t hash = addr_hash_no_port(addr); + size_t fds = (size_t)(hash & (TURN_PERMISSION_HASHTABLE_SIZE - 1)); + + turn_permission_array *parray = &(map->table[fds]); + + turn_permission_slot *slot = NULL; + + { + size_t i; + for (i = 0; i < TURN_PERMISSION_ARRAY_SIZE; ++i) { + slot = &(parray->main_slots[i]); + if (!(slot->info.allocated)) { + break; + } else { + slot = NULL; + } + } + } + + if (!slot) { + + size_t old_sz = parray->extra_sz; + + turn_permission_slot **slots = parray->extra_slots; + + if (slots) { + size_t i; + for (i = 0; i < old_sz; ++i) { + slot = slots[i]; + if (!(slot->info.allocated)) { + break; + } else { + slot = NULL; + } + } + } + + if (!slot) { + size_t old_sz_mem = old_sz * sizeof(turn_permission_slot *); + parray->extra_slots = + (turn_permission_slot **)realloc(parray->extra_slots, old_sz_mem + sizeof(turn_permission_slot *)); + slots = parray->extra_slots; + parray->extra_sz = old_sz + 1; + slots[old_sz] = (turn_permission_slot *)malloc(sizeof(turn_permission_slot)); + slot = slots[old_sz]; + } + } + + memset(slot, 0, sizeof(turn_permission_slot)); + slot->info.allocated = 1; + turn_permission_info *elem = &(slot->info); + addr_cpy(&(elem->addr), addr); + elem->owner = a; + + return elem; + } else { + return NULL; + } } -turn_permission_hashtable *allocation_get_turn_permission_hashtable(allocation *a) -{ - return &(a->addr_to_perm); +ch_info *ch_map_get(ch_map *map, uint16_t chnum, int new_chn) { + ch_info *ret = NULL; + if (map) { + size_t index = (size_t)(chnum & (CH_MAP_HASH_SIZE - 1)); + ch_map_array *a = &(map->table[index]); + + size_t i; + for (i = 0; i < CH_MAP_ARRAY_SIZE; ++i) { + ch_info *chi = &(a->main_chns[i]); + if (chi->allocated) { + if (!new_chn && (chi->chnum == chnum)) { + return chi; + } + } else if (new_chn) { + return chi; + } + } + + size_t old_sz = a->extra_sz; + if (old_sz && a->extra_chns) { + for (i = 0; i < old_sz; ++i) { + ch_info *chi = a->extra_chns[i]; + if (chi) { + if (chi->allocated) { + if (!new_chn && (chi->chnum == chnum)) { + return chi; + } + } else if (new_chn) { + return chi; + } + } + } + } + + if (new_chn) { + size_t old_sz_mem = old_sz * sizeof(ch_info *); + a->extra_chns = (ch_info **)realloc(a->extra_chns, old_sz_mem + sizeof(ch_info *)); + a->extra_chns[old_sz] = (ch_info *)calloc(sizeof(ch_info), 1); + a->extra_sz += 1; + + return a->extra_chns[old_sz]; + } + } + + return ret; } -turn_permission_info* allocation_add_permission(allocation *a, const ioa_addr* addr) -{ - if (a && addr) { +void ch_map_clean(ch_map *map) { + if (map) { + size_t index; + for (index = 0; index < CH_MAP_HASH_SIZE; ++index) { - turn_permission_hashtable *map = &(a->addr_to_perm); - uint32_t hash = addr_hash_no_port(addr); - size_t fds = (size_t) (hash & (TURN_PERMISSION_HASHTABLE_SIZE-1)); + ch_map_array *a = &(map->table[index]); - turn_permission_array *parray = &(map->table[fds]); + size_t i; + for (i = 0; i < CH_MAP_ARRAY_SIZE; ++i) { + ch_info *chi = &(a->main_chns[i]); + if (chi->allocated) { + ch_info_clean(chi); + } + } - turn_permission_slot *slot = NULL; - - { - size_t i; - for(i=0;imain_slots[i]); - if(!(slot->info.allocated)) { - break; - } else { - slot=NULL; - } - } - } - - if(!slot) { - - size_t old_sz = parray->extra_sz; - - turn_permission_slot **slots = parray->extra_slots; - - if(slots) { - size_t i; - for(i=0;iinfo.allocated)) { - break; - } else { - slot=NULL; - } - } - } - - if(!slot) { - size_t old_sz_mem = old_sz * sizeof(turn_permission_slot*); - parray->extra_slots = (turn_permission_slot **) realloc(parray->extra_slots, - old_sz_mem + sizeof(turn_permission_slot*)); - slots = parray->extra_slots; - parray->extra_sz = old_sz + 1; - slots[old_sz] = (turn_permission_slot *)malloc(sizeof(turn_permission_slot)); - slot = slots[old_sz]; - } - } - - memset(slot, 0, sizeof(turn_permission_slot)); - slot->info.allocated = 1; - turn_permission_info *elem = &(slot->info); - addr_cpy(&(elem->addr), addr); - elem->owner = a; - - return elem; - } else { - return NULL; - } -} - -ch_info *ch_map_get(ch_map* map, uint16_t chnum, int new_chn) -{ - ch_info *ret = NULL; - if(map) { - size_t index = (size_t)(chnum & (CH_MAP_HASH_SIZE-1)); - ch_map_array *a = &(map->table[index]); - - size_t i; - for(i=0;imain_chns[i]); - if(chi->allocated) { - if(!new_chn && (chi->chnum == chnum)) { - return chi; - } - } else if(new_chn) { - return chi; - } - } - - size_t old_sz = a->extra_sz; - if(old_sz && a->extra_chns) { - for(i=0;iextra_chns[i]; - if(chi) { - if(chi->allocated) { - if(!new_chn && (chi->chnum == chnum)) { - return chi; - } - } else if(new_chn) { - return chi; - } - } - } - } - - if(new_chn) { - size_t old_sz_mem = old_sz * sizeof(ch_info*); - a->extra_chns = (ch_info**)realloc(a->extra_chns,old_sz_mem + sizeof(ch_info*)); - a->extra_chns[old_sz] = (ch_info*)calloc(sizeof(ch_info), 1); - a->extra_sz += 1; - - return a->extra_chns[old_sz]; - } - } - - return ret; -} - -void ch_map_clean(ch_map* map) -{ - if(map) { - size_t index; - for(index = 0; index < CH_MAP_HASH_SIZE; ++index) { - - ch_map_array *a = &(map->table[index]); - - size_t i; - for(i=0;imain_chns[i]); - if(chi->allocated) { - ch_info_clean(chi); - } - } - - if(a->extra_chns) { - size_t sz = a->extra_sz; - for(i=0;iextra_chns[i]; - if(chi) { - if(chi->allocated) { - ch_info_clean(chi); - } - free(chi); - a->extra_chns[i] = NULL; - } - } - free(a->extra_chns); - a->extra_chns = NULL; - } - a->extra_sz = 0; - } - } + if (a->extra_chns) { + size_t sz = a->extra_sz; + for (i = 0; i < sz; ++i) { + ch_info *chi = a->extra_chns[i]; + if (chi) { + if (chi->allocated) { + ch_info_clean(chi); + } + free(chi); + a->extra_chns[i] = NULL; + } + } + free(a->extra_chns); + a->extra_chns = NULL; + } + a->extra_sz = 0; + } + } } ////////////////// TCP connections /////////////////////////////// static void set_new_tc_id(uint8_t server_id, tcp_connection *tc) { - allocation *a = (allocation*)(tc->owner); - ur_map *map = a->tcp_connections; - uint32_t newid; - uint32_t sid = server_id; - sid = sid<<24; - do { - newid = 0; - while (!newid) { - newid = (uint32_t)turn_random(); - if(!newid) { - continue; - } - newid = newid & 0x00FFFFFF; - if(!newid) { - continue; - } - newid = newid | sid; - } - } while(ur_map_get(map, (ur_map_key_type)newid, NULL)); - tc->id = newid; - ur_map_put(map, (ur_map_key_type)newid, (ur_map_value_type)tc); + allocation *a = (allocation *)(tc->owner); + ur_map *map = a->tcp_connections; + uint32_t newid; + uint32_t sid = server_id; + sid = sid << 24; + do { + newid = 0; + while (!newid) { + newid = (uint32_t)turn_random(); + if (!newid) { + continue; + } + newid = newid & 0x00FFFFFF; + if (!newid) { + continue; + } + newid = newid | sid; + } + } while (ur_map_get(map, (ur_map_key_type)newid, NULL)); + tc->id = newid; + ur_map_put(map, (ur_map_key_type)newid, (ur_map_value_type)tc); } -tcp_connection *create_tcp_connection(uint8_t server_id, allocation *a, stun_tid *tid, ioa_addr *peer_addr, int *err_code) -{ - tcp_connection_list *tcl = &(a->tcs); - if(tcl->elems) { - size_t i; - for(i=0;isz;++i) { - tcp_connection *otc = tcl->elems[i]; - if(otc) { - if(addr_eq(&(otc->peer_addr),peer_addr)) { - *err_code = 446; - return NULL; - } - } - } - } - tcp_connection *tc = (tcp_connection*)calloc(sizeof(tcp_connection), 1); - addr_cpy(&(tc->peer_addr),peer_addr); - if(tid) - memcpy(&(tc->tid),tid,sizeof(stun_tid)); - tc->owner = a; +tcp_connection *create_tcp_connection(uint8_t server_id, allocation *a, stun_tid *tid, ioa_addr *peer_addr, + int *err_code) { + tcp_connection_list *tcl = &(a->tcs); + if (tcl->elems) { + size_t i; + for (i = 0; i < tcl->sz; ++i) { + tcp_connection *otc = tcl->elems[i]; + if (otc) { + if (addr_eq(&(otc->peer_addr), peer_addr)) { + *err_code = 446; + return NULL; + } + } + } + } + tcp_connection *tc = (tcp_connection *)calloc(sizeof(tcp_connection), 1); + addr_cpy(&(tc->peer_addr), peer_addr); + if (tid) + memcpy(&(tc->tid), tid, sizeof(stun_tid)); + tc->owner = a; - int found = 0; - if(a->tcs.elems) { - size_t i; - for(i=0;isz;++i) { - tcp_connection *otc = tcl->elems[i]; - if(!otc) { - tcl->elems[i] = tc; - found = 1; - break; - } - } - } + int found = 0; + if (a->tcs.elems) { + size_t i; + for (i = 0; i < tcl->sz; ++i) { + tcp_connection *otc = tcl->elems[i]; + if (!otc) { + tcl->elems[i] = tc; + found = 1; + break; + } + } + } - if(!found) { - size_t old_sz_mem = a->tcs.sz * sizeof(tcp_connection*); - a->tcs.elems = (tcp_connection**)realloc(a->tcs.elems,old_sz_mem+sizeof(tcp_connection*)); - a->tcs.elems[a->tcs.sz] = tc; - a->tcs.sz += 1; - tcl = &(a->tcs); - } + if (!found) { + size_t old_sz_mem = a->tcs.sz * sizeof(tcp_connection *); + a->tcs.elems = (tcp_connection **)realloc(a->tcs.elems, old_sz_mem + sizeof(tcp_connection *)); + a->tcs.elems[a->tcs.sz] = tc; + a->tcs.sz += 1; + tcl = &(a->tcs); + } - set_new_tc_id(server_id, tc); - return tc; + set_new_tc_id(server_id, tc); + return tc; } -void delete_tcp_connection(tcp_connection *tc) -{ - if(tc) { - if(tc->done) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s: check on already closed tcp data connection: 0x%lx\n",__FUNCTION__,(unsigned long)tc); - return; - } - tc->done = 1; +void delete_tcp_connection(tcp_connection *tc) { + if (tc) { + if (tc->done) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s: check on already closed tcp data connection: 0x%lx\n", __FUNCTION__, + (unsigned long)tc); + return; + } + tc->done = 1; - clear_unsent_buffer(&(tc->ub_to_client)); + clear_unsent_buffer(&(tc->ub_to_client)); - IOA_EVENT_DEL(tc->peer_conn_timeout); - IOA_EVENT_DEL(tc->conn_bind_timeout); - allocation *a = (allocation*)(tc->owner); - if(a) { - ur_map *map = a->tcp_connections; - if(map) { - ur_map_del(map, (ur_map_key_type)(tc->id),NULL); - } - tcp_connection_list *tcl = &(a->tcs); - if(tcl->elems) { - size_t i; - for(i=0;isz;++i) { - if(tcl->elems[i] == tc) { - tcl->elems[i] = NULL; - break; - } - } - } - } - IOA_CLOSE_SOCKET(tc->client_s); - IOA_CLOSE_SOCKET(tc->peer_s); - free(tc); - } + IOA_EVENT_DEL(tc->peer_conn_timeout); + IOA_EVENT_DEL(tc->conn_bind_timeout); + allocation *a = (allocation *)(tc->owner); + if (a) { + ur_map *map = a->tcp_connections; + if (map) { + ur_map_del(map, (ur_map_key_type)(tc->id), NULL); + } + tcp_connection_list *tcl = &(a->tcs); + if (tcl->elems) { + size_t i; + for (i = 0; i < tcl->sz; ++i) { + if (tcl->elems[i] == tc) { + tcl->elems[i] = NULL; + break; + } + } + } + } + IOA_CLOSE_SOCKET(tc->client_s); + IOA_CLOSE_SOCKET(tc->peer_s); + free(tc); + } } -tcp_connection *get_and_clean_tcp_connection_by_id(ur_map *map, tcp_connection_id id) -{ - if(map) { - ur_map_value_type t = 0; - if (ur_map_get(map, (ur_map_key_type)id, &t) && t) { - ur_map_del(map, (ur_map_key_type)id,NULL); - return (tcp_connection*)t; - } - } - return NULL; +tcp_connection *get_and_clean_tcp_connection_by_id(ur_map *map, tcp_connection_id id) { + if (map) { + ur_map_value_type t = 0; + if (ur_map_get(map, (ur_map_key_type)id, &t) && t) { + ur_map_del(map, (ur_map_key_type)id, NULL); + return (tcp_connection *)t; + } + } + return NULL; } -tcp_connection *get_tcp_connection_by_id(ur_map *map, tcp_connection_id id) -{ - if(map) { - ur_map_value_type t = 0; - if (ur_map_get(map, (ur_map_key_type)id, &t) && t) { - return (tcp_connection*)t; - } - } - return NULL; +tcp_connection *get_tcp_connection_by_id(ur_map *map, tcp_connection_id id) { + if (map) { + ur_map_value_type t = 0; + if (ur_map_get(map, (ur_map_key_type)id, &t) && t) { + return (tcp_connection *)t; + } + } + return NULL; } -tcp_connection *get_tcp_connection_by_peer(allocation *a, ioa_addr *peer_addr) -{ - if(a && peer_addr) { - tcp_connection_list *tcl = &(a->tcs); - if(tcl->elems) { - size_t i; - size_t sz = tcl->sz; - for(i=0;ielems[i]; - if(tc) { - if(addr_eq(&(tc->peer_addr),peer_addr)) { - return tc; - } - } - } - } - } - return NULL; +tcp_connection *get_tcp_connection_by_peer(allocation *a, ioa_addr *peer_addr) { + if (a && peer_addr) { + tcp_connection_list *tcl = &(a->tcs); + if (tcl->elems) { + size_t i; + size_t sz = tcl->sz; + for (i = 0; i < sz; ++i) { + tcp_connection *tc = tcl->elems[i]; + if (tc) { + if (addr_eq(&(tc->peer_addr), peer_addr)) { + return tc; + } + } + } + } + } + return NULL; } -int can_accept_tcp_connection_from_peer(allocation *a, ioa_addr *peer_addr, int server_relay) -{ - if(server_relay) - return 1; +int can_accept_tcp_connection_from_peer(allocation *a, ioa_addr *peer_addr, int server_relay) { + if (server_relay) + return 1; - if(a && peer_addr) { - return (get_from_turn_permission_hashtable(&(a->addr_to_perm), peer_addr) != NULL); - } + if (a && peer_addr) { + return (get_from_turn_permission_hashtable(&(a->addr_to_perm), peer_addr) != NULL); + } - return 0; + return 0; } //////////////// Unsent buffers ////////////////////// -void clear_unsent_buffer(unsent_buffer *ub) -{ - if(ub) { - if(ub->bufs) { - size_t sz; - for(sz = 0; szsz; sz++) { - ioa_network_buffer_handle nbh = ub->bufs[sz]; - if(nbh) { - ioa_network_buffer_delete(NULL, nbh); - ub->bufs[sz] = NULL; - } - } - free(ub->bufs); - ub->bufs = NULL; - } - ub->sz = 0; - } +void clear_unsent_buffer(unsent_buffer *ub) { + if (ub) { + if (ub->bufs) { + size_t sz; + for (sz = 0; sz < ub->sz; sz++) { + ioa_network_buffer_handle nbh = ub->bufs[sz]; + if (nbh) { + ioa_network_buffer_delete(NULL, nbh); + ub->bufs[sz] = NULL; + } + } + free(ub->bufs); + ub->bufs = NULL; + } + ub->sz = 0; + } } -void add_unsent_buffer(unsent_buffer *ub, ioa_network_buffer_handle nbh) -{ - if(!ub || (ub->sz >= MAX_UNSENT_BUFFER_SIZE)) { - ioa_network_buffer_delete(NULL, nbh); - } else { - ub->bufs = (ioa_network_buffer_handle*)realloc(ub->bufs, sizeof(ioa_network_buffer_handle) * (ub->sz+1)); - ub->bufs[ub->sz] = nbh; - ub->sz +=1; - } +void add_unsent_buffer(unsent_buffer *ub, ioa_network_buffer_handle nbh) { + if (!ub || (ub->sz >= MAX_UNSENT_BUFFER_SIZE)) { + ioa_network_buffer_delete(NULL, nbh); + } else { + ub->bufs = (ioa_network_buffer_handle *)realloc(ub->bufs, sizeof(ioa_network_buffer_handle) * (ub->sz + 1)); + ub->bufs[ub->sz] = nbh; + ub->sz += 1; + } } -ioa_network_buffer_handle top_unsent_buffer(unsent_buffer *ub) -{ - ioa_network_buffer_handle ret = NULL; - if(ub && ub->bufs && ub->sz) { - size_t sz; - for(sz=0; szsz; ++sz) { - if(ub->bufs[sz]) { - ret = ub->bufs[sz]; - break; - } - } - } - return ret; +ioa_network_buffer_handle top_unsent_buffer(unsent_buffer *ub) { + ioa_network_buffer_handle ret = NULL; + if (ub && ub->bufs && ub->sz) { + size_t sz; + for (sz = 0; sz < ub->sz; ++sz) { + if (ub->bufs[sz]) { + ret = ub->bufs[sz]; + break; + } + } + } + return ret; } -void pop_unsent_buffer(unsent_buffer *ub) -{ - if(ub && ub->bufs && ub->sz) { - size_t sz; - for(sz=0; szsz; ++sz) { - if(ub->bufs[sz]) { - ub->bufs[sz] = NULL; - break; - } - } - } +void pop_unsent_buffer(unsent_buffer *ub) { + if (ub && ub->bufs && ub->sz) { + size_t sz; + for (sz = 0; sz < ub->sz; ++sz) { + if (ub->bufs[sz]) { + ub->bufs[sz] = NULL; + break; + } + } + } } ////////////////////////////////////////////////////////////////// - diff --git a/src/server/ns_turn_allocation.h b/src/server/ns_turn_allocation.h index 2942ea3..bb5dea2 100644 --- a/src/server/ns_turn_allocation.h +++ b/src/server/ns_turn_allocation.h @@ -31,10 +31,10 @@ #ifndef __TURN_TURN_A_LIB__ #define __TURN_TURN_A_LIB__ -#include "ns_turn_utils.h" -#include "ns_turn_msg.h" #include "ns_turn_ioalib.h" #include "ns_turn_maps.h" +#include "ns_turn_msg.h" +#include "ns_turn_utils.h" #ifdef __cplusplus extern "C" { @@ -47,17 +47,15 @@ extern "C" { ////////////// Network session //////////////// -typedef struct -{ - ioa_socket_handle s; - turn_time_t expiration_time; - ioa_timer_handle lifetime_ev; +typedef struct { + ioa_socket_handle s; + turn_time_t expiration_time; + ioa_timer_handle lifetime_ev; } relay_endpoint_session; -static inline void clear_relay_endpoint_session_data(relay_endpoint_session* cdi) -{ - if (cdi) - IOA_CLOSE_SOCKET(cdi->s); +static inline void clear_relay_endpoint_session_data(relay_endpoint_session *cdi) { + if (cdi) + IOA_CLOSE_SOCKET(cdi->s); } ////////// RFC 6062 TCP connection //////// @@ -65,12 +63,12 @@ static inline void clear_relay_endpoint_session_data(relay_endpoint_session* cdi #define MAX_UNSENT_BUFFER_SIZE (0x10) enum _TC_STATE { - TC_STATE_UNKNOWN=0, - TC_STATE_CLIENT_TO_PEER_CONNECTING, - TC_STATE_PEER_CONNECTING, - TC_STATE_PEER_CONNECTED, - TC_STATE_READY, - TC_STATE_FAILED + TC_STATE_UNKNOWN = 0, + TC_STATE_CLIENT_TO_PEER_CONNECTING, + TC_STATE_PEER_CONNECTING, + TC_STATE_PEER_CONNECTED, + TC_STATE_READY, + TC_STATE_FAILED }; typedef enum _TC_STATE TC_STATE; @@ -78,28 +76,27 @@ typedef enum _TC_STATE TC_STATE; typedef uint32_t tcp_connection_id; typedef struct { - size_t sz; - ioa_network_buffer_handle *bufs; + size_t sz; + ioa_network_buffer_handle *bufs; } unsent_buffer; -struct _tcp_connection -{ - TC_STATE state; - tcp_connection_id id; - ioa_addr peer_addr; - ioa_socket_handle client_s; - ioa_socket_handle peer_s; - ioa_timer_handle peer_conn_timeout; - ioa_timer_handle conn_bind_timeout; - stun_tid tid; - void *owner; //a - int done; - unsent_buffer ub_to_client; +struct _tcp_connection { + TC_STATE state; + tcp_connection_id id; + ioa_addr peer_addr; + ioa_socket_handle client_s; + ioa_socket_handle peer_s; + ioa_timer_handle peer_conn_timeout; + ioa_timer_handle conn_bind_timeout; + stun_tid tid; + void *owner; // a + int done; + unsent_buffer ub_to_client; }; typedef struct _tcp_connection_list { - size_t sz; - tcp_connection **elems; + size_t sz; + tcp_connection **elems; } tcp_connection_list; //////////////////////////////// @@ -116,7 +113,7 @@ typedef struct _ch_info { ioa_addr peer_addr; turn_time_t expiration_time; ioa_timer_handle lifetime_ev; - void *owner; //perm + void *owner; // perm TURN_CHANNEL_HANDLER_KERNEL kernel_channel; } ch_info; @@ -126,43 +123,43 @@ typedef struct _ch_info { #define CH_MAP_ARRAY_SIZE (0x3) typedef struct _chn_map_array { - ch_info main_chns[CH_MAP_ARRAY_SIZE]; - size_t extra_sz; - ch_info **extra_chns; + ch_info main_chns[CH_MAP_ARRAY_SIZE]; + size_t extra_sz; + ch_info **extra_chns; } ch_map_array; typedef struct _ch_map { - ch_map_array table[CH_MAP_HASH_SIZE]; + ch_map_array table[CH_MAP_HASH_SIZE]; } ch_map; -ch_info *ch_map_get(ch_map* map, uint16_t chnum, int new_chn); -void ch_map_clean(ch_map* map); +ch_info *ch_map_get(ch_map *map, uint16_t chnum, int new_chn); +void ch_map_clean(ch_map *map); //////////////////////////// typedef struct _turn_permission_info { - int allocated; - lm_map chns; - ioa_addr addr; - turn_time_t expiration_time; - ioa_timer_handle lifetime_ev; - void* owner; //a - int verbose; - unsigned long long session_id; + int allocated; + lm_map chns; + ioa_addr addr; + turn_time_t expiration_time; + ioa_timer_handle lifetime_ev; + void *owner; // a + int verbose; + unsigned long long session_id; } turn_permission_info; typedef struct _turn_permission_slot { - turn_permission_info info; + turn_permission_info info; } turn_permission_slot; typedef struct _turn_permission_array { - turn_permission_slot main_slots[TURN_PERMISSION_ARRAY_SIZE]; - size_t extra_sz; - turn_permission_slot **extra_slots; + turn_permission_slot main_slots[TURN_PERMISSION_ARRAY_SIZE]; + size_t extra_sz; + turn_permission_slot **extra_slots; } turn_permission_array; typedef struct _turn_permission_hashtable { - turn_permission_array table[TURN_PERMISSION_HASHTABLE_SIZE]; + turn_permission_array table[TURN_PERMISSION_HASHTABLE_SIZE]; } turn_permission_hashtable; //////////////// ALLOCATION ////////////////////// @@ -170,7 +167,7 @@ typedef struct _turn_permission_hashtable { #define ALLOC_IPV4_INDEX (0) #define ALLOC_IPV6_INDEX (1) #define ALLOC_PROTOCOLS_NUMBER (2) -#define ALLOC_INDEX(family) ((((family)==AF_INET6)) ? ALLOC_IPV6_INDEX : ALLOC_IPV4_INDEX ) +#define ALLOC_INDEX(family) ((((family) == AF_INET6)) ? ALLOC_IPV6_INDEX : ALLOC_IPV4_INDEX) #define ALLOC_INDEX_ADDR(addr) ALLOC_INDEX(((addr)->ss).sa_family) typedef struct _allocation { @@ -179,36 +176,36 @@ typedef struct _allocation { turn_permission_hashtable addr_to_perm; relay_endpoint_session relay_sessions[ALLOC_PROTOCOLS_NUMBER]; int relay_sessions_failure[ALLOC_PROTOCOLS_NUMBER]; - ch_map chns; /* chnum-to-ch_info* */ - void *owner; //ss - ur_map *tcp_connections; //global (per turn server) reference - tcp_connection_list tcs; //local reference + ch_map chns; /* chnum-to-ch_info* */ + void *owner; // ss + ur_map *tcp_connections; // global (per turn server) reference + tcp_connection_list tcs; // local reference } allocation; //////////// CHANNELS //////////////////// -uint16_t get_turn_channel_number(turn_permission_info* tinfo, ioa_addr *addr); -ch_info *get_turn_channel(turn_permission_info* tinfo, ioa_addr *addr); +uint16_t get_turn_channel_number(turn_permission_info *tinfo, ioa_addr *addr); +ch_info *get_turn_channel(turn_permission_info *tinfo, ioa_addr *addr); -void turn_channel_delete(ch_info* chn); +void turn_channel_delete(ch_info *chn); /////////// ALLOCATION //////////// -void init_allocation(void *owner, allocation* a, ur_map *tcp_connections); +void init_allocation(void *owner, allocation *a, ur_map *tcp_connections); void clear_allocation(allocation *a, SOCKET_TYPE socket_type); -void turn_permission_clean(turn_permission_info* tinfo); +void turn_permission_clean(turn_permission_info *tinfo); void set_allocation_lifetime_ev(allocation *a, turn_time_t exp_time, ioa_timer_handle ev, int family); -int is_allocation_valid(const allocation* a); -void set_allocation_valid(allocation* a, int value); -turn_permission_info* allocation_get_permission(allocation* a, const ioa_addr *addr); -turn_permission_hashtable* allocation_get_turn_permission_hashtable(allocation *a); -turn_permission_info* allocation_add_permission(allocation *a, const ioa_addr* addr); +int is_allocation_valid(const allocation *a); +void set_allocation_valid(allocation *a, int value); +turn_permission_info *allocation_get_permission(allocation *a, const ioa_addr *addr); +turn_permission_hashtable *allocation_get_turn_permission_hashtable(allocation *a); +turn_permission_info *allocation_add_permission(allocation *a, const ioa_addr *addr); -ch_info* allocation_get_new_ch_info(allocation* a, uint16_t chnum, ioa_addr* peer_addr); -ch_info* allocation_get_ch_info(allocation* a, uint16_t chnum); -ch_info* allocation_get_ch_info_by_peer_addr(allocation* a, ioa_addr* peer_addr); +ch_info *allocation_get_new_ch_info(allocation *a, uint16_t chnum, ioa_addr *peer_addr); +ch_info *allocation_get_ch_info(allocation *a, uint16_t chnum); +ch_info *allocation_get_ch_info_by_peer_addr(allocation *a, ioa_addr *peer_addr); relay_endpoint_session *get_relay_session(allocation *a, int family); int get_relay_session_failure(allocation *a, int family); @@ -220,7 +217,8 @@ tcp_connection *get_and_clean_tcp_connection_by_id(ur_map *map, tcp_connection_i tcp_connection *get_tcp_connection_by_id(ur_map *map, tcp_connection_id id); tcp_connection *get_tcp_connection_by_peer(allocation *a, ioa_addr *peer_addr); int can_accept_tcp_connection_from_peer(allocation *a, ioa_addr *peer_addr, int server_relay); -tcp_connection *create_tcp_connection(uint8_t server_id, allocation *a, stun_tid *tid, ioa_addr *peer_addr, int *err_code); +tcp_connection *create_tcp_connection(uint8_t server_id, allocation *a, stun_tid *tid, ioa_addr *peer_addr, + int *err_code); void delete_tcp_connection(tcp_connection *tc); void clear_unsent_buffer(unsent_buffer *ub); diff --git a/src/server/ns_turn_ioalib.h b/src/server/ns_turn_ioalib.h index a4a5534..4a83be3 100644 --- a/src/server/ns_turn_ioalib.h +++ b/src/server/ns_turn_ioalib.h @@ -50,41 +50,41 @@ struct _tcp_connection; typedef struct _tcp_connection tcp_connection; #if defined(_MSC_VER) - #ifndef strtok_r - #define strtok_r strtok_s - #endif +#ifndef strtok_r +#define strtok_r strtok_s +#endif - #ifndef sleep - #define sleep(t) Sleep(t * 1000) - #endif +#ifndef sleep +#define sleep(t) Sleep(t * 1000) +#endif - #ifndef usleep - #define usleep Sleep - #endif +#ifndef usleep +#define usleep Sleep +#endif + +#if !defined(ssize_t) && !defined(_SSIZE_T_) +#include +typedef SSIZE_T ssize_t; +#endif - #if !defined(ssize_t) && !defined(_SSIZE_T_) - #include - typedef SSIZE_T ssize_t; - #endif - #endif ////////////// Mutexes ///////////////////// struct _turn_mutex { uint32_t data; - void* mutex; + void *mutex; }; typedef struct _turn_mutex turn_mutex; -int turn_mutex_init(turn_mutex* mutex); -int turn_mutex_init_recursive(turn_mutex* mutex); +int turn_mutex_init(turn_mutex *mutex); +int turn_mutex_init_recursive(turn_mutex *mutex); int turn_mutex_lock(const turn_mutex *mutex); int turn_mutex_unlock(const turn_mutex *mutex); -int turn_mutex_destroy(turn_mutex* mutex); +int turn_mutex_destroy(turn_mutex *mutex); #define TURN_MUTEX_DECLARE(mutex) turn_mutex mutex; #define TURN_MUTEX_INIT(mutex) turn_mutex_init(mutex) @@ -95,37 +95,37 @@ int turn_mutex_destroy(turn_mutex* mutex); /////// Sockets ////////////////////////////// -#define IOA_EV_TIMEOUT 0x01 -#define IOA_EV_READ 0x02 -#define IOA_EV_WRITE 0x04 -#define IOA_EV_SIGNAL 0x08 -#define IOA_EV_CLOSE 0x10 +#define IOA_EV_TIMEOUT 0x01 +#define IOA_EV_READ 0x02 +#define IOA_EV_WRITE 0x04 +#define IOA_EV_SIGNAL 0x08 +#define IOA_EV_CLOSE 0x10 enum _SOCKET_TYPE { - UNKNOWN_SOCKET=0, - TCP_SOCKET=6, - UDP_SOCKET=17, - TLS_SOCKET=56, - SCTP_SOCKET=132, - TLS_SCTP_SOCKET=133, - DTLS_SOCKET=250, - TCP_SOCKET_PROXY=253, - TENTATIVE_SCTP_SOCKET=254, - TENTATIVE_TCP_SOCKET=255 + UNKNOWN_SOCKET = 0, + TCP_SOCKET = 6, + UDP_SOCKET = 17, + TLS_SOCKET = 56, + SCTP_SOCKET = 132, + TLS_SCTP_SOCKET = 133, + DTLS_SOCKET = 250, + TCP_SOCKET_PROXY = 253, + TENTATIVE_SCTP_SOCKET = 254, + TENTATIVE_TCP_SOCKET = 255 }; typedef enum _SOCKET_TYPE SOCKET_TYPE; enum _SOCKET_APP_TYPE { - UNKNOWN_APP_SOCKET, - CLIENT_SOCKET, - HTTP_CLIENT_SOCKET, - HTTPS_CLIENT_SOCKET, - RELAY_SOCKET, - RELAY_RTCP_SOCKET, - TCP_CLIENT_DATA_SOCKET, - TCP_RELAY_DATA_SOCKET, - LISTENER_SOCKET + UNKNOWN_APP_SOCKET, + CLIENT_SOCKET, + HTTP_CLIENT_SOCKET, + HTTPS_CLIENT_SOCKET, + RELAY_SOCKET, + RELAY_RTCP_SOCKET, + TCP_CLIENT_DATA_SOCKET, + TCP_RELAY_DATA_SOCKET, + LISTENER_SOCKET }; typedef enum _SOCKET_APP_TYPE SOCKET_APP_TYPE; @@ -144,10 +144,10 @@ typedef void *ioa_network_buffer_handle; /* event data for net event */ typedef struct _ioa_net_data { - ioa_addr src_addr; - ioa_network_buffer_handle nbh; - int recv_ttl; - int recv_tos; + ioa_addr src_addr; + ioa_network_buffer_handle nbh; + int recv_ttl; + int recv_tos; } ioa_net_data; /* Callback on TCP connection completion */ @@ -163,27 +163,27 @@ typedef struct _realm_options_t realm_options_t; //////// IP White/black listing /////////// struct _ip_range { - char str[257]; - char realm[513]; - ioa_addr_range enc; + char str[257]; + char realm[513]; + ioa_addr_range enc; }; typedef struct _ip_range ip_range_t; struct _ip_range_list { - ip_range_t *rs; - size_t ranges_number; + ip_range_t *rs; + size_t ranges_number; }; typedef struct _ip_range_list ip_range_list_t; void ioa_lock_whitelist(ioa_engine_handle e); void ioa_unlock_whitelist(ioa_engine_handle e); -const ip_range_list_t* ioa_get_whitelist(ioa_engine_handle e); +const ip_range_list_t *ioa_get_whitelist(ioa_engine_handle e); void ioa_lock_blacklist(ioa_engine_handle e); void ioa_unlock_blacklist(ioa_engine_handle e); -const ip_range_list_t* ioa_get_blacklist(ioa_engine_handle e); +const ip_range_list_t *ioa_get_blacklist(ioa_engine_handle e); //////////////////////////////////////////// @@ -215,7 +215,8 @@ void turn_report_session_usage(void *session, int force_invalid); * the function must work correctly when chnum=0 * (when no hint information is available). */ -typedef void (*ioa_net_event_handler)(ioa_socket_handle s, int event_type, ioa_net_data *data, void *ctx, int can_resume); +typedef void (*ioa_net_event_handler)(ioa_socket_handle s, int event_type, ioa_net_data *data, void *ctx, + int can_resume); /* * Timer callback @@ -224,10 +225,17 @@ typedef void (*ioa_timer_event_handler)(ioa_engine_handle e, void *ctx); /* timers */ -ioa_timer_handle set_ioa_timer(ioa_engine_handle e, int secs, int ms, ioa_timer_event_handler cb, void *ctx, int persist, const char *txt); +ioa_timer_handle set_ioa_timer(ioa_engine_handle e, int secs, int ms, ioa_timer_event_handler cb, void *ctx, + int persist, const char *txt); void stop_ioa_timer(ioa_timer_handle th); void delete_ioa_timer(ioa_timer_handle th); -#define IOA_EVENT_DEL(E) do { if(E) { delete_ioa_timer(E); E = NULL; } } while(0) +#define IOA_EVENT_DEL(E) \ + do { \ + if (E) { \ + delete_ioa_timer(E); \ + E = NULL; \ + } \ + } while (0) ioa_socket_handle create_unbound_relay_ioa_socket(ioa_engine_handle e, int family, SOCKET_TYPE st, SOCKET_APP_TYPE sat); @@ -239,13 +247,13 @@ void inc_ioa_socket_ref_counter(ioa_socket_handle s); * event_port == 0: reserve rtcp; * even_port == +1: reserve and bind rtcp. */ -int create_relay_ioa_sockets(ioa_engine_handle e, ioa_socket_handle client_s, - int address_family, uint8_t transport, - int even_port, ioa_socket_handle *rtp_s, ioa_socket_handle *rtcp_s, - uint64_t *out_reservation_token, int *err_code, const uint8_t **reason, - accept_cb acb, void *acbarg); +int create_relay_ioa_sockets(ioa_engine_handle e, ioa_socket_handle client_s, int address_family, uint8_t transport, + int even_port, ioa_socket_handle *rtp_s, ioa_socket_handle *rtcp_s, + uint64_t *out_reservation_token, int *err_code, const uint8_t **reason, accept_cb acb, + void *acbarg); -ioa_socket_handle ioa_create_connecting_tcp_relay_socket(ioa_socket_handle s, ioa_addr *peer_addr, connect_cb cb, void *arg); +ioa_socket_handle ioa_create_connecting_tcp_relay_socket(ioa_socket_handle s, ioa_addr *peer_addr, connect_cb cb, + void *arg); int get_ioa_socket_from_reservation(ioa_engine_handle e, uint64_t in_reservation_token, ioa_socket_handle *s); @@ -253,26 +261,34 @@ int get_ioa_socket_address_family(ioa_socket_handle s); int is_stream_socket(int st); int is_tcp_socket(int st); int is_sctp_socket(int st); -const char* socket_type_name(SOCKET_TYPE st); -const char* get_ioa_socket_cipher(ioa_socket_handle s); -const char* get_ioa_socket_ssl_method(ioa_socket_handle s); +const char *socket_type_name(SOCKET_TYPE st); +const char *get_ioa_socket_cipher(ioa_socket_handle s); +const char *get_ioa_socket_ssl_method(ioa_socket_handle s); SOCKET_TYPE get_ioa_socket_type(ioa_socket_handle s); SOCKET_APP_TYPE get_ioa_socket_app_type(ioa_socket_handle s); -const char* get_ioa_socket_tls_method(ioa_socket_handle s); -const char* get_ioa_socket_tls_cipher(ioa_socket_handle s); +const char *get_ioa_socket_tls_method(ioa_socket_handle s); +const char *get_ioa_socket_tls_cipher(ioa_socket_handle s); void set_ioa_socket_app_type(ioa_socket_handle s, SOCKET_APP_TYPE sat); -ioa_addr* get_local_addr_from_ioa_socket(ioa_socket_handle s); -ioa_addr* get_remote_addr_from_ioa_socket(ioa_socket_handle s); +ioa_addr *get_local_addr_from_ioa_socket(ioa_socket_handle s); +ioa_addr *get_remote_addr_from_ioa_socket(ioa_socket_handle s); int get_local_mtu_ioa_socket(ioa_socket_handle s); ts_ur_super_session *get_ioa_socket_session(ioa_socket_handle s); void set_ioa_socket_session(ioa_socket_handle s, ts_ur_super_session *ss); void clear_ioa_socket_session_if(ioa_socket_handle s, void *ss); tcp_connection *get_ioa_socket_sub_session(ioa_socket_handle s); void set_ioa_socket_sub_session(ioa_socket_handle s, tcp_connection *tc); -int register_callback_on_ioa_socket(ioa_engine_handle e, ioa_socket_handle s, int event_type, ioa_net_event_handler cb, void *ctx, int clean_preexisting); -int send_data_from_ioa_socket_nbh(ioa_socket_handle s, ioa_addr* dest_addr, ioa_network_buffer_handle nbh, int ttl, int tos, int *skip); +int register_callback_on_ioa_socket(ioa_engine_handle e, ioa_socket_handle s, int event_type, ioa_net_event_handler cb, + void *ctx, int clean_preexisting); +int send_data_from_ioa_socket_nbh(ioa_socket_handle s, ioa_addr *dest_addr, ioa_network_buffer_handle nbh, int ttl, + int tos, int *skip); void close_ioa_socket(ioa_socket_handle s); -#define IOA_CLOSE_SOCKET(S) do { if(S) { close_ioa_socket(S); S = NULL; } } while(0) +#define IOA_CLOSE_SOCKET(S) \ + do { \ + if (S) { \ + close_ioa_socket(S); \ + S = NULL; \ + } \ + } while (0) ioa_socket_handle detach_ioa_socket(ioa_socket_handle s); void detach_socket_net_data(ioa_socket_handle s); int set_df_on_ioa_socket(ioa_socket_handle s, int value); @@ -283,23 +299,19 @@ void close_ioa_socket_after_processing_if_necessary(ioa_socket_handle s); ////////////////// Base64 ///////////////////////////// -char *base64_encode(const unsigned char *data, - size_t input_length, - size_t *output_length); +char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length); void build_base64_decoding_table(void); -unsigned char *base64_decode(const char *data, - size_t input_length, - size_t *output_length); +unsigned char *base64_decode(const char *data, size_t input_length, size_t *output_length); ///////////// Realm /////////////////// -void get_default_realm_options(realm_options_t* ro); -int get_realm_options_by_origin(char *origin, realm_options_t* ro); -void get_realm_options_by_name(char *realm, realm_options_t* ro); -int get_canonic_origin(const char* o, char *co, int sz); -int get_default_protocol_port(const char* scheme, size_t slen); +void get_default_realm_options(realm_options_t *ro); +int get_realm_options_by_origin(char *origin, realm_options_t *ro); +void get_realm_options_by_name(char *realm, realm_options_t *ro); +int get_canonic_origin(const char *o, char *co, int sz); +int get_default_protocol_port(const char *scheme, size_t slen); ///////////// HTTP //////////////////// diff --git a/src/server/ns_turn_khash.h b/src/server/ns_turn_khash.h index f75f347..7f25472 100644 --- a/src/server/ns_turn_khash.h +++ b/src/server/ns_turn_khash.h @@ -29,35 +29,35 @@ #include "khash.h" KHASH_MAP_INIT_INT(32, char) int main() { - int ret, is_missing; - khiter_t k; - khash_t(32) *h = kh_init(32); - k = kh_put(32, h, 5, &ret); - kh_value(h, k) = 10; - k = kh_get(32, h, 10); - is_missing = (k == kh_end(h)); - k = kh_get(32, h, 5); - kh_del(32, h, k); - for (k = kh_begin(h); k != kh_end(h); ++k) - if (kh_exist(h, k)) kh_value(h, k) = 1; - kh_destroy(32, h); - return 0; + int ret, is_missing; + khiter_t k; + khash_t(32) *h = kh_init(32); + k = kh_put(32, h, 5, &ret); + kh_value(h, k) = 10; + k = kh_get(32, h, 10); + is_missing = (k == kh_end(h)); + k = kh_get(32, h, 5); + kh_del(32, h, k); + for (k = kh_begin(h); k != kh_end(h); ++k) + if (kh_exist(h, k)) kh_value(h, k) = 1; + kh_destroy(32, h); + return 0; } */ /* 2013-05-02 (0.2.8): - * Use quadratic probing. When the capacity is power of 2, stepping function - i*(i+1)/2 guarantees to traverse each bucket. It is better than double - hashing on cache performance and is more robust than linear probing. + * Use quadratic probing. When the capacity is power of 2, stepping function + i*(i+1)/2 guarantees to traverse each bucket. It is better than double + hashing on cache performance and is more robust than linear probing. - In theory, double hashing should be more robust than quadratic probing. - However, my implementation is probably not for large hash tables, because - the second hash function is closely tied to the first hash function, - which reduce the effectiveness of double hashing. + In theory, double hashing should be more robust than quadratic probing. + However, my implementation is probably not for large hash tables, because + the second hash function is closely tied to the first hash function, + which reduce the effectiveness of double hashing. - Reference: http://research.cs.vt.edu/AVresearch/hashing/quadratic.php + Reference: http://research.cs.vt.edu/AVresearch/hashing/quadratic.php 2011-12-29 (0.2.7): @@ -65,18 +65,18 @@ int main() { 2011-09-16 (0.2.6): - * The capacity is a power of 2. This seems to dramatically improve the - speed for simple keys. Thank Zilong Tan for the suggestion. Reference: + * The capacity is a power of 2. This seems to dramatically improve the + speed for simple keys. Thank Zilong Tan for the suggestion. Reference: - - http://code.google.com/p/ulib/ - - http://nothings.org/computer/judy/ + - http://code.google.com/p/ulib/ + - http://nothings.org/computer/judy/ - * Allow to optionally use linear probing which usually has better - performance for random input. Double hashing is still the default as it - is more robust to certain non-random input. + * Allow to optionally use linear probing which usually has better + performance for random input. Double hashing is still the default as it + is more robust to certain non-random input. - * Added Wang's integer hash function (not used by default). This hash - function is more robust to certain non-random input. + * Added Wang's integer hash function (not used by default). This hash + function is more robust to certain non-random input. 2011-02-14 (0.2.5): @@ -88,32 +88,31 @@ int main() { 2008-09-19 (0.2.3): - * Corrected the example - * Improved interfaces + * Corrected the example + * Improved interfaces 2008-09-11 (0.2.2): - * Improved speed a little in kh_put() + * Improved speed a little in kh_put() 2008-09-10 (0.2.1): - * Added kh_clear() - * Fixed a compiling error + * Added kh_clear() + * Fixed a compiling error 2008-09-02 (0.2.0): - * Changed to token concatenation which increases flexibility. + * Changed to token concatenation which increases flexibility. 2008-08-31 (0.1.2): - * Fixed a bug in kh_get(), which has not been tested previously. + * Fixed a bug in kh_get(), which has not been tested previously. 2008-08-31 (0.1.1): - * Added destructor + * Added destructor */ - #ifndef __AC_KHASH_H #define __AC_KHASH_H @@ -125,9 +124,9 @@ int main() { #define AC_VERSION_KHASH_H "0.2.8" +#include #include #include -#include /* compiler specific configuration */ @@ -153,7 +152,7 @@ typedef unsigned long long khint64_t; #ifndef klib_unused #if (defined __clang__ && __clang_major__ >= 3) || (defined __GNUC__ && __GNUC__ >= 3) -#define klib_unused __attribute__ ((__unused__)) +#define klib_unused __attribute__((__unused__)) #else #define klib_unused #endif @@ -162,28 +161,29 @@ typedef unsigned long long khint64_t; typedef khint32_t khint_t; typedef khint_t khiter_t; -#define __ac_isempty(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&2) -#define __ac_isdel(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&1) -#define __ac_iseither(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&3) -#define __ac_set_isdel_false(flag, i) (flag[i>>4]&=~(1ul<<((i&0xfU)<<1))) -#define __ac_set_isempty_false(flag, i) (flag[i>>4]&=~(2ul<<((i&0xfU)<<1))) -#define __ac_set_isboth_false(flag, i) (flag[i>>4]&=~(3ul<<((i&0xfU)<<1))) -#define __ac_set_isdel_true(flag, i) (flag[i>>4]|=1ul<<((i&0xfU)<<1)) +#define __ac_isempty(flag, i) ((flag[i >> 4] >> ((i & 0xfU) << 1)) & 2) +#define __ac_isdel(flag, i) ((flag[i >> 4] >> ((i & 0xfU) << 1)) & 1) +#define __ac_iseither(flag, i) ((flag[i >> 4] >> ((i & 0xfU) << 1)) & 3) +#define __ac_set_isdel_false(flag, i) (flag[i >> 4] &= ~(1ul << ((i & 0xfU) << 1))) +#define __ac_set_isempty_false(flag, i) (flag[i >> 4] &= ~(2ul << ((i & 0xfU) << 1))) +#define __ac_set_isboth_false(flag, i) (flag[i >> 4] &= ~(3ul << ((i & 0xfU) << 1))) +#define __ac_set_isdel_true(flag, i) (flag[i >> 4] |= 1ul << ((i & 0xfU) << 1)) -#define __ac_fsize(m) ((m) < 16? 1 : (m)>>4) +#define __ac_fsize(m) ((m) < 16 ? 1 : (m) >> 4) #ifndef kroundup32 -#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +#define kroundup32(x) \ + (--(x), (x) |= (x) >> 1, (x) |= (x) >> 2, (x) |= (x) >> 4, (x) |= (x) >> 8, (x) |= (x) >> 16, ++(x)) #endif #ifndef kcalloc -#define kcalloc(N,Z) calloc(N,Z) +#define kcalloc(N, Z) calloc(N, Z) #endif #ifndef kmalloc #define kmalloc(Z) malloc(Z) #endif #ifndef krealloc -#define krealloc(P,Z) realloc(P,Z) +#define krealloc(P, Z) realloc(P, Z) #endif #ifndef kfree #define kfree(P) free(P) @@ -191,179 +191,211 @@ typedef khint_t khiter_t; static const double __ac_HASH_UPPER = 0.77; -#define __KHASH_TYPE(name, khkey_t, khval_t) \ - typedef struct kh_##name##_s { \ - khint_t n_buckets, size, n_occupied, upper_bound; \ - khint32_t *flags; \ - khkey_t *keys; \ - khval_t *vals; \ - } kh_##name##_t; +#define __KHASH_TYPE(name, khkey_t, khval_t) \ + typedef struct kh_##name##_s { \ + khint_t n_buckets, size, n_occupied, upper_bound; \ + khint32_t *flags; \ + khkey_t *keys; \ + khval_t *vals; \ + } kh_##name##_t; -#define __KHASH_PROTOTYPES(name, khkey_t, khval_t) \ - extern kh_##name##_t *kh_init_##name(void); \ - extern void kh_destroy_##name(kh_##name##_t *h); \ - extern void kh_clear_##name(kh_##name##_t *h); \ - extern khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key); \ - extern int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \ - extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret); \ - extern void kh_del_##name(kh_##name##_t *h, khint_t x); +#define __KHASH_PROTOTYPES(name, khkey_t, khval_t) \ + extern kh_##name##_t *kh_init_##name(void); \ + extern void kh_destroy_##name(kh_##name##_t *h); \ + extern void kh_clear_##name(kh_##name##_t *h); \ + extern khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key); \ + extern int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \ + extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret); \ + extern void kh_del_##name(kh_##name##_t *h, khint_t x); -#define __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ - SCOPE kh_##name##_t *kh_init_##name(void) { \ - return (kh_##name##_t*)kcalloc(1, sizeof(kh_##name##_t)); \ - } \ - SCOPE void kh_destroy_##name(kh_##name##_t *h) \ - { \ - if (h) { \ - kfree((void *)h->keys); kfree(h->flags); \ - kfree((void *)h->vals); \ - kfree(h); \ - } \ - } \ - SCOPE void kh_clear_##name(kh_##name##_t *h) \ - { \ - if (h && h->flags) { \ - memset(h->flags, 0xaa, __ac_fsize(h->n_buckets) * sizeof(khint32_t)); \ - h->size = h->n_occupied = 0; \ - } \ - } \ - SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \ - { \ - if (h->n_buckets) { \ - khint_t k, i, last, mask, step = 0; \ - mask = h->n_buckets - 1; \ - k = __hash_func(key); i = k & mask; \ - last = i; \ - while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \ - i = (i + (++step)) & mask; \ - if (i == last) return h->n_buckets; \ - } \ - return __ac_iseither(h->flags, i)? h->n_buckets : i; \ - } else return 0; \ - } \ - SCOPE int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \ - { /* This function uses 0.25*n_buckets bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. */ \ - khint32_t *new_flags = 0; \ - khint_t j = 1; \ - { \ - kroundup32(new_n_buckets); \ - if (new_n_buckets < 4) new_n_buckets = 4; \ - if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0; /* requested size is too small */ \ - else { /* hash table size to be changed (shrink or expand); rehash */ \ - new_flags = (khint32_t*)kmalloc(__ac_fsize(new_n_buckets) * sizeof(khint32_t)); \ - if (!new_flags) return -1; \ - memset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \ - if (h->n_buckets < new_n_buckets) { /* expand */ \ - khkey_t *new_keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \ - if (!new_keys) { kfree(new_flags); return -1; } \ - h->keys = new_keys; \ - if (kh_is_map) { \ - khval_t *new_vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \ - if (!new_vals) { kfree(new_flags); return -1; } \ - h->vals = new_vals; \ - } \ - } /* otherwise shrink */ \ - } \ - } \ - if (j) { /* rehashing is needed */ \ - for (j = 0; j != h->n_buckets; ++j) { \ - if (__ac_iseither(h->flags, j) == 0) { \ - khkey_t key = h->keys[j]; \ - khval_t val; \ - khint_t new_mask; \ - new_mask = new_n_buckets - 1; \ - if (kh_is_map) val = h->vals[j]; \ - __ac_set_isdel_true(h->flags, j); \ - while (1) { /* kick-out process; sort of like in Cuckoo hashing */ \ - khint_t k, i, step = 0; \ - k = __hash_func(key); \ - i = k & new_mask; \ - while (!__ac_isempty(new_flags, i)) i = (i + (++step)) & new_mask; \ - __ac_set_isempty_false(new_flags, i); \ - if (i < h->n_buckets && __ac_iseither(h->flags, i) == 0) { /* kick out the existing element */ \ - { khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \ - if (kh_is_map) { khval_t tmp = h->vals[i]; h->vals[i] = val; val = tmp; } \ - __ac_set_isdel_true(h->flags, i); /* mark it as deleted in the old hash table */ \ - } else { /* write the element and jump out of the loop */ \ - h->keys[i] = key; \ - if (kh_is_map) h->vals[i] = val; \ - break; \ - } \ - } \ - } \ - } \ - if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \ - h->keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \ - if (kh_is_map) h->vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \ - } \ - kfree(h->flags); /* free the working space */ \ - h->flags = new_flags; \ - h->n_buckets = new_n_buckets; \ - h->n_occupied = h->size; \ - h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \ - } \ - return 0; \ - } \ - SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \ - { \ - khint_t x; \ - if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \ - if (h->n_buckets > (h->size<<1)) { \ - if (kh_resize_##name(h, h->n_buckets - 1) < 0) { /* clear "deleted" elements */ \ - *ret = -1; return h->n_buckets; \ - } \ - } else if (kh_resize_##name(h, h->n_buckets + 1) < 0) { /* expand the hash table */ \ - *ret = -1; return h->n_buckets; \ - } \ - } /* TODO: to implement automatically shrinking; resize() already support shrinking */ \ - { \ - khint_t k, i, site, last, mask = h->n_buckets - 1, step = 0; \ - x = site = h->n_buckets; k = __hash_func(key); i = k & mask; \ - if (__ac_isempty(h->flags, i)) x = i; /* for speed up */ \ - else { \ - last = i; \ - while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \ - if (__ac_isdel(h->flags, i)) site = i; \ - i = (i + (++step)) & mask; \ - if (i == last) { x = site; break; } \ - } \ - if (x == h->n_buckets) { \ - if (__ac_isempty(h->flags, i) && site != h->n_buckets) x = site; \ - else x = i; \ - } \ - } \ - } \ - if (__ac_isempty(h->flags, x)) { /* not present at all */ \ - h->keys[x] = key; \ - __ac_set_isboth_false(h->flags, x); \ - ++h->size; ++h->n_occupied; \ - *ret = 1; \ - } else if (__ac_isdel(h->flags, x)) { /* deleted */ \ - h->keys[x] = key; \ - __ac_set_isboth_false(h->flags, x); \ - ++h->size; \ - *ret = 2; \ - } else *ret = 0; /* Don't touch h->keys[x] if present and not deleted */ \ - return x; \ - } \ - SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x) \ - { \ - if (x != h->n_buckets && !__ac_iseither(h->flags, x)) { \ - __ac_set_isdel_true(h->flags, x); \ - --h->size; \ - } \ - } +#define __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ + SCOPE kh_##name##_t *kh_init_##name(void) { return (kh_##name##_t *)kcalloc(1, sizeof(kh_##name##_t)); } \ + SCOPE void kh_destroy_##name(kh_##name##_t *h) { \ + if (h) { \ + kfree((void *)h->keys); \ + kfree(h->flags); \ + kfree((void *)h->vals); \ + kfree(h); \ + } \ + } \ + SCOPE void kh_clear_##name(kh_##name##_t *h) { \ + if (h && h->flags) { \ + memset(h->flags, 0xaa, __ac_fsize(h->n_buckets) * sizeof(khint32_t)); \ + h->size = h->n_occupied = 0; \ + } \ + } \ + SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) { \ + if (h->n_buckets) { \ + khint_t k, i, last, mask, step = 0; \ + mask = h->n_buckets - 1; \ + k = __hash_func(key); \ + i = k & mask; \ + last = i; \ + while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \ + i = (i + (++step)) & mask; \ + if (i == last) \ + return h->n_buckets; \ + } \ + return __ac_iseither(h->flags, i) ? h->n_buckets : i; \ + } else \ + return 0; \ + } \ + SCOPE int kh_resize_##name(kh_##name##_t *h, \ + khint_t new_n_buckets) { /* This function uses 0.25*n_buckets bytes of working space \ + instead of [sizeof(key_t+val_t)+.25]*n_buckets. */ \ + khint32_t *new_flags = 0; \ + khint_t j = 1; \ + { \ + kroundup32(new_n_buckets); \ + if (new_n_buckets < 4) \ + new_n_buckets = 4; \ + if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) \ + j = 0; /* requested size is too small */ \ + else { /* hash table size to be changed (shrink or expand); rehash */ \ + new_flags = (khint32_t *)kmalloc(__ac_fsize(new_n_buckets) * sizeof(khint32_t)); \ + if (!new_flags) \ + return -1; \ + memset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \ + if (h->n_buckets < new_n_buckets) { /* expand */ \ + khkey_t *new_keys = (khkey_t *)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \ + if (!new_keys) { \ + kfree(new_flags); \ + return -1; \ + } \ + h->keys = new_keys; \ + if (kh_is_map) { \ + khval_t *new_vals = (khval_t *)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \ + if (!new_vals) { \ + kfree(new_flags); \ + return -1; \ + } \ + h->vals = new_vals; \ + } \ + } /* otherwise shrink */ \ + } \ + } \ + if (j) { /* rehashing is needed */ \ + for (j = 0; j != h->n_buckets; ++j) { \ + if (__ac_iseither(h->flags, j) == 0) { \ + khkey_t key = h->keys[j]; \ + khval_t val; \ + khint_t new_mask; \ + new_mask = new_n_buckets - 1; \ + if (kh_is_map) \ + val = h->vals[j]; \ + __ac_set_isdel_true(h->flags, j); \ + while (1) { /* kick-out process; sort of like in Cuckoo hashing */ \ + khint_t k, i, step = 0; \ + k = __hash_func(key); \ + i = k & new_mask; \ + while (!__ac_isempty(new_flags, i)) \ + i = (i + (++step)) & new_mask; \ + __ac_set_isempty_false(new_flags, i); \ + if (i < h->n_buckets && __ac_iseither(h->flags, i) == 0) { /* kick out the existing element */ \ + { \ + khkey_t tmp = h->keys[i]; \ + h->keys[i] = key; \ + key = tmp; \ + } \ + if (kh_is_map) { \ + khval_t tmp = h->vals[i]; \ + h->vals[i] = val; \ + val = tmp; \ + } \ + __ac_set_isdel_true(h->flags, i); /* mark it as deleted in the old hash table */ \ + } else { /* write the element and jump out of the loop */ \ + h->keys[i] = key; \ + if (kh_is_map) \ + h->vals[i] = val; \ + break; \ + } \ + } \ + } \ + } \ + if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \ + h->keys = (khkey_t *)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \ + if (kh_is_map) \ + h->vals = (khval_t *)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \ + } \ + kfree(h->flags); /* free the working space */ \ + h->flags = new_flags; \ + h->n_buckets = new_n_buckets; \ + h->n_occupied = h->size; \ + h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \ + } \ + return 0; \ + } \ + SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) { \ + khint_t x; \ + if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \ + if (h->n_buckets > (h->size << 1)) { \ + if (kh_resize_##name(h, h->n_buckets - 1) < 0) { /* clear "deleted" elements */ \ + *ret = -1; \ + return h->n_buckets; \ + } \ + } else if (kh_resize_##name(h, h->n_buckets + 1) < 0) { /* expand the hash table */ \ + *ret = -1; \ + return h->n_buckets; \ + } \ + } /* TODO: to implement automatically shrinking; resize() already support shrinking */ \ + { \ + khint_t k, i, site, last, mask = h->n_buckets - 1, step = 0; \ + x = site = h->n_buckets; \ + k = __hash_func(key); \ + i = k & mask; \ + if (__ac_isempty(h->flags, i)) \ + x = i; /* for speed up */ \ + else { \ + last = i; \ + while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \ + if (__ac_isdel(h->flags, i)) \ + site = i; \ + i = (i + (++step)) & mask; \ + if (i == last) { \ + x = site; \ + break; \ + } \ + } \ + if (x == h->n_buckets) { \ + if (__ac_isempty(h->flags, i) && site != h->n_buckets) \ + x = site; \ + else \ + x = i; \ + } \ + } \ + } \ + if (__ac_isempty(h->flags, x)) { /* not present at all */ \ + h->keys[x] = key; \ + __ac_set_isboth_false(h->flags, x); \ + ++h->size; \ + ++h->n_occupied; \ + *ret = 1; \ + } else if (__ac_isdel(h->flags, x)) { /* deleted */ \ + h->keys[x] = key; \ + __ac_set_isboth_false(h->flags, x); \ + ++h->size; \ + *ret = 2; \ + } else \ + *ret = 0; /* Don't touch h->keys[x] if present and not deleted */ \ + return x; \ + } \ + SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x) { \ + if (x != h->n_buckets && !__ac_iseither(h->flags, x)) { \ + __ac_set_isdel_true(h->flags, x); \ + --h->size; \ + } \ + } -#define KHASH_DECLARE(name, khkey_t, khval_t) \ - __KHASH_TYPE(name, khkey_t, khval_t) \ - __KHASH_PROTOTYPES(name, khkey_t, khval_t) +#define KHASH_DECLARE(name, khkey_t, khval_t) \ + __KHASH_TYPE(name, khkey_t, khval_t) \ + __KHASH_PROTOTYPES(name, khkey_t, khval_t) -#define KHASH_INIT2(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ - __KHASH_TYPE(name, khkey_t, khval_t) \ - __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) +#define KHASH_INIT2(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ + __KHASH_TYPE(name, khkey_t, khval_t) \ + __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) -#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ - KHASH_INIT2(name, static kh_inline klib_unused, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) +#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ + KHASH_INIT2(name, static kh_inline klib_unused, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) /* --- BEGIN OF HASH FUNCTIONS --- */ @@ -382,7 +414,7 @@ static const double __ac_HASH_UPPER = 0.77; @param key The integer [khint64_t] @return The hash value [khint_t] */ -#define kh_int64_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11) +#define kh_int64_hash_func(key) (khint32_t)((key) >> 33 ^ (key) ^ (key) << 11) /*! @function @abstract 64-bit integer comparison function */ @@ -392,11 +424,12 @@ static const double __ac_HASH_UPPER = 0.77; @param s Pointer to a null terminated string @return The hash value */ -static kh_inline khint_t __ac_X31_hash_string(const char *s) -{ - khint_t h = (khint_t)*s; - if (h) for (++s ; *s; ++s) h = (h << 5) - h + (khint_t)*s; - return h; +static kh_inline khint_t __ac_X31_hash_string(const char *s) { + khint_t h = (khint_t)*s; + if (h) + for (++s; *s; ++s) + h = (h << 5) - h + (khint_t)*s; + return h; } /*! @function @abstract Another interface to const char* hash function @@ -409,15 +442,14 @@ static kh_inline khint_t __ac_X31_hash_string(const char *s) */ #define kh_str_hash_equal(a, b) (strcmp(a, b) == 0) -static kh_inline khint_t __ac_Wang_hash(khint_t key) -{ - key += ~(key << 15); - key ^= (key >> 10); - key += (key << 3); - key ^= (key >> 6); - key += ~(key << 11); - key ^= (key >> 16); - return key; +static kh_inline khint_t __ac_Wang_hash(khint_t key) { + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); + return key; } #define kh_int_hash_func2(key) __ac_Wang_hash((khint_t)key) @@ -468,7 +500,7 @@ static kh_inline khint_t __ac_Wang_hash(khint_t key) @param r Extra return code: -1 if the operation failed; 0 if the key is present in the hash table; 1 if the bucket is empty (never used); 2 if the element in - the bucket has been deleted [int*] + the bucket has been deleted [int*] @return Iterator to the inserted element [khint_t] */ #define kh_put(name, h, k, r) kh_put_##name(h, k, r) @@ -555,13 +587,17 @@ static kh_inline khint_t __ac_Wang_hash(khint_t key) @param vvar Variable to which value will be assigned @param code Block of code to execute */ -#define kh_foreach(h, kvar, vvar, code) { khint_t __i; \ - for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \ - if (!kh_exist(h,__i)) continue; \ - (kvar) = kh_key(h,__i); \ - (vvar) = kh_val(h,__i); \ - code; \ - } } +#define kh_foreach(h, kvar, vvar, code) \ + { \ + khint_t __i; \ + for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \ + if (!kh_exist(h, __i)) \ + continue; \ + (kvar) = kh_key(h, __i); \ + (vvar) = kh_val(h, __i); \ + code; \ + } \ + } /*! @function @abstract Iterate over the values in the hash table @@ -569,12 +605,16 @@ static kh_inline khint_t __ac_Wang_hash(khint_t key) @param vvar Variable to which value will be assigned @param code Block of code to execute */ -#define kh_foreach_value(h, vvar, code) { khint_t __i; \ - for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \ - if (!kh_exist(h,__i)) continue; \ - (vvar) = kh_val(h,__i); \ - code; \ - } } +#define kh_foreach_value(h, vvar, code) \ + { \ + khint_t __i; \ + for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \ + if (!kh_exist(h, __i)) \ + continue; \ + (vvar) = kh_val(h, __i); \ + code; \ + } \ + } /* More convenient interfaces */ @@ -582,46 +622,41 @@ static kh_inline khint_t __ac_Wang_hash(khint_t key) @abstract Instantiate a hash set containing integer keys @param name Name of the hash table [symbol] */ -#define KHASH_SET_INIT_INT(name) \ - KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal) +#define KHASH_SET_INIT_INT(name) KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal) /*! @function @abstract Instantiate a hash map containing integer keys @param name Name of the hash table [symbol] @param khval_t Type of values [type] */ -#define KHASH_MAP_INIT_INT(name, khval_t) \ - KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal) +#define KHASH_MAP_INIT_INT(name, khval_t) KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal) /*! @function @abstract Instantiate a hash set containing 64-bit integer keys @param name Name of the hash table [symbol] */ -#define KHASH_SET_INIT_INT64(name) \ - KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal) +#define KHASH_SET_INIT_INT64(name) KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal) /*! @function @abstract Instantiate a hash map containing 64-bit integer keys @param name Name of the hash table [symbol] @param khval_t Type of values [type] */ -#define KHASH_MAP_INIT_INT64(name, khval_t) \ - KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal) +#define KHASH_MAP_INIT_INT64(name, khval_t) \ + KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal) typedef const char *kh_cstr_t; /*! @function @abstract Instantiate a hash map containing const char* keys @param name Name of the hash table [symbol] */ -#define KHASH_SET_INIT_STR(name) \ - KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal) +#define KHASH_SET_INIT_STR(name) KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal) /*! @function @abstract Instantiate a hash map containing const char* keys @param name Name of the hash table [symbol] @param khval_t Type of values [type] */ -#define KHASH_MAP_INIT_STR(name, khval_t) \ - KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal) +#define KHASH_MAP_INIT_STR(name, khval_t) KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal) #endif /* __AC_KHASH_H */ diff --git a/src/server/ns_turn_maps.c b/src/server/ns_turn_maps.c index 34dc6bf..9416636 100644 --- a/src/server/ns_turn_maps.c +++ b/src/server/ns_turn_maps.c @@ -39,16 +39,16 @@ KHASH_MAP_INIT_INT64(3, ur_map_value_type) #define MAGIC_HASH ((uint64_t)(0x90ABCDEFL)) struct _ur_map { - khash_t(3) *h; + khash_t(3) * h; uint64_t magic; TURN_MUTEX_DECLARE(mutex) }; -static int ur_map_init(ur_map* map) { - if(map) { - map->h=kh_init(3); - if(map->h) { - map->magic=MAGIC_HASH; +static int ur_map_init(ur_map *map) { + if (map) { + map->h = kh_init(3); + if (map->h) { + map->magic = MAGIC_HASH; TURN_MUTEX_INIT_RECURSIVE(&(map->mutex)); return 0; } @@ -56,11 +56,11 @@ static int ur_map_init(ur_map* map) { return -1; } -#define ur_map_valid(map) ((map) && ((map)->h) && ((map)->magic==MAGIC_HASH)) +#define ur_map_valid(map) ((map) && ((map)->h) && ((map)->magic == MAGIC_HASH)) -ur_map* ur_map_create(void) { - ur_map *map=(ur_map*)malloc(sizeof(ur_map)); - if(ur_map_init(map)<0) { +ur_map *ur_map_create(void) { + ur_map *map = (ur_map *)malloc(sizeof(ur_map)); + if (ur_map_init(map) < 0) { free(map); return NULL; } @@ -72,19 +72,20 @@ ur_map* ur_map_create(void) { * 0 - success * -1 - error */ -int ur_map_put(ur_map* map, ur_map_key_type key, ur_map_value_type value) { - if(!ur_map_valid(map)) return -1; +int ur_map_put(ur_map *map, ur_map_key_type key, ur_map_value_type value) { + if (!ur_map_valid(map)) + return -1; else { - int ret=0; + int ret = 0; khiter_t k; k = kh_get(3, map->h, key); - if(k != kh_end(map->h)) { + if (k != kh_end(map->h)) { kh_del(3, map->h, k); } - - k = kh_put(3,map->h,key,&ret); + + k = kh_put(3, map->h, key, &ret); if (!ret) { kh_del(3, map->h, k); @@ -102,15 +103,17 @@ int ur_map_put(ur_map* map, ur_map_key_type key, ur_map_value_type value) { * 1 - success * 0 - not found */ -int ur_map_get(const ur_map* map, ur_map_key_type key, ur_map_value_type *value) { - if(!ur_map_valid(map)) return 0; +int ur_map_get(const ur_map *map, ur_map_key_type key, ur_map_value_type *value) { + if (!ur_map_valid(map)) + return 0; else { khiter_t k; k = kh_get(3, map->h, key); - if((k != kh_end(map->h)) && kh_exist(map->h,k)) { - if(value) *value=kh_value(map->h,k); + if ((k != kh_end(map->h)) && kh_exist(map->h, k)) { + if (value) + *value = kh_value(map->h, k); return 1; } @@ -123,18 +126,19 @@ int ur_map_get(const ur_map* map, ur_map_key_type key, ur_map_value_type *value) * 1 - success * 0 - not found */ -int ur_map_del(ur_map* map, ur_map_key_type key,ur_map_del_func delfunc) { - if(!ur_map_valid(map)) return 0; +int ur_map_del(ur_map *map, ur_map_key_type key, ur_map_del_func delfunc) { + if (!ur_map_valid(map)) + return 0; else { khiter_t k; k = kh_get(3, map->h, key); - if((k != kh_end(map->h)) && kh_exist(map->h,k)) { - if(delfunc) { - delfunc(kh_value(map->h,k)); + if ((k != kh_end(map->h)) && kh_exist(map->h, k)) { + if (delfunc) { + delfunc(kh_value(map->h, k)); } - kh_del(3,map->h,k); + kh_del(3, map->h, k); return 1; } @@ -147,14 +151,15 @@ int ur_map_del(ur_map* map, ur_map_key_type key,ur_map_del_func delfunc) { * 1 - success * 0 - not found */ -int ur_map_exist(const ur_map* map, ur_map_key_type key) { - if(!ur_map_valid(map)) return 0; +int ur_map_exist(const ur_map *map, ur_map_key_type key) { + if (!ur_map_valid(map)) + return 0; else { khiter_t k; k = kh_get(3, map->h, key); - if((k != kh_end(map->h)) && kh_exist(map->h,k)) { + if ((k != kh_end(map->h)) && kh_exist(map->h, k)) { return 1; } @@ -162,73 +167,69 @@ int ur_map_exist(const ur_map* map, ur_map_key_type key) { } } -void ur_map_free(ur_map** map) { - if(map && ur_map_valid(*map)) { - { - static int khctest=0; - if(khctest) - kh_clear(3,(*map)->h); - } - kh_destroy(3,(*map)->h); - (*map)->h=NULL; - (*map)->magic=0; +void ur_map_free(ur_map **map) { + if (map && ur_map_valid(*map)) { + { + static int khctest = 0; + if (khctest) + kh_clear(3, (*map)->h); + } + kh_destroy(3, (*map)->h); + (*map)->h = NULL; + (*map)->magic = 0; TURN_MUTEX_DESTROY(&((*map)->mutex)); free(*map); - *map=NULL; + *map = NULL; } } -size_t ur_map_size(const ur_map* map) { - if(ur_map_valid(map)) { +size_t ur_map_size(const ur_map *map) { + if (ur_map_valid(map)) { return kh_size(map->h); } else { return 0; } } -int ur_map_foreach(ur_map* map, foreachcb_type func) { - if(map && func && ur_map_valid(map)) { +int ur_map_foreach(ur_map *map, foreachcb_type func) { + if (map && func && ur_map_valid(map)) { khiter_t k; for (k = kh_begin((*map)->h); k != kh_end(map->h); ++k) { if (kh_exist(map->h, k)) { - if(func((ur_map_key_type)(kh_key(map->h, k)), - (ur_map_value_type)(kh_value(map->h, k)))) { - return 1; - } + if (func((ur_map_key_type)(kh_key(map->h, k)), (ur_map_value_type)(kh_value(map->h, k)))) { + return 1; + } } } } return 0; } -int ur_map_foreach_arg(const ur_map* map, foreachcb_arg_type func, void* arg) { - if(map && func && ur_map_valid(map)) { +int ur_map_foreach_arg(const ur_map *map, foreachcb_arg_type func, void *arg) { + if (map && func && ur_map_valid(map)) { khiter_t k; for (k = kh_begin((*map)->h); k != kh_end(map->h); ++k) { if (kh_exist(map->h, k)) { - if(func((ur_map_key_type)(kh_key(map->h, k)), - (ur_map_value_type)(kh_value(map->h, k)), - arg) - ) { - return 1; - } + if (func((ur_map_key_type)(kh_key(map->h, k)), (ur_map_value_type)(kh_value(map->h, k)), arg)) { + return 1; + } } } } return 0; } -int ur_map_lock(const ur_map* map) { - if(ur_map_valid(map)) { - TURN_MUTEX_LOCK((const turn_mutex*)&(map->mutex)); +int ur_map_lock(const ur_map *map) { + if (ur_map_valid(map)) { + TURN_MUTEX_LOCK((const turn_mutex *)&(map->mutex)); return 0; } return -1; } -int ur_map_unlock(const ur_map* map) { - if(ur_map_valid(map)) { - TURN_MUTEX_UNLOCK((const turn_mutex*)&(map->mutex)); +int ur_map_unlock(const ur_map *map) { + if (ur_map_valid(map)) { + TURN_MUTEX_UNLOCK((const turn_mutex *)&(map->mutex)); return 0; } return -1; @@ -236,11 +237,10 @@ int ur_map_unlock(const ur_map* map) { //////////////////// LOCAL MAPS //////////////////////////////////// -void lm_map_init(lm_map *map) -{ - if(map) { - memset(map, 0, sizeof(lm_map)); - } +void lm_map_init(lm_map *map) { + if (map) { + memset(map, 0, sizeof(lm_map)); + } } /** @@ -249,79 +249,78 @@ void lm_map_init(lm_map *map) * -1 - error */ -int lm_map_put(lm_map* map, ur_map_key_type key, ur_map_value_type value) -{ - int ret = -1; - if(map && key && value) { +int lm_map_put(lm_map *map, ur_map_key_type key, ur_map_value_type value) { + int ret = -1; + if (map && key && value) { - size_t index = (size_t)(key & (LM_MAP_HASH_SIZE - 1)); - lm_map_array *a = &(map->table[index]); + size_t index = (size_t)(key & (LM_MAP_HASH_SIZE - 1)); + lm_map_array *a = &(map->table[index]); - size_t i; + size_t i; - for(i=0;imain_keys[i]; - ur_map_value_type value0 = a->main_values[i]; + ur_map_key_type key0 = a->main_keys[i]; + ur_map_value_type value0 = a->main_values[i]; - if(key0 == key) { - if(value0 == value) { - return 0; - } else { - return -1; - } - } + if (key0 == key) { + if (value0 == value) { + return 0; + } else { + return -1; + } + } - if(!key0 || !value0) { - a->main_keys[i] = key; - a->main_values[i] = value; - return 0; - } - } + if (!key0 || !value0) { + a->main_keys[i] = key; + a->main_values[i] = value; + return 0; + } + } - size_t esz = a->extra_sz; - if(esz && a->extra_keys && a->extra_values) { - for(i=0;iextra_keys[i]; - ur_map_value_type *valuep = a->extra_values[i]; - if(keyp && valuep) { - if(!(*keyp) || !(*valuep)) { - *keyp = key; - *valuep = value; - return 0; - } - } else { - if(!(*keyp)) { - a->extra_keys[i] = (ur_map_key_type*)malloc(sizeof(ur_map_key_type)); - keyp = a->extra_keys[i]; - } - if(!(*valuep)) { - a->extra_values[i] = (ur_map_value_type*)malloc(sizeof(ur_map_value_type)); - valuep = a->extra_values[i]; - } - *keyp = key; - *valuep = value; - return 0; - } - } - } + size_t esz = a->extra_sz; + if (esz && a->extra_keys && a->extra_values) { + for (i = 0; i < esz; ++i) { + ur_map_key_type *keyp = a->extra_keys[i]; + ur_map_value_type *valuep = a->extra_values[i]; + if (keyp && valuep) { + if (!(*keyp) || !(*valuep)) { + *keyp = key; + *valuep = value; + return 0; + } + } else { + if (!(*keyp)) { + a->extra_keys[i] = (ur_map_key_type *)malloc(sizeof(ur_map_key_type)); + keyp = a->extra_keys[i]; + } + if (!(*valuep)) { + a->extra_values[i] = (ur_map_value_type *)malloc(sizeof(ur_map_value_type)); + valuep = a->extra_values[i]; + } + *keyp = key; + *valuep = value; + return 0; + } + } + } - size_t old_sz = esz; - size_t old_sz_mem = esz * sizeof(ur_map_key_type*); - a->extra_keys = (ur_map_key_type**)realloc(a->extra_keys,old_sz_mem + sizeof(ur_map_key_type*)); - a->extra_keys[old_sz] = (ur_map_key_type*)malloc(sizeof(ur_map_key_type)); - *(a->extra_keys[old_sz]) = key; + size_t old_sz = esz; + size_t old_sz_mem = esz * sizeof(ur_map_key_type *); + a->extra_keys = (ur_map_key_type **)realloc(a->extra_keys, old_sz_mem + sizeof(ur_map_key_type *)); + a->extra_keys[old_sz] = (ur_map_key_type *)malloc(sizeof(ur_map_key_type)); + *(a->extra_keys[old_sz]) = key; - old_sz_mem = esz * sizeof(ur_map_value_type*); - a->extra_values = (ur_map_value_type**)realloc(a->extra_values,old_sz_mem + sizeof(ur_map_value_type*)); - a->extra_values[old_sz] = (ur_map_value_type*)malloc(sizeof(ur_map_value_type)); - *(a->extra_values[old_sz]) = value; + old_sz_mem = esz * sizeof(ur_map_value_type *); + a->extra_values = (ur_map_value_type **)realloc(a->extra_values, old_sz_mem + sizeof(ur_map_value_type *)); + a->extra_values[old_sz] = (ur_map_value_type *)malloc(sizeof(ur_map_value_type)); + *(a->extra_values[old_sz]) = value; - a->extra_sz += 1; + a->extra_sz += 1; - return 0; - } - return ret; + return 0; + } + return ret; } /** @@ -330,43 +329,42 @@ int lm_map_put(lm_map* map, ur_map_key_type key, ur_map_value_type value) * 0 - not found */ -int lm_map_get(const lm_map* map, ur_map_key_type key, ur_map_value_type *value) -{ - int ret = 0; - if(map && key) { - size_t index = (size_t)(key & (LM_MAP_HASH_SIZE - 1)); - const lm_map_array *a = &(map->table[index]); +int lm_map_get(const lm_map *map, ur_map_key_type key, ur_map_value_type *value) { + int ret = 0; + if (map && key) { + size_t index = (size_t)(key & (LM_MAP_HASH_SIZE - 1)); + const lm_map_array *a = &(map->table[index]); - size_t i; + size_t i; - for(i=0;imain_keys[i]; - if((key0 == key) && a->main_values[i]) { - if(value) { - *value = a->main_values[i]; - } - return 1; - } - } + ur_map_key_type key0 = a->main_keys[i]; + if ((key0 == key) && a->main_values[i]) { + if (value) { + *value = a->main_values[i]; + } + return 1; + } + } - size_t esz = a->extra_sz; - if(esz && a->extra_keys && a->extra_values) { - for(i=0;iextra_keys[i]; - ur_map_value_type *valuep = a->extra_values[i]; - if(keyp && valuep) { - if(*keyp == key) { - if(value) - *value = *valuep; - return 1; - } - } - } - } - } + size_t esz = a->extra_sz; + if (esz && a->extra_keys && a->extra_values) { + for (i = 0; i < esz; ++i) { + ur_map_key_type *keyp = a->extra_keys[i]; + ur_map_value_type *valuep = a->extra_values[i]; + if (keyp && valuep) { + if (*keyp == key) { + if (value) + *value = *valuep; + return 1; + } + } + } + } + } - return ret; + return ret; } /** * @ret: @@ -374,49 +372,48 @@ int lm_map_get(const lm_map* map, ur_map_key_type key, ur_map_value_type *value) * 0 - not found */ -int lm_map_del(lm_map* map, ur_map_key_type key,ur_map_del_func delfunc) -{ - int ret = 0; +int lm_map_del(lm_map *map, ur_map_key_type key, ur_map_del_func delfunc) { + int ret = 0; - if(map && key) { - size_t index = (size_t)(key & (LM_MAP_HASH_SIZE - 1)); - lm_map_array *a = &(map->table[index]); + if (map && key) { + size_t index = (size_t)(key & (LM_MAP_HASH_SIZE - 1)); + lm_map_array *a = &(map->table[index]); - size_t i; + size_t i; - for(i=0;imain_keys[i]; + ur_map_key_type key0 = a->main_keys[i]; - if((key0 == key) && a->main_values[i]) { - if(delfunc) { - delfunc(a->main_values[i]); - } - a->main_keys[i] = 0; - a->main_values[i] = 0; - return 1; - } - } + if ((key0 == key) && a->main_values[i]) { + if (delfunc) { + delfunc(a->main_values[i]); + } + a->main_keys[i] = 0; + a->main_values[i] = 0; + return 1; + } + } - size_t esz = a->extra_sz; - if(esz && a->extra_keys && a->extra_values) { - for(i=0;iextra_keys[i]; - ur_map_value_type *valuep = a->extra_values[i]; - if(keyp && valuep) { - if(*keyp == key) { - if(delfunc) - delfunc(*valuep); - *keyp = 0; - *valuep = 0; - return 1; - } - } - } - } - } + size_t esz = a->extra_sz; + if (esz && a->extra_keys && a->extra_values) { + for (i = 0; i < esz; ++i) { + ur_map_key_type *keyp = a->extra_keys[i]; + ur_map_value_type *valuep = a->extra_values[i]; + if (keyp && valuep) { + if (*keyp == key) { + if (delfunc) + delfunc(*valuep); + *keyp = 0; + *valuep = 0; + return 1; + } + } + } + } + } - return ret; + return ret; } /** * @ret: @@ -424,369 +421,359 @@ int lm_map_del(lm_map* map, ur_map_key_type key,ur_map_del_func delfunc) * 0 - not found */ -int lm_map_exist(const lm_map* map, ur_map_key_type key) -{ - return lm_map_get(map, key, NULL); +int lm_map_exist(const lm_map *map, ur_map_key_type key) { return lm_map_get(map, key, NULL); } + +void lm_map_clean(lm_map *map) { + size_t j; + for (j = 0; j < LM_MAP_HASH_SIZE; ++j) { + + lm_map_array *a = &(map->table[j]); + + size_t esz = a->extra_sz; + if (esz) { + size_t i; + if (a->extra_keys) { + for (i = 0; i < esz; ++i) { + ur_map_key_type *keyp = a->extra_keys[i]; + if (keyp) { + *keyp = 0; + free(keyp); + } + } + free(a->extra_keys); + a->extra_keys = NULL; + } + if (a->extra_values) { + for (i = 0; i < esz; ++i) { + ur_map_value_type *valuep = a->extra_values[i]; + if (valuep) { + *valuep = 0; + free(valuep); + } + } + free(a->extra_values); + a->extra_values = NULL; + } + } + } + + lm_map_init(map); } -void lm_map_clean(lm_map* map) -{ - size_t j; - for(j=0;jtable[j]); + if (map) { - size_t esz = a->extra_sz; - if(esz) { - size_t i; - if(a->extra_keys) { - for(i=0;iextra_keys[i]; - if(keyp) { - *keyp = 0; - free(keyp); - } - } - free(a->extra_keys); - a->extra_keys = NULL; - } - if(a->extra_values) { - for(i=0;iextra_values[i]; - if(valuep) { - *valuep = 0; - free(valuep); - } - } - free(a->extra_values); - a->extra_values = NULL; - } - } - } + size_t i; - lm_map_init(map); + for (i = 0; i < LM_MAP_HASH_SIZE; ++i) { + + const lm_map_array *a = &(map->table[i]); + + size_t j; + + for (j = 0; j < LM_MAP_ARRAY_SIZE; ++j) { + if (a->main_keys[j] && a->main_values[j]) { + ++ret; + } + } + + size_t esz = a->extra_sz; + if (esz && a->extra_values && a->extra_keys) { + for (j = 0; j < esz; ++j) { + if (*(a->extra_keys[j]) && *(a->extra_values[j])) { + ++ret; + } + } + } + } + } + + return ret; } -size_t lm_map_size(const lm_map* map) -{ - size_t ret = 0; +int lm_map_foreach(lm_map *map, foreachcb_type func) { + size_t ret = 0; - if(map) { + if (map) { - size_t i; + size_t i; - for(i=0;itable[i]); + lm_map_array *a = &(map->table[i]); - size_t j; + size_t j; - for(j=0;jmain_keys[j] && a->main_values[j]) { - ++ret; - } - } + for (j = 0; j < LM_MAP_ARRAY_SIZE; ++j) { + if (a->main_keys[j] && a->main_values[j]) { + if (func((ur_map_key_type)a->main_keys[j], (ur_map_value_type)a->main_values[j])) { + return 1; + } + } + } - size_t esz = a->extra_sz; - if(esz && a->extra_values && a->extra_keys) { - for(j=0;jextra_keys[j]) && *(a->extra_values[j])) { - ++ret; - } - } - } - } - } + size_t esz = a->extra_sz; + if (esz && a->extra_values && a->extra_keys) { + for (j = 0; j < esz; ++j) { + if (*(a->extra_keys[j]) && *(a->extra_values[j])) { + if (func((ur_map_key_type) * (a->extra_keys[j]), (ur_map_value_type) * (a->extra_values[j]))) { + return 1; + } + } + } + } + } + } - return ret; + return ret; } -int lm_map_foreach(lm_map* map, foreachcb_type func) -{ - size_t ret = 0; +int lm_map_foreach_arg(lm_map *map, foreachcb_arg_type func, void *arg) { + size_t ret = 0; - if(map) { + if (map) { - size_t i; + size_t i; - for(i=0;itable[i]); + lm_map_array *a = &(map->table[i]); - size_t j; + size_t j; - for(j=0;jmain_keys[j] && a->main_values[j]) { - if(func((ur_map_key_type)a->main_keys[j], - (ur_map_value_type)a->main_values[j])) { - return 1; - } - } - } + for (j = 0; j < LM_MAP_ARRAY_SIZE; ++j) { + if (a->main_keys[j] && a->main_values[j]) { + if (func((ur_map_key_type)a->main_keys[j], (ur_map_value_type)a->main_values[j], arg)) { + return 1; + } + } + } - size_t esz = a->extra_sz; - if(esz && a->extra_values && a->extra_keys) { - for(j=0;jextra_keys[j]) && *(a->extra_values[j])) { - if(func((ur_map_key_type)*(a->extra_keys[j]), - (ur_map_value_type)*(a->extra_values[j]))) { - return 1; - } - } - } - } - } - } + size_t esz = a->extra_sz; + if (esz && a->extra_values && a->extra_keys) { + for (j = 0; j < esz; ++j) { + if (*(a->extra_keys[j]) && *(a->extra_values[j])) { + if (func((ur_map_key_type) * (a->extra_keys[j]), (ur_map_value_type) * (a->extra_values[j]), arg)) { + return 1; + } + } + } + } + } + } - return ret; -} - -int lm_map_foreach_arg(lm_map* map, foreachcb_arg_type func, void* arg) -{ - size_t ret = 0; - - if(map) { - - size_t i; - - for(i=0;itable[i]); - - size_t j; - - for(j=0;jmain_keys[j] && a->main_values[j]) { - if(func((ur_map_key_type)a->main_keys[j], - (ur_map_value_type)a->main_values[j], - arg)) { - return 1; - } - } - } - - size_t esz = a->extra_sz; - if(esz && a->extra_values && a->extra_keys) { - for(j=0;jextra_keys[j]) && *(a->extra_values[j])) { - if(func((ur_map_key_type)*(a->extra_keys[j]), - (ur_map_value_type)*(a->extra_values[j]), - arg)) { - return 1; - } - } - } - } - } - } - - return ret; + return ret; } //////////////////// ADDR LISTS /////////////////////////////////// -static void addr_list_free(addr_list_header* slh) { - if(slh) { - if(slh->extra_list) { +static void addr_list_free(addr_list_header *slh) { + if (slh) { + if (slh->extra_list) { free(slh->extra_list); } memset(slh, 0, sizeof(addr_list_header)); } } - -static void addr_list_add(addr_list_header* slh, const ioa_addr* key, ur_addr_map_value_type value) { - if(!key || !value) return; +static void addr_list_add(addr_list_header *slh, const ioa_addr *key, ur_addr_map_value_type value) { + + if (!key || !value) + return; addr_elem *elem = NULL; size_t i; - for(i=0;imain_list[i].value)) { - elem = &(slh->main_list[i]); - break; - } + for (i = 0; i < ADDR_ARRAY_SIZE; ++i) { + if (!(slh->main_list[i].value)) { + elem = &(slh->main_list[i]); + break; + } } - if(!elem && slh->extra_list) { - for(i=0;iextra_sz;++i) { - if(!(slh->extra_list[i].value)) { - elem = &(slh->extra_list[i]); - break; - } - } + if (!elem && slh->extra_list) { + for (i = 0; i < slh->extra_sz; ++i) { + if (!(slh->extra_list[i].value)) { + elem = &(slh->extra_list[i]); + break; + } + } } - if(!elem) { - size_t old_sz = slh->extra_sz; - size_t old_sz_mem = old_sz * sizeof(addr_elem); - slh->extra_list = (addr_elem*)realloc(slh->extra_list, old_sz_mem + sizeof(addr_elem)); - elem = &(slh->extra_list[old_sz]); - slh->extra_sz += 1; + if (!elem) { + size_t old_sz = slh->extra_sz; + size_t old_sz_mem = old_sz * sizeof(addr_elem); + slh->extra_list = (addr_elem *)realloc(slh->extra_list, old_sz_mem + sizeof(addr_elem)); + elem = &(slh->extra_list[old_sz]); + slh->extra_sz += 1; } - addr_cpy(&(elem->key),key); - elem->value=value; + addr_cpy(&(elem->key), key); + elem->value = value; } -static void addr_list_remove(addr_list_header* slh, const ioa_addr* key, - ur_addr_map_func delfunc, int *counter) { - if(!slh || !key) return; +static void addr_list_remove(addr_list_header *slh, const ioa_addr *key, ur_addr_map_func delfunc, int *counter) { + if (!slh || !key) + return; - if(counter) - *counter = 0; + if (counter) + *counter = 0; size_t i; - for(i=0;imain_list[i]); - if(elem->value) { - if(addr_eq(&(elem->key),key)) { - if(delfunc && elem->value) - delfunc(elem->value); - elem->value = 0; - if(counter) { - *counter += 1; - } - } - } + for (i = 0; i < ADDR_ARRAY_SIZE; ++i) { + addr_elem *elem = &(slh->main_list[i]); + if (elem->value) { + if (addr_eq(&(elem->key), key)) { + if (delfunc && elem->value) + delfunc(elem->value); + elem->value = 0; + if (counter) { + *counter += 1; + } + } + } } - if(slh->extra_list) { - for(i=0;iextra_sz;++i) { - addr_elem *elem=&(slh->extra_list[i]); - if(elem->value) { - if(addr_eq(&(elem->key),key)) { - if(delfunc && elem->value) - delfunc(elem->value); - elem->value = 0; - if(counter) { - *counter += 1; - } - } - } - } + if (slh->extra_list) { + for (i = 0; i < slh->extra_sz; ++i) { + addr_elem *elem = &(slh->extra_list[i]); + if (elem->value) { + if (addr_eq(&(elem->key), key)) { + if (delfunc && elem->value) + delfunc(elem->value); + elem->value = 0; + if (counter) { + *counter += 1; + } + } + } + } } } -static void addr_list_foreach(addr_list_header* slh, ur_addr_map_func func) { - if(slh && func) { +static void addr_list_foreach(addr_list_header *slh, ur_addr_map_func func) { + if (slh && func) { - size_t i; + size_t i; - for(i=0;imain_list[i]); - if(elem->value) { - func(elem->value); - } - } + for (i = 0; i < ADDR_ARRAY_SIZE; ++i) { + addr_elem *elem = &(slh->main_list[i]); + if (elem->value) { + func(elem->value); + } + } - if(slh->extra_list) { - for(i=0;iextra_sz;++i) { - addr_elem *elem=&(slh->extra_list[i]); - if(elem->value) { - func(elem->value); - } - } - } + if (slh->extra_list) { + for (i = 0; i < slh->extra_sz; ++i) { + addr_elem *elem = &(slh->extra_list[i]); + if (elem->value) { + func(elem->value); + } + } + } } } -static size_t addr_list_num_elements(const addr_list_header* slh) { +static size_t addr_list_num_elements(const addr_list_header *slh) { - size_t ret = 0; + size_t ret = 0; - if (slh) { + if (slh) { - size_t i; + size_t i; - for (i = 0; i < ADDR_ARRAY_SIZE; ++i) { - const addr_elem *elem = &(slh->main_list[i]); - if (elem->value) { - ++ret; - } - } + for (i = 0; i < ADDR_ARRAY_SIZE; ++i) { + const addr_elem *elem = &(slh->main_list[i]); + if (elem->value) { + ++ret; + } + } - if (slh->extra_list) { - for (i = 0; i < slh->extra_sz; ++i) { - addr_elem *elem = &(slh->extra_list[i]); - if (elem->value) { - ++ret; - } - } - } - } + if (slh->extra_list) { + for (i = 0; i < slh->extra_sz; ++i) { + addr_elem *elem = &(slh->extra_list[i]); + if (elem->value) { + ++ret; + } + } + } + } - return ret; + return ret; } -static size_t addr_list_size(const addr_list_header* slh) { +static size_t addr_list_size(const addr_list_header *slh) { - size_t ret = 0; + size_t ret = 0; - if (slh) { + if (slh) { - ret += ADDR_ARRAY_SIZE; + ret += ADDR_ARRAY_SIZE; - ret += slh->extra_sz; - } + ret += slh->extra_sz; + } - return ret; + return ret; } -static addr_elem* addr_list_get(addr_list_header* slh, const ioa_addr* key) { +static addr_elem *addr_list_get(addr_list_header *slh, const ioa_addr *key) { - if(!slh || !key) return NULL; + if (!slh || !key) + return NULL; size_t i; - for(i=0;imain_list[i]); - if(elem->value) { - if(addr_eq(&(elem->key),key)) { - return elem; - } - } + for (i = 0; i < ADDR_ARRAY_SIZE; ++i) { + addr_elem *elem = &(slh->main_list[i]); + if (elem->value) { + if (addr_eq(&(elem->key), key)) { + return elem; + } + } } - if(slh->extra_list) { - for(i=0;iextra_sz;++i) { - addr_elem *elem=&(slh->extra_list[i]); - if(elem->value) { - if(addr_eq(&(elem->key),key)) { - return elem; - } - } - } + if (slh->extra_list) { + for (i = 0; i < slh->extra_sz; ++i) { + addr_elem *elem = &(slh->extra_list[i]); + if (elem->value) { + if (addr_eq(&(elem->key), key)) { + return elem; + } + } + } } return NULL; } -static const addr_elem* addr_list_get_const(const addr_list_header* slh, const ioa_addr* key) { +static const addr_elem *addr_list_get_const(const addr_list_header *slh, const ioa_addr *key) { - if(!slh || !key) return NULL; + if (!slh || !key) + return NULL; size_t i; - for(i=0;imain_list[i]); - if(elem->value) { - if(addr_eq(&(elem->key),key)) { - return elem; - } - } + for (i = 0; i < ADDR_ARRAY_SIZE; ++i) { + const addr_elem *elem = &(slh->main_list[i]); + if (elem->value) { + if (addr_eq(&(elem->key), key)) { + return elem; + } + } } - if(slh->extra_list) { - for(i=0;iextra_sz;++i) { - const addr_elem *elem=&(slh->extra_list[i]); - if(elem->value) { - if(addr_eq(&(elem->key),key)) { - return elem; - } - } - } + if (slh->extra_list) { + for (i = 0; i < slh->extra_sz; ++i) { + const addr_elem *elem = &(slh->extra_list[i]); + if (elem->value) { + if (addr_eq(&(elem->key), key)) { + return elem; + } + } + } } return NULL; @@ -798,19 +785,19 @@ static const addr_elem* addr_list_get_const(const addr_list_header* slh, const i #define get_addr_list_header(map, key) (&((map)->lists[addr_map_index((key))])) -#define ur_addr_map_valid(map) ((map) && ((map)->magic==MAGIC_HASH)) +#define ur_addr_map_valid(map) ((map) && ((map)->magic == MAGIC_HASH)) -void ur_addr_map_init(ur_addr_map* map) { - if(map) { +void ur_addr_map_init(ur_addr_map *map) { + if (map) { memset(map, 0, sizeof(ur_addr_map)); - map->magic=MAGIC_HASH; + map->magic = MAGIC_HASH; } } -void ur_addr_map_clean(ur_addr_map* map) { - if(map && ur_addr_map_valid(map)) { - uint32_t i=0; - for(i=0;ilists[i])); } memset(map, 0, sizeof(ur_addr_map)); @@ -823,19 +810,20 @@ void ur_addr_map_clean(ur_addr_map* map) { * -1 - error * if the addr key exists, the value is updated. */ -int ur_addr_map_put(ur_addr_map* map, ioa_addr* key, ur_addr_map_value_type value) { +int ur_addr_map_put(ur_addr_map *map, ioa_addr *key, ur_addr_map_value_type value) { - if(!ur_addr_map_valid(map)) return -1; + if (!ur_addr_map_valid(map)) + return -1; else { - addr_list_header* slh = get_addr_list_header(map, key); + addr_list_header *slh = get_addr_list_header(map, key); - addr_elem* elem = addr_list_get(slh, key); - if(elem) { - elem->value=value; + addr_elem *elem = addr_list_get(slh, key); + if (elem) { + elem->value = value; } else { - addr_list_add(slh,key,value); + addr_list_add(slh, key, value); } return 0; @@ -847,17 +835,19 @@ int ur_addr_map_put(ur_addr_map* map, ioa_addr* key, ur_addr_map_value_type valu * 1 - success * 0 - not found */ -int ur_addr_map_get(const ur_addr_map* map, ioa_addr* key, ur_addr_map_value_type *value) { +int ur_addr_map_get(const ur_addr_map *map, ioa_addr *key, ur_addr_map_value_type *value) { - if(!ur_addr_map_valid(map)) return 0; + if (!ur_addr_map_valid(map)) + return 0; else { - const addr_list_header* slh = get_addr_list_header(map, key); + const addr_list_header *slh = get_addr_list_header(map, key); const addr_elem *elem = addr_list_get_const(slh, key); - if(elem) { - if(value) *value=elem->value; + if (elem) { + if (value) + *value = elem->value; return 1; } @@ -870,19 +860,20 @@ int ur_addr_map_get(const ur_addr_map* map, ioa_addr* key, ur_addr_map_value_typ * 1 - success * 0 - not found */ -int ur_addr_map_del(ur_addr_map* map, ioa_addr* key,ur_addr_map_func delfunc) { +int ur_addr_map_del(ur_addr_map *map, ioa_addr *key, ur_addr_map_func delfunc) { - if(!ur_addr_map_valid(map)) return 0; + if (!ur_addr_map_valid(map)) + return 0; else { - addr_list_header* slh = get_addr_list_header(map, key); + addr_list_header *slh = get_addr_list_header(map, key); - int counter=0; + int counter = 0; addr_list_remove(slh, key, delfunc, &counter); - return (counter>0); + return (counter > 0); } } @@ -891,58 +882,58 @@ int ur_addr_map_del(ur_addr_map* map, ioa_addr* key,ur_addr_map_func delfunc) { * 1 - success * 0 - not found */ -void ur_addr_map_foreach(ur_addr_map* map, ur_addr_map_func func) { +void ur_addr_map_foreach(ur_addr_map *map, ur_addr_map_func func) { - if(ur_addr_map_valid(map)) { + if (ur_addr_map_valid(map)) { + + uint32_t i = 0; + for (i = 0; i < ADDR_MAP_SIZE; i++) { + + addr_list_header *slh = &(map->lists[i]); - uint32_t i=0; - for(i=0;ilists[i]); - addr_list_foreach(slh, func); } } } -size_t ur_addr_map_num_elements(const ur_addr_map* map) { +size_t ur_addr_map_num_elements(const ur_addr_map *map) { - size_t ret = 0; + size_t ret = 0; - if (ur_addr_map_valid(map)) { - uint32_t i = 0; - for (i = 0; i < ADDR_MAP_SIZE; i++) { + if (ur_addr_map_valid(map)) { + uint32_t i = 0; + for (i = 0; i < ADDR_MAP_SIZE; i++) { - const addr_list_header* slh = &(map->lists[i]); + const addr_list_header *slh = &(map->lists[i]); - ret += addr_list_num_elements(slh); - } - } + ret += addr_list_num_elements(slh); + } + } - return ret; + return ret; } -size_t ur_addr_map_size(const ur_addr_map* map) { +size_t ur_addr_map_size(const ur_addr_map *map) { - size_t ret = 0; + size_t ret = 0; - if (ur_addr_map_valid(map)) { - uint32_t i = 0; - for (i = 0; i < ADDR_MAP_SIZE; i++) { + if (ur_addr_map_valid(map)) { + uint32_t i = 0; + for (i = 0; i < ADDR_MAP_SIZE; i++) { - const addr_list_header* slh = &(map->lists[i]); + const addr_list_header *slh = &(map->lists[i]); - ret += addr_list_size(slh); - } - } + ret += addr_list_size(slh); + } + } - return ret; + return ret; } //////////////////// STRING LISTS /////////////////////////////////// typedef struct _string_list { - struct _string_list* next; + struct _string_list *next; } string_list; typedef struct _string_elem { @@ -957,61 +948,67 @@ typedef struct _string_list_header { } string_list_header; static size_t string_list_size(const string_list *sl) { - if(!sl) return 0; - return 1+string_list_size(sl->next); + if (!sl) + return 0; + return 1 + string_list_size(sl->next); } -static void string_list_free(string_list_header* slh, ur_string_map_func del_value_func) { - if(slh) { - string_list* list=slh->list; - while(list) { - string_elem *elem=(string_elem*)list; - string_list* tail=elem->list.next; - if(elem->key) free(elem->key); - if(del_value_func && elem->value) - del_value_func(elem->value); +static void string_list_free(string_list_header *slh, ur_string_map_func del_value_func) { + if (slh) { + string_list *list = slh->list; + while (list) { + string_elem *elem = (string_elem *)list; + string_list *tail = elem->list.next; + if (elem->key) + free(elem->key); + if (del_value_func && elem->value) + del_value_func(elem->value); free(elem); - list=tail; + list = tail; } - slh->list=NULL; + slh->list = NULL; } } -static string_list* string_list_add(string_list* sl, const ur_string_map_key_type key, ur_string_map_value_type value) { - if(!key) return sl; - string_elem *elem=(string_elem*)malloc(sizeof(string_elem)); - elem->list.next=sl; - elem->key_size = strlen(key)+1; - elem->key=(char*)malloc(elem->key_size); - memcpy(elem->key,key,elem->key_size); - elem->value=value; +static string_list *string_list_add(string_list *sl, const ur_string_map_key_type key, ur_string_map_value_type value) { + if (!key) + return sl; + string_elem *elem = (string_elem *)malloc(sizeof(string_elem)); + elem->list.next = sl; + elem->key_size = strlen(key) + 1; + elem->key = (char *)malloc(elem->key_size); + memcpy(elem->key, key, elem->key_size); + elem->value = value; return &(elem->list); } -static string_list* string_list_remove(string_list* sl, const ur_string_map_key_type key, - ur_string_map_func del_value_func, int *counter) { - if(!sl || !key) return sl; - string_elem *elem=(string_elem*)sl; - string_list* tail=elem->list.next; - if(strcmp(elem->key,key)==0) { +static string_list *string_list_remove(string_list *sl, const ur_string_map_key_type key, + ur_string_map_func del_value_func, int *counter) { + if (!sl || !key) + return sl; + string_elem *elem = (string_elem *)sl; + string_list *tail = elem->list.next; + if (strcmp(elem->key, key) == 0) { free(elem->key); - if(del_value_func) - del_value_func(elem->value); + if (del_value_func) + del_value_func(elem->value); free(elem); - if(counter) *counter+=1; - sl=string_list_remove(tail, key, del_value_func, counter); + if (counter) + *counter += 1; + sl = string_list_remove(tail, key, del_value_func, counter); } else { - elem->list.next=string_list_remove(tail,key,del_value_func,counter); + elem->list.next = string_list_remove(tail, key, del_value_func, counter); } return sl; } -static string_elem* string_list_get(string_list* sl, const ur_string_map_key_type key) { +static string_elem *string_list_get(string_list *sl, const ur_string_map_key_type key) { - if(!sl || !key) return NULL; + if (!sl || !key) + return NULL; - string_elem *elem=(string_elem*)sl; - if(strcmp(elem->key,key)==0) { + string_elem *elem = (string_elem *)sl; + if (strcmp(elem->key, key) == 0) { return elem; } else { return string_list_get(elem->list.next, key); @@ -1031,7 +1028,7 @@ struct _ur_string_map { static uint32_t string_hash(const ur_string_map_key_type key) { - uint8_t *str=(uint8_t*)key; + uint8_t *str = (uint8_t *)key; uint32_t hash = 0; int c = 0; @@ -1042,18 +1039,16 @@ static uint32_t string_hash(const ur_string_map_key_type key) { return hash; } -static int string_map_index(const ur_string_map_key_type key) { - return (int)(string_hash(key) % STRING_MAP_SIZE); -} +static int string_map_index(const ur_string_map_key_type key) { return (int)(string_hash(key) % STRING_MAP_SIZE); } -static string_list_header* get_string_list_header(ur_string_map *map, const ur_string_map_key_type key) { +static string_list_header *get_string_list_header(ur_string_map *map, const ur_string_map_key_type key) { return &(map->lists[string_map_index(key)]); } -static int ur_string_map_init(ur_string_map* map) { - if(map) { +static int ur_string_map_init(ur_string_map *map) { + if (map) { memset(map, 0, sizeof(ur_string_map)); - map->magic=MAGIC_HASH; + map->magic = MAGIC_HASH; TURN_MUTEX_INIT_RECURSIVE(&(map->mutex)); @@ -1062,13 +1057,11 @@ static int ur_string_map_init(ur_string_map* map) { return -1; } -static int ur_string_map_valid(const ur_string_map *map) { - return (map && map->magic==MAGIC_HASH); -} +static int ur_string_map_valid(const ur_string_map *map) { return (map && map->magic == MAGIC_HASH); } -ur_string_map* ur_string_map_create(ur_string_map_func del_value_func) { - ur_string_map *map=(ur_string_map*)malloc(sizeof(ur_string_map)); - if(ur_string_map_init(map)<0) { +ur_string_map *ur_string_map_create(ur_string_map_func del_value_func) { + ur_string_map *map = (ur_string_map *)malloc(sizeof(ur_string_map)); + if (ur_string_map_init(map) < 0) { free(map); return NULL; } @@ -1082,25 +1075,26 @@ ur_string_map* ur_string_map_create(ur_string_map_func del_value_func) { * -1 - error * if the string key exists, and the value is different, return error. */ -int ur_string_map_put(ur_string_map* map, const ur_string_map_key_type key, ur_string_map_value_type value) { +int ur_string_map_put(ur_string_map *map, const ur_string_map_key_type key, ur_string_map_value_type value) { - if(!ur_string_map_valid(map)) return -1; + if (!ur_string_map_valid(map)) + return -1; else { - string_list_header* slh = get_string_list_header(map, key); + string_list_header *slh = get_string_list_header(map, key); string_elem *elem = string_list_get(slh->list, key); - if(elem) { - if(elem->value != value) { - if(map->del_value_func) - map->del_value_func(elem->value); - elem->value = value; + if (elem) { + if (elem->value != value) { + if (map->del_value_func) + map->del_value_func(elem->value); + elem->value = value; } return 0; } - slh->list=string_list_add(slh->list,key,value); + slh->list = string_list_add(slh->list, key, value); return 0; } @@ -1111,16 +1105,18 @@ int ur_string_map_put(ur_string_map* map, const ur_string_map_key_type key, ur_s * 1 - success * 0 - not found */ -int ur_string_map_get(ur_string_map* map, const ur_string_map_key_type key, ur_string_map_value_type *value) { +int ur_string_map_get(ur_string_map *map, const ur_string_map_key_type key, ur_string_map_value_type *value) { - if(!ur_string_map_valid(map)) return 0; + if (!ur_string_map_valid(map)) + return 0; else { - string_list_header* slh = get_string_list_header(map, key); + string_list_header *slh = get_string_list_header(map, key); string_elem *elem = string_list_get(slh->list, key); - if(elem) { - if(value) *value=elem->value; + if (elem) { + if (value) + *value = elem->value; return 1; } else { return 0; @@ -1133,50 +1129,51 @@ int ur_string_map_get(ur_string_map* map, const ur_string_map_key_type key, ur_s * 1 - success * 0 - not found */ -int ur_string_map_del(ur_string_map* map, const ur_string_map_key_type key) { +int ur_string_map_del(ur_string_map *map, const ur_string_map_key_type key) { - if(!ur_string_map_valid(map)) return 0; + if (!ur_string_map_valid(map)) + return 0; else { - string_list_header* slh = get_string_list_header(map, key); + string_list_header *slh = get_string_list_header(map, key); - int counter=0; + int counter = 0; - slh->list=string_list_remove(slh->list, key, map->del_value_func, &counter); + slh->list = string_list_remove(slh->list, key, map->del_value_func, &counter); - return (counter>0); + return (counter > 0); } } -void ur_string_map_clean(ur_string_map* map) { - if (ur_string_map_valid(map)) { - int i = 0; - for (i = 0; i < STRING_MAP_SIZE; i++) { - string_list_free(&(map->lists[i]), map->del_value_func); - } - } +void ur_string_map_clean(ur_string_map *map) { + if (ur_string_map_valid(map)) { + int i = 0; + for (i = 0; i < STRING_MAP_SIZE; i++) { + string_list_free(&(map->lists[i]), map->del_value_func); + } + } } -void ur_string_map_free(ur_string_map** map) { - if(map && ur_string_map_valid(*map)) { - int i=0; - for(i=0;ilists[i]),(*map)->del_value_func); +void ur_string_map_free(ur_string_map **map) { + if (map && ur_string_map_valid(*map)) { + int i = 0; + for (i = 0; i < STRING_MAP_SIZE; i++) { + string_list_free(&((*map)->lists[i]), (*map)->del_value_func); } - (*map)->magic=0; + (*map)->magic = 0; TURN_MUTEX_DESTROY(&((*map)->mutex)); free(*map); - *map=NULL; + *map = NULL; } } -size_t ur_string_map_size(const ur_string_map* map) { - if(ur_string_map_valid(map)) { - size_t ret=0; - int i=0; - for(i=0;ilists[i].list); +size_t ur_string_map_size(const ur_string_map *map) { + if (ur_string_map_valid(map)) { + size_t ret = 0; + int i = 0; + for (i = 0; i < STRING_MAP_SIZE; i++) { + ret += string_list_size(map->lists[i].list); } return ret; } else { @@ -1184,17 +1181,17 @@ size_t ur_string_map_size(const ur_string_map* map) { } } -int ur_string_map_lock(const ur_string_map* map) { - if(ur_string_map_valid(map)) { - TURN_MUTEX_LOCK((const turn_mutex*)&(map->mutex)); +int ur_string_map_lock(const ur_string_map *map) { + if (ur_string_map_valid(map)) { + TURN_MUTEX_LOCK((const turn_mutex *)&(map->mutex)); return 0; } return -1; } -int ur_string_map_unlock(const ur_string_map* map) { - if(ur_string_map_valid(map)) { - TURN_MUTEX_UNLOCK((const turn_mutex*)&(map->mutex)); +int ur_string_map_unlock(const ur_string_map *map) { + if (ur_string_map_valid(map)) { + TURN_MUTEX_UNLOCK((const turn_mutex *)&(map->mutex)); return 0; } return -1; diff --git a/src/server/ns_turn_maps.h b/src/server/ns_turn_maps.h index 21dc827..cab2dbf 100644 --- a/src/server/ns_turn_maps.h +++ b/src/server/ns_turn_maps.h @@ -50,13 +50,11 @@ typedef uintptr_t ur_map_value_type; typedef void (*ur_map_del_func)(ur_map_value_type); typedef int (*foreachcb_type)(ur_map_key_type key, ur_map_value_type value); -typedef int (*foreachcb_arg_type)(ur_map_key_type key, - ur_map_value_type value, - void *arg); +typedef int (*foreachcb_arg_type)(ur_map_key_type key, ur_map_value_type value, void *arg); ///////////// non-local map ///////////////////// -ur_map* ur_map_create(void); +ur_map *ur_map_create(void); /** * @ret: @@ -64,7 +62,7 @@ ur_map* ur_map_create(void); * -1 - error */ -int ur_map_put(ur_map* map, ur_map_key_type key, ur_map_value_type value); +int ur_map_put(ur_map *map, ur_map_key_type key, ur_map_value_type value); /** * @ret: @@ -72,32 +70,32 @@ int ur_map_put(ur_map* map, ur_map_key_type key, ur_map_value_type value); * 0 - not found */ -int ur_map_get(const ur_map* map, ur_map_key_type key, ur_map_value_type *value); +int ur_map_get(const ur_map *map, ur_map_key_type key, ur_map_value_type *value); /** * @ret: * 1 - success * 0 - not found */ -int ur_map_del(ur_map* map, ur_map_key_type key,ur_map_del_func delfunc); +int ur_map_del(ur_map *map, ur_map_key_type key, ur_map_del_func delfunc); /** * @ret: * 1 - success * 0 - not found */ -int ur_map_exist(const ur_map* map, ur_map_key_type key); +int ur_map_exist(const ur_map *map, ur_map_key_type key); -void ur_map_free(ur_map** map); +void ur_map_free(ur_map **map); -size_t ur_map_size(const ur_map* map); +size_t ur_map_size(const ur_map *map); -int ur_map_foreach(ur_map* map, foreachcb_type func); +int ur_map_foreach(ur_map *map, foreachcb_type func); -int ur_map_foreach_arg(const ur_map* map, foreachcb_arg_type func, void* arg); +int ur_map_foreach_arg(const ur_map *map, foreachcb_arg_type func, void *arg); -int ur_map_lock(const ur_map* map); -int ur_map_unlock(const ur_map* map); +int ur_map_lock(const ur_map *map); +int ur_map_unlock(const ur_map *map); ///////////// "local" map ///////////////////// @@ -105,15 +103,15 @@ int ur_map_unlock(const ur_map* map); #define LM_MAP_ARRAY_SIZE (3) typedef struct _lm_map_array { - ur_map_key_type main_keys[LM_MAP_ARRAY_SIZE]; - ur_map_value_type main_values[LM_MAP_ARRAY_SIZE]; - size_t extra_sz; - ur_map_key_type **extra_keys; - ur_map_value_type **extra_values; + ur_map_key_type main_keys[LM_MAP_ARRAY_SIZE]; + ur_map_value_type main_values[LM_MAP_ARRAY_SIZE]; + size_t extra_sz; + ur_map_key_type **extra_keys; + ur_map_value_type **extra_values; } lm_map_array; typedef struct _lm_map { - lm_map_array table[LM_MAP_HASH_SIZE]; + lm_map_array table[LM_MAP_HASH_SIZE]; } lm_map; void lm_map_init(lm_map *map); @@ -124,7 +122,7 @@ void lm_map_init(lm_map *map); * -1 - error */ -int lm_map_put(lm_map* map, ur_map_key_type key, ur_map_value_type value); +int lm_map_put(lm_map *map, ur_map_key_type key, ur_map_value_type value); /** * @ret: @@ -132,29 +130,29 @@ int lm_map_put(lm_map* map, ur_map_key_type key, ur_map_value_type value); * 0 - not found */ -int lm_map_get(const lm_map* map, ur_map_key_type key, ur_map_value_type *value); +int lm_map_get(const lm_map *map, ur_map_key_type key, ur_map_value_type *value); /** * @ret: * 1 - success * 0 - not found */ -int lm_map_del(lm_map* map, ur_map_key_type key,ur_map_del_func delfunc); +int lm_map_del(lm_map *map, ur_map_key_type key, ur_map_del_func delfunc); /** * @ret: * 1 - success * 0 - not found */ -int lm_map_exist(const lm_map* map, ur_map_key_type key); +int lm_map_exist(const lm_map *map, ur_map_key_type key); -void lm_map_clean(lm_map* map); +void lm_map_clean(lm_map *map); -size_t lm_map_size(const lm_map* map); +size_t lm_map_size(const lm_map *map); -int lm_map_foreach(lm_map* map, foreachcb_type func); +int lm_map_foreach(lm_map *map, foreachcb_type func); -int lm_map_foreach_arg(lm_map* map, foreachcb_arg_type func, void* arg); +int lm_map_foreach_arg(lm_map *map, foreachcb_arg_type func, void *arg); //////////////// UR ADDR MAP ////////////////// @@ -184,8 +182,8 @@ typedef struct _ur_addr_map ur_addr_map; typedef void (*ur_addr_map_func)(ur_addr_map_value_type); -void ur_addr_map_init(ur_addr_map* map); -void ur_addr_map_clean(ur_addr_map* map); +void ur_addr_map_init(ur_addr_map *map); +void ur_addr_map_clean(ur_addr_map *map); /** * @ret: @@ -193,42 +191,42 @@ void ur_addr_map_clean(ur_addr_map* map); * -1 - error * if the addr key exists, the value is updated. */ -int ur_addr_map_put(ur_addr_map* map, ioa_addr* key, ur_addr_map_value_type value); +int ur_addr_map_put(ur_addr_map *map, ioa_addr *key, ur_addr_map_value_type value); /** * @ret: * 1 - success * 0 - not found */ -int ur_addr_map_get(const ur_addr_map* map, ioa_addr* key, ur_addr_map_value_type *value); +int ur_addr_map_get(const ur_addr_map *map, ioa_addr *key, ur_addr_map_value_type *value); /** * @ret: * 1 - success * 0 - not found */ -int ur_addr_map_del(ur_addr_map* map, ioa_addr* key,ur_addr_map_func func); +int ur_addr_map_del(ur_addr_map *map, ioa_addr *key, ur_addr_map_func func); /** * @ret: * 1 - success * 0 - not found */ -void ur_addr_map_foreach(ur_addr_map* map, ur_addr_map_func func); +void ur_addr_map_foreach(ur_addr_map *map, ur_addr_map_func func); -size_t ur_addr_map_num_elements(const ur_addr_map* map); -size_t ur_addr_map_size(const ur_addr_map* map); +size_t ur_addr_map_num_elements(const ur_addr_map *map); +size_t ur_addr_map_size(const ur_addr_map *map); //////////////// UR STRING MAP ////////////////// -typedef char* ur_string_map_key_type; -typedef void* ur_string_map_value_type; +typedef char *ur_string_map_key_type; +typedef void *ur_string_map_value_type; struct _ur_string_map; typedef struct _ur_string_map ur_string_map; typedef void (*ur_string_map_func)(ur_string_map_value_type); -ur_string_map* ur_string_map_create(ur_string_map_func del_value_func); +ur_string_map *ur_string_map_create(ur_string_map_func del_value_func); /** * @ret: @@ -236,29 +234,29 @@ ur_string_map* ur_string_map_create(ur_string_map_func del_value_func); * -1 - error * if the string key exists, and the value is different, return error. */ -int ur_string_map_put(ur_string_map* map, const ur_string_map_key_type key, ur_string_map_value_type value); +int ur_string_map_put(ur_string_map *map, const ur_string_map_key_type key, ur_string_map_value_type value); /** * @ret: * 1 - success * 0 - not found */ -int ur_string_map_get(ur_string_map* map, const ur_string_map_key_type key, ur_string_map_value_type *value); +int ur_string_map_get(ur_string_map *map, const ur_string_map_key_type key, ur_string_map_value_type *value); /** * @ret: * 1 - success * 0 - not found */ -int ur_string_map_del(ur_string_map* map, const ur_string_map_key_type key); +int ur_string_map_del(ur_string_map *map, const ur_string_map_key_type key); -void ur_string_map_clean(ur_string_map* map); -void ur_string_map_free(ur_string_map** map); +void ur_string_map_clean(ur_string_map *map); +void ur_string_map_free(ur_string_map **map); -size_t ur_string_map_size(const ur_string_map* map); +size_t ur_string_map_size(const ur_string_map *map); -int ur_string_map_lock(const ur_string_map* map); -int ur_string_map_unlock(const ur_string_map* map); +int ur_string_map_lock(const ur_string_map *map); +int ur_string_map_unlock(const ur_string_map *map); //////////////////////////////////////////// diff --git a/src/server/ns_turn_maps_rtcp.c b/src/server/ns_turn_maps_rtcp.c index d70177c..e7ad848 100644 --- a/src/server/ns_turn_maps_rtcp.c +++ b/src/server/ns_turn_maps_rtcp.c @@ -47,7 +47,6 @@ struct _rtcp_map { TURN_MUTEX_DECLARE(mutex) }; - typedef struct { ioa_socket_handle s; turn_time_t t; @@ -56,9 +55,7 @@ typedef struct { //////////////////////////////////////////// -static int rtcp_map_valid(const rtcp_map *map) { - return (map && (map->magic==MAGIC_RTCP_MAP) && map->map); -} +static int rtcp_map_valid(const rtcp_map *map) { return (map && (map->magic == MAGIC_RTCP_MAP) && map->map); } typedef struct { rtcp_token_type tokens[MAX_TOKEN_DEL]; @@ -66,44 +63,40 @@ typedef struct { turn_time_t t; } timeout_check_arg_type; -static int timeout_check(ur_map_key_type key, - ur_map_value_type value, - void *arg) { - - if(value && arg) { - - timeout_check_arg_type *tcat=(timeout_check_arg_type*)arg; - - rtcp_alloc_type* rat=(rtcp_alloc_type*)value; - - if(turn_time_before(rat->t, tcat->t) && (tcat->tntokens[(tcat->tn)++]=key; +static int timeout_check(ur_map_key_type key, ur_map_value_type value, void *arg) { + + if (value && arg) { + + timeout_check_arg_type *tcat = (timeout_check_arg_type *)arg; + + rtcp_alloc_type *rat = (rtcp_alloc_type *)value; + + if (turn_time_before(rat->t, tcat->t) && (tcat->tn < MAX_TOKEN_DEL)) { + tcat->tokens[(tcat->tn)++] = key; } } - + return 0; } -static void rtcp_alloc_free(ur_map_value_type value) -{ - rtcp_alloc_type *at = (rtcp_alloc_type *)value; - if (at) { - IOA_CLOSE_SOCKET(at->s); - free(at); - } +static void rtcp_alloc_free(ur_map_value_type value) { + rtcp_alloc_type *at = (rtcp_alloc_type *)value; + if (at) { + IOA_CLOSE_SOCKET(at->s); + free(at); + } } -static void rtcp_alloc_free_savefd(ur_map_value_type value) -{ - rtcp_alloc_type *at = (rtcp_alloc_type *) value; - if (at) { - free(at); - } +static void rtcp_alloc_free_savefd(ur_map_value_type value) { + rtcp_alloc_type *at = (rtcp_alloc_type *)value; + if (at) { + free(at); + } } static int foreachcb_free(ur_map_key_type key, ur_map_value_type value) { UNUSED_ARG(key); - if(value) { + if (value) { rtcp_alloc_free(value); } return 0; @@ -114,70 +107,72 @@ static int foreachcb_free(ur_map_key_type key, ur_map_value_type value) { * 1 - success * 0 - not found */ -static int rtcp_map_del(rtcp_map* map, rtcp_token_type token) { - if(!rtcp_map_valid(map)) return 0; +static int rtcp_map_del(rtcp_map *map, rtcp_token_type token) { + if (!rtcp_map_valid(map)) + return 0; else { TURN_MUTEX_LOCK(&map->mutex); - int ret = ur_map_del(map->map,token,rtcp_alloc_free); + int ret = ur_map_del(map->map, token, rtcp_alloc_free); TURN_MUTEX_UNLOCK(&map->mutex); return ret; } } -static int rtcp_map_del_savefd(rtcp_map* map, rtcp_token_type token) { - if(!rtcp_map_valid(map)) return 0; +static int rtcp_map_del_savefd(rtcp_map *map, rtcp_token_type token) { + if (!rtcp_map_valid(map)) + return 0; else { - int ret = ur_map_del(map->map,token,rtcp_alloc_free_savefd); + int ret = ur_map_del(map->map, token, rtcp_alloc_free_savefd); return ret; } } -static void rtcp_map_timeout_handler(ioa_engine_handle e, void* arg) { - +static void rtcp_map_timeout_handler(ioa_engine_handle e, void *arg) { + UNUSED_ARG(e); - if(!arg) return; + if (!arg) + return; - rtcp_map* map=(rtcp_map*)arg; + rtcp_map *map = (rtcp_map *)arg; - if(rtcp_map_valid(map)) { + if (rtcp_map_valid(map)) { TURN_MUTEX_LOCK(&map->mutex); timeout_check_arg_type tcat; - tcat.tn=0; - tcat.t=turn_time(); - + tcat.tn = 0; + tcat.t = turn_time(); + ur_map_foreach_arg(map->map, timeout_check, &tcat); TURN_MUTEX_UNLOCK(&map->mutex); - int i=0; - for(i=0;imagic != MAGIC_RTCP_MAP) { - map->magic = MAGIC_RTCP_MAP; - map->map = ur_map_create(); - if (e) - map->timer_ev = set_ioa_timer(e, 3, 0, rtcp_map_timeout_handler, - map, 1, "rtcp_map_timeout_handler"); - TURN_MUTEX_INIT(&map->mutex); - if (rtcp_map_valid(map)) - return 0; - } - } - return -1; +static int rtcp_map_init(rtcp_map *map, ioa_engine_handle e) { + if (map) { + if (map->magic != MAGIC_RTCP_MAP) { + map->magic = MAGIC_RTCP_MAP; + map->map = ur_map_create(); + if (e) + map->timer_ev = set_ioa_timer(e, 3, 0, rtcp_map_timeout_handler, map, 1, "rtcp_map_timeout_handler"); + TURN_MUTEX_INIT(&map->mutex); + if (rtcp_map_valid(map)) + return 0; + } + } + return -1; } -rtcp_map* rtcp_map_create(ioa_engine_handle e) { - rtcp_map *map=(rtcp_map*)calloc(sizeof(rtcp_map), 1); - if(rtcp_map_init(map,e)<0) { +rtcp_map *rtcp_map_create(ioa_engine_handle e) { + rtcp_map *map = (rtcp_map *)calloc(sizeof(rtcp_map), 1); + if (rtcp_map_init(map, e) < 0) { free(map); return NULL; } @@ -189,20 +184,23 @@ rtcp_map* rtcp_map_create(ioa_engine_handle e) { * 0 - success * -1 - error */ -int rtcp_map_put(rtcp_map* map, rtcp_token_type token, ioa_socket_handle s) { - if(!rtcp_map_valid(map)) return -1; +int rtcp_map_put(rtcp_map *map, rtcp_token_type token, ioa_socket_handle s) { + if (!rtcp_map_valid(map)) + return -1; else { - rtcp_alloc_type *value=(rtcp_alloc_type*)calloc(sizeof(rtcp_alloc_type), 1); - if(!value) return -1; + rtcp_alloc_type *value = (rtcp_alloc_type *)calloc(sizeof(rtcp_alloc_type), 1); + if (!value) + return -1; - value->s=s; - value->t=turn_time() + RTCP_TIMEOUT; - value->token=token; + value->s = s; + value->t = turn_time() + RTCP_TIMEOUT; + value->token = token; TURN_MUTEX_LOCK(&map->mutex); - int ret = ur_map_put(map->map,token,(ur_map_value_type)value); - //TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s: 111.111: ret=%d, token=%llu\n",__FUNCTION__,ret,token); + int ret = ur_map_put(map->map, token, (ur_map_value_type)value); + // TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s: 111.111: ret=%d, token=%llu\n",__FUNCTION__,ret,token); TURN_MUTEX_UNLOCK(&map->mutex); - if(ret<0) free(value); + if (ret < 0) + free(value); return ret; } } @@ -212,40 +210,40 @@ int rtcp_map_put(rtcp_map* map, rtcp_token_type token, ioa_socket_handle s) { * >=0 - success * <0 - not found */ -ioa_socket_handle rtcp_map_get(rtcp_map* map, rtcp_token_type token) { - ioa_socket_handle s = NULL; - if (rtcp_map_valid(map)) { - ur_map_value_type value; - TURN_MUTEX_LOCK(&map->mutex); - int ret = ur_map_get(map->map, token, &value); - if (ret) { - rtcp_alloc_type* rval = (rtcp_alloc_type*) value; - if (rval) { - s = rval->s; - rtcp_map_del_savefd(map, token); - } - } - TURN_MUTEX_UNLOCK(&map->mutex); - } - return s; +ioa_socket_handle rtcp_map_get(rtcp_map *map, rtcp_token_type token) { + ioa_socket_handle s = NULL; + if (rtcp_map_valid(map)) { + ur_map_value_type value; + TURN_MUTEX_LOCK(&map->mutex); + int ret = ur_map_get(map->map, token, &value); + if (ret) { + rtcp_alloc_type *rval = (rtcp_alloc_type *)value; + if (rval) { + s = rval->s; + rtcp_map_del_savefd(map, token); + } + } + TURN_MUTEX_UNLOCK(&map->mutex); + } + return s; } -void rtcp_map_free(rtcp_map** map) { - if(map && rtcp_map_valid(*map)) { +void rtcp_map_free(rtcp_map **map) { + if (map && rtcp_map_valid(*map)) { TURN_MUTEX_LOCK(&((*map)->mutex)); IOA_EVENT_DEL((*map)->timer_ev); ur_map_foreach((*map)->map, foreachcb_free); ur_map_free(&((*map)->map)); - (*map)->magic=0; + (*map)->magic = 0; TURN_MUTEX_UNLOCK(&((*map)->mutex)); TURN_MUTEX_DESTROY(&((*map)->mutex)); free(*map); - *map=NULL; + *map = NULL; } } -size_t rtcp_map_size(const rtcp_map* map) { - if(rtcp_map_valid(map)) { +size_t rtcp_map_size(const rtcp_map *map) { + if (rtcp_map_valid(map)) { TURN_MUTEX_LOCK(&map->mutex); size_t ret = ur_map_size(map->map); TURN_MUTEX_UNLOCK(&map->mutex); diff --git a/src/server/ns_turn_maps_rtcp.h b/src/server/ns_turn_maps_rtcp.h index 43be9ad..45ff5fe 100644 --- a/src/server/ns_turn_maps_rtcp.h +++ b/src/server/ns_turn_maps_rtcp.h @@ -31,8 +31,8 @@ #ifndef __TURN_RTCP_MAP__ #define __TURN_RTCP_MAP__ -#include "ns_turn_maps.h" #include "ns_turn_ioalib.h" +#include "ns_turn_maps.h" #ifdef __cplusplus extern "C" { @@ -47,30 +47,30 @@ typedef struct _rtcp_map rtcp_map; //////////////////////////////////////////////// -rtcp_map* rtcp_map_create(ioa_engine_handle e); +rtcp_map *rtcp_map_create(ioa_engine_handle e); /** * @ret: * 0 - success * -1 - error */ -int rtcp_map_put(rtcp_map* map, rtcp_token_type key, ioa_socket_handle s); +int rtcp_map_put(rtcp_map *map, rtcp_token_type key, ioa_socket_handle s); /** * @ret: * >=0 - success * <0 - not found */ -ioa_socket_handle rtcp_map_get(rtcp_map* map, rtcp_token_type token); +ioa_socket_handle rtcp_map_get(rtcp_map *map, rtcp_token_type token); /** * @ret: * 1 - success * 0 - not found */ -void rtcp_map_free(rtcp_map** map); +void rtcp_map_free(rtcp_map **map); -size_t rtcp_map_size(const rtcp_map* map); +size_t rtcp_map_size(const rtcp_map *map); //////////////////////////////////////////// diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index a60e972..b83c642 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -30,44 +30,48 @@ #include "ns_turn_server.h" -#include "ns_turn_utils.h" +#include "../apps/relay/ns_ioalib_impl.h" #include "ns_turn_allocation.h" #include "ns_turn_ioalib.h" -#include "../apps/relay/ns_ioalib_impl.h" +#include "ns_turn_utils.h" /////////////////////////////////////////// -#define FUNCSTART if(server && eve(server->verbose)) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s:%d:start\n",__FUNCTION__,__LINE__) -#define FUNCEND if(server && eve(server->verbose)) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s:%d:end\n",__FUNCTION__,__LINE__) +#define FUNCSTART \ + if (server && eve(server->verbose)) \ + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s:%d:start\n", __FUNCTION__, __LINE__) +#define FUNCEND \ + if (server && eve(server->verbose)) \ + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s:%d:end\n", __FUNCTION__, __LINE__) //////////////////////////////////////////////// static inline int get_family(int stun_family, ioa_engine_handle e, ioa_socket_handle client_socket) { - switch(stun_family) { - case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4: - return AF_INET; - break; - case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6: - return AF_INET6; - break; - case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT: - if(e->default_relays && get_ioa_socket_address_family(client_socket) == AF_INET6) - return AF_INET6; - else - return AF_INET; - default: - return AF_INET; - }; + switch (stun_family) { + case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4: + return AF_INET; + break; + case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6: + return AF_INET6; + break; + case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT: + if (e->default_relays && get_ioa_socket_address_family(client_socket) == AF_INET6) + return AF_INET6; + else + return AF_INET; + default: + return AF_INET; + }; } //////////////////////////////////////////////// -const char * get_version(turn_turnserver *server) { - if(server && !*server->no_software_attribute) { - return (const char *) TURN_SOFTWARE; - } else { - return (const char *) "None"; - } +const char *get_version(turn_turnserver *server) { + if (server && !*server->no_software_attribute) { + return (const char *)TURN_SOFTWARE; + } else { + return (const char *)"None"; + } } #define MAX_NUMBER_OF_UNKNOWN_ATTRS (128) @@ -75,4968 +79,4795 @@ const char * get_version(turn_turnserver *server) { int TURN_MAX_ALLOCATE_TIMEOUT = 60; int TURN_MAX_ALLOCATE_TIMEOUT_STUN_ONLY = 3; -static inline void log_method(ts_ur_super_session* ss, const char *method, int err_code, const uint8_t *reason) -{ - if(ss) { - if(!method) method = "unknown"; - if(!err_code) { - if(ss->origin[0]) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "session %018llu: origin <%s> realm <%s> user <%s>: incoming packet %s processed, success\n", - (unsigned long long)(ss->id), (const char*)(ss->origin),(const char*)(ss->realm_options.name),(const char*)(ss->username),method); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "session %018llu: realm <%s> user <%s>: incoming packet %s processed, success\n", - (unsigned long long)(ss->id), (const char*)(ss->realm_options.name),(const char*)(ss->username),method); - } - } else { - if(!reason) reason=get_default_reason(err_code); - if(ss->origin[0]) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "session %018llu: origin <%s> realm <%s> user <%s>: incoming packet %s processed, error %d: %s\n", - (unsigned long long)(ss->id), (const char*)(ss->origin),(const char*)(ss->realm_options.name),(const char*)(ss->username), method, err_code, reason); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "session %018llu: realm <%s> user <%s>: incoming packet %s processed, error %d: %s\n", - (unsigned long long)(ss->id), (const char*)(ss->realm_options.name),(const char*)(ss->username), method, err_code, reason); - } - } +static inline void log_method(ts_ur_super_session *ss, const char *method, int err_code, const uint8_t *reason) { + if (ss) { + if (!method) + method = "unknown"; + if (!err_code) { + if (ss->origin[0]) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, + "session %018llu: origin <%s> realm <%s> user <%s>: incoming packet %s processed, success\n", + (unsigned long long)(ss->id), (const char *)(ss->origin), (const char *)(ss->realm_options.name), + (const char *)(ss->username), method); + } else { + TURN_LOG_FUNC( + TURN_LOG_LEVEL_INFO, "session %018llu: realm <%s> user <%s>: incoming packet %s processed, success\n", + (unsigned long long)(ss->id), (const char *)(ss->realm_options.name), (const char *)(ss->username), method); + } + } else { + if (!reason) + reason = get_default_reason(err_code); + if (ss->origin[0]) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, + "session %018llu: origin <%s> realm <%s> user <%s>: incoming packet %s processed, error %d: %s\n", + (unsigned long long)(ss->id), (const char *)(ss->origin), (const char *)(ss->realm_options.name), + (const char *)(ss->username), method, err_code, reason); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, + "session %018llu: realm <%s> user <%s>: incoming packet %s processed, error %d: %s\n", + (unsigned long long)(ss->id), (const char *)(ss->realm_options.name), + (const char *)(ss->username), method, err_code, reason); + } + } } } /////////////////////////////////////////// -static int attach_socket_to_session(turn_turnserver* server, ioa_socket_handle s, ts_ur_super_session* ss); +static int attach_socket_to_session(turn_turnserver *server, ioa_socket_handle s, ts_ur_super_session *ss); -static int check_stun_auth(turn_turnserver *server, - ts_ur_super_session *ss, stun_tid *tid, int *resp_constructed, - int *err_code, const uint8_t **reason, - ioa_net_data *in_buffer, ioa_network_buffer_handle nbh, - uint16_t method, int *message_integrity, - int *postpone_reply, - int can_resume); +static int check_stun_auth(turn_turnserver *server, ts_ur_super_session *ss, stun_tid *tid, int *resp_constructed, + int *err_code, const uint8_t **reason, ioa_net_data *in_buffer, + ioa_network_buffer_handle nbh, uint16_t method, int *message_integrity, int *postpone_reply, + int can_resume); -static int create_relay_connection(turn_turnserver* server, - ts_ur_super_session *ss, uint32_t lifetime, - int address_family, uint8_t transport, - int even_port, uint64_t in_reservation_token, uint64_t *out_reservation_token, - int *err_code, const uint8_t **reason, accept_cb acb); +static int create_relay_connection(turn_turnserver *server, ts_ur_super_session *ss, uint32_t lifetime, + int address_family, uint8_t transport, int even_port, uint64_t in_reservation_token, + uint64_t *out_reservation_token, int *err_code, const uint8_t **reason, + accept_cb acb); -static int refresh_relay_connection(turn_turnserver* server, - ts_ur_super_session *ss, uint32_t lifetime, int even_port, - uint64_t in_reservation_token, uint64_t *out_reservation_token, - int *err_code, int family); +static int refresh_relay_connection(turn_turnserver *server, ts_ur_super_session *ss, uint32_t lifetime, int even_port, + uint64_t in_reservation_token, uint64_t *out_reservation_token, int *err_code, + int family); -static int write_client_connection(turn_turnserver *server, ts_ur_super_session* ss, ioa_network_buffer_handle nbh, int ttl, int tos); +static int write_client_connection(turn_turnserver *server, ts_ur_super_session *ss, ioa_network_buffer_handle nbh, + int ttl, int tos); static void tcp_peer_accept_connection(ioa_socket_handle s, void *arg); -static int read_client_connection(turn_turnserver *server, - ts_ur_super_session *ss, ioa_net_data *in_buffer, - int can_resume, int count_usage); +static int read_client_connection(turn_turnserver *server, ts_ur_super_session *ss, ioa_net_data *in_buffer, + int can_resume, int count_usage); static int need_stun_authentication(turn_turnserver *server, ts_ur_super_session *ss); /////////////////// timer ////////////////////////// -static void timer_timeout_handler(ioa_engine_handle e, void *arg) -{ - UNUSED_ARG(e); - if(arg) { - turn_turnserver *server=(turn_turnserver*)arg; - server->ctime = turn_time(); - } +static void timer_timeout_handler(ioa_engine_handle e, void *arg) { + UNUSED_ARG(e); + if (arg) { + turn_turnserver *server = (turn_turnserver *)arg; + server->ctime = turn_time(); + } } -turn_time_t get_turn_server_time(turn_turnserver *server) -{ - if(server) { - return server->ctime; - } - return turn_time(); +turn_time_t get_turn_server_time(turn_turnserver *server) { + if (server) { + return server->ctime; + } + return turn_time(); } /////////////////// quota ////////////////////// -static int inc_quota(ts_ur_super_session* ss, uint8_t *username) -{ - if(ss && !(ss->quota_used) && ss->server && ((turn_turnserver*)ss->server)->chquotacb && username) { +static int inc_quota(ts_ur_super_session *ss, uint8_t *username) { + if (ss && !(ss->quota_used) && ss->server && ((turn_turnserver *)ss->server)->chquotacb && username) { - if(((turn_turnserver*)ss->server)->ct == TURN_CREDENTIALS_LONG_TERM) { - if(!(ss->origin_set)) { - return -1; - } - } + if (((turn_turnserver *)ss->server)->ct == TURN_CREDENTIALS_LONG_TERM) { + if (!(ss->origin_set)) { + return -1; + } + } - if((((turn_turnserver*)ss->server)->chquotacb)(username, ss->oauth, (uint8_t*)ss->realm_options.name)<0) { + if ((((turn_turnserver *)ss->server)->chquotacb)(username, ss->oauth, (uint8_t *)ss->realm_options.name) < 0) { - return -1; + return -1; - } else { + } else { - STRCPY(ss->username,username); + STRCPY(ss->username, username); - ss->quota_used = 1; - } - } + ss->quota_used = 1; + } + } - return 0; + return 0; } -static void dec_quota(ts_ur_super_session* ss) -{ - if(ss && ss->quota_used && ss->server && ((turn_turnserver*)ss->server)->raqcb) { +static void dec_quota(ts_ur_super_session *ss) { + if (ss && ss->quota_used && ss->server && ((turn_turnserver *)ss->server)->raqcb) { - ss->quota_used = 0; + ss->quota_used = 0; - (((turn_turnserver*)ss->server)->raqcb)(ss->username, ss->oauth, (uint8_t*)ss->realm_options.name); - } + (((turn_turnserver *)ss->server)->raqcb)(ss->username, ss->oauth, (uint8_t *)ss->realm_options.name); + } } -static void dec_bps(ts_ur_super_session* ss) -{ - if(ss && ss->server) { +static void dec_bps(ts_ur_super_session *ss) { + if (ss && ss->server) { - if(ss->bps) { - if(((turn_turnserver*)ss->server)->allocate_bps_func) { - ((turn_turnserver*)ss->server)->allocate_bps_func(ss->bps,0); - } - ss->bps = 0; - } - } + if (ss->bps) { + if (((turn_turnserver *)ss->server)->allocate_bps_func) { + ((turn_turnserver *)ss->server)->allocate_bps_func(ss->bps, 0); + } + ss->bps = 0; + } + } } /////////////////// server lists /////////////////// -void init_turn_server_addrs_list(turn_server_addrs_list_t *l) -{ - if(l) { - l->addrs = NULL; - l->size = 0; - TURN_MUTEX_INIT(&(l->m)); - } +void init_turn_server_addrs_list(turn_server_addrs_list_t *l) { + if (l) { + l->addrs = NULL; + l->size = 0; + TURN_MUTEX_INIT(&(l->m)); + } } /////////////////// RFC 5780 /////////////////////// -void set_rfc5780(turn_turnserver *server, get_alt_addr_cb cb, send_message_cb smcb) -{ - if(server) { - if(!cb || !smcb) { - server->rfc5780 = 0; - server->alt_addr_cb = NULL; - server->sm_cb = NULL; - } else { - server->rfc5780 = 1; - server->alt_addr_cb = cb; - server->sm_cb = smcb; - } - } +void set_rfc5780(turn_turnserver *server, get_alt_addr_cb cb, send_message_cb smcb) { + if (server) { + if (!cb || !smcb) { + server->rfc5780 = 0; + server->alt_addr_cb = NULL; + server->sm_cb = NULL; + } else { + server->rfc5780 = 1; + server->alt_addr_cb = cb; + server->sm_cb = smcb; + } + } } -static int is_rfc5780(turn_turnserver *server) -{ - if(!server) - return 0; +static int is_rfc5780(turn_turnserver *server) { + if (!server) + return 0; - return ((server->rfc5780) && (server->alt_addr_cb)); + return ((server->rfc5780) && (server->alt_addr_cb)); } -static int get_other_address(turn_turnserver *server, ts_ur_super_session *ss, ioa_addr *alt_addr) -{ - if(is_rfc5780(server) && ss && ss->client_socket) { - int ret = server->alt_addr_cb(get_local_addr_from_ioa_socket(ss->client_socket), alt_addr); - return ret; - } +static int get_other_address(turn_turnserver *server, ts_ur_super_session *ss, ioa_addr *alt_addr) { + if (is_rfc5780(server) && ss && ss->client_socket) { + int ret = server->alt_addr_cb(get_local_addr_from_ioa_socket(ss->client_socket), alt_addr); + return ret; + } - return -1; + return -1; } -static int send_turn_message_to(turn_turnserver *server, ioa_network_buffer_handle nbh, ioa_addr *response_origin, ioa_addr *response_destination) -{ - if(is_rfc5780(server) && nbh && response_origin && response_destination) { - return server->sm_cb(server->e, nbh, response_origin, response_destination); - } +static int send_turn_message_to(turn_turnserver *server, ioa_network_buffer_handle nbh, ioa_addr *response_origin, + ioa_addr *response_destination) { + if (is_rfc5780(server) && nbh && response_origin && response_destination) { + return server->sm_cb(server->e, nbh, response_origin, response_destination); + } - return -1; + return -1; } /////////////////// Peer addr check ///////////////////////////// -static int good_peer_addr(turn_turnserver *server, const char* realm, ioa_addr *peer_addr) -{ -#define CHECK_REALM(r) if((r)[0] && realm && realm[0] && strcmp((r),realm)) continue +static int good_peer_addr(turn_turnserver *server, const char *realm, ioa_addr *peer_addr) { +#define CHECK_REALM(r) \ + if ((r)[0] && realm && realm[0] && strcmp((r), realm)) \ + continue - if(server && peer_addr) { - if(*(server->no_multicast_peers) && ioa_addr_is_multicast(peer_addr)) - return 0; - if( !*(server->allow_loopback_peers) && ioa_addr_is_loopback(peer_addr)) - return 0; - if (ioa_addr_is_zero(peer_addr)) - return 0; + if (server && peer_addr) { + if (*(server->no_multicast_peers) && ioa_addr_is_multicast(peer_addr)) + return 0; + if (!*(server->allow_loopback_peers) && ioa_addr_is_loopback(peer_addr)) + return 0; + if (ioa_addr_is_zero(peer_addr)) + return 0; - { - int i; + { + int i; - if(server->ip_whitelist) { - // White listing of addr ranges - for (i = server->ip_whitelist->ranges_number - 1; i >= 0; --i) { - CHECK_REALM(server->ip_whitelist->rs[i].realm); - if (ioa_addr_in_range(&(server->ip_whitelist->rs[i].enc), peer_addr)) - return 1; - } - } + if (server->ip_whitelist) { + // White listing of addr ranges + for (i = server->ip_whitelist->ranges_number - 1; i >= 0; --i) { + CHECK_REALM(server->ip_whitelist->rs[i].realm); + if (ioa_addr_in_range(&(server->ip_whitelist->rs[i].enc), peer_addr)) + return 1; + } + } - { - ioa_lock_whitelist(server->e); + { + ioa_lock_whitelist(server->e); - const ip_range_list_t* wl = ioa_get_whitelist(server->e); - if(wl) { - // White listing of addr ranges - for (i = wl->ranges_number - 1; i >= 0; --i) { - CHECK_REALM(wl->rs[i].realm); - if (ioa_addr_in_range(&(wl->rs[i].enc), peer_addr)) { - ioa_unlock_whitelist(server->e); - return 1; - } - } - } + const ip_range_list_t *wl = ioa_get_whitelist(server->e); + if (wl) { + // White listing of addr ranges + for (i = wl->ranges_number - 1; i >= 0; --i) { + CHECK_REALM(wl->rs[i].realm); + if (ioa_addr_in_range(&(wl->rs[i].enc), peer_addr)) { + ioa_unlock_whitelist(server->e); + return 1; + } + } + } - ioa_unlock_whitelist(server->e); - } + ioa_unlock_whitelist(server->e); + } - if(server->ip_blacklist) { - // Black listing of addr ranges - for (i = server->ip_blacklist->ranges_number - 1; i >= 0; --i) { - CHECK_REALM(server->ip_blacklist->rs[i].realm); - if (ioa_addr_in_range(&(server->ip_blacklist->rs[i].enc), peer_addr)) { - char saddr[129]; - addr_to_string_no_port(peer_addr,(uint8_t*)saddr); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "A peer IP %s denied in the range: %s\n",saddr,server->ip_blacklist->rs[i].str); - return 0; - } - } - } + if (server->ip_blacklist) { + // Black listing of addr ranges + for (i = server->ip_blacklist->ranges_number - 1; i >= 0; --i) { + CHECK_REALM(server->ip_blacklist->rs[i].realm); + if (ioa_addr_in_range(&(server->ip_blacklist->rs[i].enc), peer_addr)) { + char saddr[129]; + addr_to_string_no_port(peer_addr, (uint8_t *)saddr); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "A peer IP %s denied in the range: %s\n", saddr, + server->ip_blacklist->rs[i].str); + return 0; + } + } + } - { - ioa_lock_blacklist(server->e); + { + ioa_lock_blacklist(server->e); - const ip_range_list_t* bl = ioa_get_blacklist(server->e); - if(bl) { - // Black listing of addr ranges - for (i = bl->ranges_number - 1; i >= 0; --i) { - CHECK_REALM(bl->rs[i].realm); - if (ioa_addr_in_range(&(bl->rs[i].enc), peer_addr)) { - ioa_unlock_blacklist(server->e); - char saddr[129]; - addr_to_string_no_port(peer_addr,(uint8_t*)saddr); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "A peer IP %s denied in the range: %s\n",saddr,bl->rs[i].str); - return 0; - } - } - } + const ip_range_list_t *bl = ioa_get_blacklist(server->e); + if (bl) { + // Black listing of addr ranges + for (i = bl->ranges_number - 1; i >= 0; --i) { + CHECK_REALM(bl->rs[i].realm); + if (ioa_addr_in_range(&(bl->rs[i].enc), peer_addr)) { + ioa_unlock_blacklist(server->e); + char saddr[129]; + addr_to_string_no_port(peer_addr, (uint8_t *)saddr); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "A peer IP %s denied in the range: %s\n", saddr, bl->rs[i].str); + return 0; + } + } + } - ioa_unlock_blacklist(server->e); - } - } - } + ioa_unlock_blacklist(server->e); + } + } + } #undef CHECK_REALM - return 1; + return 1; } /////////////////// Allocation ////////////////////////////////// -allocation* get_allocation_ss(ts_ur_super_session *ss) { - return &(ss->alloc); +allocation *get_allocation_ss(ts_ur_super_session *ss) { return &(ss->alloc); } + +static inline relay_endpoint_session *get_relay_session_ss(ts_ur_super_session *ss, int family) { + return get_relay_session(&(ss->alloc), family); } -static inline relay_endpoint_session *get_relay_session_ss(ts_ur_super_session *ss, int family) -{ - return get_relay_session(&(ss->alloc),family); -} - -static inline ioa_socket_handle get_relay_socket_ss(ts_ur_super_session *ss, int family) -{ - return get_relay_socket(&(ss->alloc),family); +static inline ioa_socket_handle get_relay_socket_ss(ts_ur_super_session *ss, int family) { + return get_relay_socket(&(ss->alloc), family); } /////////// Session info /////// -void turn_session_info_init(struct turn_session_info* tsi) { - if(tsi) { - memset(tsi, 0, sizeof(struct turn_session_info)); - } +void turn_session_info_init(struct turn_session_info *tsi) { + if (tsi) { + memset(tsi, 0, sizeof(struct turn_session_info)); + } } -void turn_session_info_clean(struct turn_session_info* tsi) { - if(tsi) { - if(tsi->extra_peers_data) { - free(tsi->extra_peers_data); - } - turn_session_info_init(tsi); - } +void turn_session_info_clean(struct turn_session_info *tsi) { + if (tsi) { + if (tsi->extra_peers_data) { + free(tsi->extra_peers_data); + } + turn_session_info_init(tsi); + } } -void turn_session_info_add_peer(struct turn_session_info* tsi, ioa_addr *peer) -{ - if(tsi && peer) { - { - size_t i; - for(i=0;imain_peers_size;++i) { - if(addr_eq(peer, &(tsi->main_peers_data[i].addr))) { - return; - } - } +void turn_session_info_add_peer(struct turn_session_info *tsi, ioa_addr *peer) { + if (tsi && peer) { + { + size_t i; + for (i = 0; i < tsi->main_peers_size; ++i) { + if (addr_eq(peer, &(tsi->main_peers_data[i].addr))) { + return; + } + } - if(tsi->main_peers_size < TURN_MAIN_PEERS_ARRAY_SIZE) { - addr_cpy(&(tsi->main_peers_data[tsi->main_peers_size].addr),peer); - addr_to_string(&(tsi->main_peers_data[tsi->main_peers_size].addr), - (uint8_t*)tsi->main_peers_data[tsi->main_peers_size].saddr); - tsi->main_peers_size += 1; - return; - } - } + if (tsi->main_peers_size < TURN_MAIN_PEERS_ARRAY_SIZE) { + addr_cpy(&(tsi->main_peers_data[tsi->main_peers_size].addr), peer); + addr_to_string(&(tsi->main_peers_data[tsi->main_peers_size].addr), + (uint8_t *)tsi->main_peers_data[tsi->main_peers_size].saddr); + tsi->main_peers_size += 1; + return; + } + } - if(tsi->extra_peers_data) { - size_t sz; - for(sz=0;szextra_peers_size;++sz) { - if(addr_eq(peer, &(tsi->extra_peers_data[sz].addr))) { - return; - } - } - } - tsi->extra_peers_data = (addr_data*)realloc(tsi->extra_peers_data,(tsi->extra_peers_size+1)*sizeof(addr_data)); - addr_cpy(&(tsi->extra_peers_data[tsi->extra_peers_size].addr),peer); - addr_to_string(&(tsi->extra_peers_data[tsi->extra_peers_size].addr), - (uint8_t*)tsi->extra_peers_data[tsi->extra_peers_size].saddr); - tsi->extra_peers_size += 1; - } + if (tsi->extra_peers_data) { + size_t sz; + for (sz = 0; sz < tsi->extra_peers_size; ++sz) { + if (addr_eq(peer, &(tsi->extra_peers_data[sz].addr))) { + return; + } + } + } + tsi->extra_peers_data = + (addr_data *)realloc(tsi->extra_peers_data, (tsi->extra_peers_size + 1) * sizeof(addr_data)); + addr_cpy(&(tsi->extra_peers_data[tsi->extra_peers_size].addr), peer); + addr_to_string(&(tsi->extra_peers_data[tsi->extra_peers_size].addr), + (uint8_t *)tsi->extra_peers_data[tsi->extra_peers_size].saddr); + tsi->extra_peers_size += 1; + } } struct tsi_arg { - struct turn_session_info* tsi; - ioa_addr *addr; + struct turn_session_info *tsi; + ioa_addr *addr; }; -static int turn_session_info_foreachcb(ur_map_key_type key, ur_map_value_type value, void *arg) -{ - UNUSED_ARG(value); +static int turn_session_info_foreachcb(ur_map_key_type key, ur_map_value_type value, void *arg) { + UNUSED_ARG(value); - int port = (int)key; - struct tsi_arg *ta = (struct tsi_arg *)arg; - if(port && ta && ta->tsi && ta->addr) { - ioa_addr a; - addr_cpy(&a,ta->addr); - addr_set_port(&a,port); - turn_session_info_add_peer(ta->tsi,&a); - } - return 0; + int port = (int)key; + struct tsi_arg *ta = (struct tsi_arg *)arg; + if (port && ta && ta->tsi && ta->addr) { + ioa_addr a; + addr_cpy(&a, ta->addr); + addr_set_port(&a, port); + turn_session_info_add_peer(ta->tsi, &a); + } + return 0; } -int turn_session_info_copy_from(struct turn_session_info* tsi, ts_ur_super_session *ss) -{ - int ret = -1; +int turn_session_info_copy_from(struct turn_session_info *tsi, ts_ur_super_session *ss) { + int ret = -1; - if(tsi && ss) { - tsi->id = ss->id; - tsi->bps = ss->bps; - tsi->start_time = ss->start_time; - tsi->valid = is_allocation_valid(&(ss->alloc)) && !(ss->to_be_closed) && (ss->quota_used); - if(tsi->valid) { - if(ss->alloc.relay_sessions[ALLOC_IPV4_INDEX].s) { - tsi->expiration_time = ss->alloc.relay_sessions[ALLOC_IPV4_INDEX].expiration_time; - if(ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].s) { - if(turn_time_before(tsi->expiration_time,ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].expiration_time)) { - tsi->expiration_time = ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].expiration_time; - } - } - } else if(ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].s) { - tsi->expiration_time = ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].expiration_time; - } - if(ss->client_socket) { - tsi->client_protocol = get_ioa_socket_type(ss->client_socket); - addr_cpy(&(tsi->local_addr_data.addr),get_local_addr_from_ioa_socket(ss->client_socket)); - addr_to_string(&(tsi->local_addr_data.addr),(uint8_t*)tsi->local_addr_data.saddr); - addr_cpy(&(tsi->remote_addr_data.addr),get_remote_addr_from_ioa_socket(ss->client_socket)); - addr_to_string(&(tsi->remote_addr_data.addr),(uint8_t*)tsi->remote_addr_data.saddr); - } - { - if(ss->alloc.relay_sessions[ALLOC_IPV4_INDEX].s) { - tsi->peer_protocol = get_ioa_socket_type(ss->alloc.relay_sessions[ALLOC_IPV4_INDEX].s); - if(ss->alloc.is_valid) { - addr_cpy(&(tsi->relay_addr_data_ipv4.addr),get_local_addr_from_ioa_socket(ss->alloc.relay_sessions[ALLOC_IPV4_INDEX].s)); - addr_to_string(&(tsi->relay_addr_data_ipv4.addr),(uint8_t*)tsi->relay_addr_data_ipv4.saddr); - } - } - if(ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].s) { - tsi->peer_protocol = get_ioa_socket_type(ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].s); - if(ss->alloc.is_valid) { - addr_cpy(&(tsi->relay_addr_data_ipv6.addr),get_local_addr_from_ioa_socket(ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].s)); - addr_to_string(&(tsi->relay_addr_data_ipv6.addr),(uint8_t*)tsi->relay_addr_data_ipv6.saddr); - } - } - } - STRCPY(tsi->username,ss->username); - tsi->enforce_fingerprints = ss->enforce_fingerprints; - STRCPY(tsi->tls_method, get_ioa_socket_tls_method(ss->client_socket)); - STRCPY(tsi->tls_cipher, get_ioa_socket_tls_cipher(ss->client_socket)); - STRCPY(tsi->realm, ss->realm_options.name); - STRCPY(tsi->origin, ss->origin); + if (tsi && ss) { + tsi->id = ss->id; + tsi->bps = ss->bps; + tsi->start_time = ss->start_time; + tsi->valid = is_allocation_valid(&(ss->alloc)) && !(ss->to_be_closed) && (ss->quota_used); + if (tsi->valid) { + if (ss->alloc.relay_sessions[ALLOC_IPV4_INDEX].s) { + tsi->expiration_time = ss->alloc.relay_sessions[ALLOC_IPV4_INDEX].expiration_time; + if (ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].s) { + if (turn_time_before(tsi->expiration_time, ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].expiration_time)) { + tsi->expiration_time = ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].expiration_time; + } + } + } else if (ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].s) { + tsi->expiration_time = ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].expiration_time; + } + if (ss->client_socket) { + tsi->client_protocol = get_ioa_socket_type(ss->client_socket); + addr_cpy(&(tsi->local_addr_data.addr), get_local_addr_from_ioa_socket(ss->client_socket)); + addr_to_string(&(tsi->local_addr_data.addr), (uint8_t *)tsi->local_addr_data.saddr); + addr_cpy(&(tsi->remote_addr_data.addr), get_remote_addr_from_ioa_socket(ss->client_socket)); + addr_to_string(&(tsi->remote_addr_data.addr), (uint8_t *)tsi->remote_addr_data.saddr); + } + { + if (ss->alloc.relay_sessions[ALLOC_IPV4_INDEX].s) { + tsi->peer_protocol = get_ioa_socket_type(ss->alloc.relay_sessions[ALLOC_IPV4_INDEX].s); + if (ss->alloc.is_valid) { + addr_cpy(&(tsi->relay_addr_data_ipv4.addr), + get_local_addr_from_ioa_socket(ss->alloc.relay_sessions[ALLOC_IPV4_INDEX].s)); + addr_to_string(&(tsi->relay_addr_data_ipv4.addr), (uint8_t *)tsi->relay_addr_data_ipv4.saddr); + } + } + if (ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].s) { + tsi->peer_protocol = get_ioa_socket_type(ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].s); + if (ss->alloc.is_valid) { + addr_cpy(&(tsi->relay_addr_data_ipv6.addr), + get_local_addr_from_ioa_socket(ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].s)); + addr_to_string(&(tsi->relay_addr_data_ipv6.addr), (uint8_t *)tsi->relay_addr_data_ipv6.saddr); + } + } + } + STRCPY(tsi->username, ss->username); + tsi->enforce_fingerprints = ss->enforce_fingerprints; + STRCPY(tsi->tls_method, get_ioa_socket_tls_method(ss->client_socket)); + STRCPY(tsi->tls_cipher, get_ioa_socket_tls_cipher(ss->client_socket)); + STRCPY(tsi->realm, ss->realm_options.name); + STRCPY(tsi->origin, ss->origin); - if(ss->t_received_packets > ss->received_packets) - tsi->received_packets = ss->t_received_packets; - else - tsi->received_packets = ss->received_packets; + if (ss->t_received_packets > ss->received_packets) + tsi->received_packets = ss->t_received_packets; + else + tsi->received_packets = ss->received_packets; - if(ss->t_sent_packets > ss->sent_packets) - tsi->sent_packets = ss->t_sent_packets; - else - tsi->sent_packets = ss->sent_packets; + if (ss->t_sent_packets > ss->sent_packets) + tsi->sent_packets = ss->t_sent_packets; + else + tsi->sent_packets = ss->sent_packets; - if(ss->t_received_bytes > ss->received_bytes) - tsi->received_bytes = ss->t_received_bytes; - else - tsi->received_bytes = ss->received_bytes; + if (ss->t_received_bytes > ss->received_bytes) + tsi->received_bytes = ss->t_received_bytes; + else + tsi->received_bytes = ss->received_bytes; - if(ss->t_sent_bytes > ss->sent_bytes) - tsi->sent_bytes = ss->t_sent_bytes; - else - tsi->sent_bytes = ss->sent_bytes; + if (ss->t_sent_bytes > ss->sent_bytes) + tsi->sent_bytes = ss->t_sent_bytes; + else + tsi->sent_bytes = ss->sent_bytes; - if (ss->t_peer_received_packets > ss->peer_received_packets) - tsi->peer_received_packets = ss->t_peer_received_packets; - else - tsi->peer_received_packets = ss->peer_received_packets; + if (ss->t_peer_received_packets > ss->peer_received_packets) + tsi->peer_received_packets = ss->t_peer_received_packets; + else + tsi->peer_received_packets = ss->peer_received_packets; - if (ss->t_peer_sent_packets > ss->peer_sent_packets) - tsi->peer_sent_packets = ss->t_peer_sent_packets; - else - tsi->peer_sent_packets = ss->peer_sent_packets; + if (ss->t_peer_sent_packets > ss->peer_sent_packets) + tsi->peer_sent_packets = ss->t_peer_sent_packets; + else + tsi->peer_sent_packets = ss->peer_sent_packets; - if (ss->t_peer_received_bytes > ss->peer_received_bytes) - tsi->peer_received_bytes = ss->t_peer_received_bytes; - else - tsi->peer_received_bytes = ss->peer_received_bytes; + if (ss->t_peer_received_bytes > ss->peer_received_bytes) + tsi->peer_received_bytes = ss->t_peer_received_bytes; + else + tsi->peer_received_bytes = ss->peer_received_bytes; - if (ss->t_peer_sent_bytes > ss->peer_sent_bytes) - tsi->peer_sent_bytes = ss->t_peer_sent_bytes; - else - tsi->peer_sent_bytes = ss->peer_sent_bytes; + if (ss->t_peer_sent_bytes > ss->peer_sent_bytes) + tsi->peer_sent_bytes = ss->t_peer_sent_bytes; + else + tsi->peer_sent_bytes = ss->peer_sent_bytes; - { - tsi->received_rate = ss->received_rate; - tsi->sent_rate = ss->sent_rate; - tsi->total_rate = tsi->received_rate + tsi->sent_rate; - tsi->peer_received_rate = ss->peer_received_rate; - tsi->peer_sent_rate = ss->peer_sent_rate; - tsi->peer_total_rate = tsi->peer_received_rate + tsi->peer_sent_rate; - } + { + tsi->received_rate = ss->received_rate; + tsi->sent_rate = ss->sent_rate; + tsi->total_rate = tsi->received_rate + tsi->sent_rate; + tsi->peer_received_rate = ss->peer_received_rate; + tsi->peer_sent_rate = ss->peer_sent_rate; + tsi->peer_total_rate = tsi->peer_received_rate + tsi->peer_sent_rate; + } - tsi->is_mobile = ss->is_mobile; + tsi->is_mobile = ss->is_mobile; - { - size_t i; - for(i=0;ialloc.addr_to_perm.table[i]); + turn_permission_array *parray = &(ss->alloc.addr_to_perm.table[i]); - { - size_t j; - for(j=0;jmain_slots[j]); - if(slot->info.allocated) { - turn_session_info_add_peer(tsi,&(slot->info.addr)); - struct tsi_arg arg = { - tsi, - &(slot->info.addr) - }; - lm_map_foreach_arg(&(slot->info.chns), turn_session_info_foreachcb, &arg); - } - } - } + { + size_t j; + for (j = 0; j < TURN_PERMISSION_ARRAY_SIZE; ++j) { + turn_permission_slot *slot = &(parray->main_slots[j]); + if (slot->info.allocated) { + turn_session_info_add_peer(tsi, &(slot->info.addr)); + struct tsi_arg arg = {tsi, &(slot->info.addr)}; + lm_map_foreach_arg(&(slot->info.chns), turn_session_info_foreachcb, &arg); + } + } + } - { - turn_permission_slot **slots = parray->extra_slots; - if(slots) { - size_t sz = parray->extra_sz; - size_t j; - for(j=0;jinfo.allocated) { - turn_session_info_add_peer(tsi,&(slot->info.addr)); - struct tsi_arg arg = { - tsi, - &(slot->info.addr) - }; - lm_map_foreach_arg(&(slot->info.chns), turn_session_info_foreachcb, &arg); - } - } - } - } - } - } + { + turn_permission_slot **slots = parray->extra_slots; + if (slots) { + size_t sz = parray->extra_sz; + size_t j; + for (j = 0; j < sz; ++j) { + turn_permission_slot *slot = slots[j]; + if (slot && slot->info.allocated) { + turn_session_info_add_peer(tsi, &(slot->info.addr)); + struct tsi_arg arg = {tsi, &(slot->info.addr)}; + lm_map_foreach_arg(&(slot->info.chns), turn_session_info_foreachcb, &arg); + } + } + } + } + } + } - { - tcp_connection_list *tcl = &(ss->alloc.tcs); - if(tcl->elems) { - size_t i; - size_t sz = tcl->sz; - for(i=0;ielems[i]) { - tcp_connection *tc = tcl->elems[i]; - if(tc) { - turn_session_info_add_peer(tsi,&(tc->peer_addr)); - } - } - } - } - } - } + { + tcp_connection_list *tcl = &(ss->alloc.tcs); + if (tcl->elems) { + size_t i; + size_t sz = tcl->sz; + for (i = 0; i < sz; ++i) { + if (tcl->elems[i]) { + tcp_connection *tc = tcl->elems[i]; + if (tc) { + turn_session_info_add_peer(tsi, &(tc->peer_addr)); + } + } + } + } + } + } - ret = 0; - } + ret = 0; + } - return ret; + return ret; } -int report_turn_session_info(turn_turnserver *server, ts_ur_super_session *ss, int force_invalid) -{ - if(server && ss && server->send_turn_session_info) { - struct turn_session_info tsi; - turn_session_info_init(&tsi); - if(turn_session_info_copy_from(&tsi,ss)<0) { - turn_session_info_clean(&tsi); - } else { - if(force_invalid) - tsi.valid = 0; - if(server->send_turn_session_info(&tsi)<0) { - turn_session_info_clean(&tsi); - } else { - return 0; - } - } - } +int report_turn_session_info(turn_turnserver *server, ts_ur_super_session *ss, int force_invalid) { + if (server && ss && server->send_turn_session_info) { + struct turn_session_info tsi; + turn_session_info_init(&tsi); + if (turn_session_info_copy_from(&tsi, ss) < 0) { + turn_session_info_clean(&tsi); + } else { + if (force_invalid) + tsi.valid = 0; + if (server->send_turn_session_info(&tsi) < 0) { + turn_session_info_clean(&tsi); + } else { + return 0; + } + } + } - return -1; + return -1; } /////////// SS ///////////////// -static int mobile_id_to_string(mobile_id_t mid, char *dst, size_t dst_sz) -{ - size_t output_length = 0; +static int mobile_id_to_string(mobile_id_t mid, char *dst, size_t dst_sz) { + size_t output_length = 0; - if(!dst) - return -1; + if (!dst) + return -1; - char *s = base64_encode((const unsigned char *)&mid, - sizeof(mid), - &output_length); + char *s = base64_encode((const unsigned char *)&mid, sizeof(mid), &output_length); - if(!s) - return -1; + if (!s) + return -1; - if(!output_length || (output_length+1 > dst_sz)) { - free(s); - return -1; - } + if (!output_length || (output_length + 1 > dst_sz)) { + free(s); + return -1; + } - memcpy(dst, s, output_length); + memcpy(dst, s, output_length); - free(s); + free(s); - dst[output_length] = 0; + dst[output_length] = 0; - return (int)output_length; + return (int)output_length; } -static mobile_id_t string_to_mobile_id(char* src) -{ - mobile_id_t mid = 0; +static mobile_id_t string_to_mobile_id(char *src) { + mobile_id_t mid = 0; - if(src) { + if (src) { - size_t output_length = 0; + size_t output_length = 0; - unsigned char *out = base64_decode(src, strlen(src), &output_length); + unsigned char *out = base64_decode(src, strlen(src), &output_length); - if(out) { + if (out) { - if(output_length == sizeof(mid)) { - mid = *((mobile_id_t*)out); - } + if (output_length == sizeof(mid)) { + mid = *((mobile_id_t *)out); + } - free(out); - } - } + free(out); + } + } - return mid; + return mid; } -static mobile_id_t get_new_mobile_id(turn_turnserver* server) -{ - mobile_id_t newid = 0; +static mobile_id_t get_new_mobile_id(turn_turnserver *server) { + mobile_id_t newid = 0; - if(server && server->mobile_connections_map) { - ur_map *map = server->mobile_connections_map; - uint64_t sid = server->id; - sid = sid<<56; - do { - while (!newid) { - if(TURN_RANDOM_SIZE == sizeof(mobile_id_t)) - newid = (mobile_id_t)turn_random(); - else { - newid = (mobile_id_t)turn_random(); - newid = (newid<<32) + (mobile_id_t)turn_random(); - } - if(!newid) { - continue; - } - newid = newid & 0x00FFFFFFFFFFFFFFLL; - if(!newid) { - continue; - } - newid = newid | sid; - } - } while(ur_map_get(map, (ur_map_key_type)newid, NULL)); - } - return newid; + if (server && server->mobile_connections_map) { + ur_map *map = server->mobile_connections_map; + uint64_t sid = server->id; + sid = sid << 56; + do { + while (!newid) { + if (TURN_RANDOM_SIZE == sizeof(mobile_id_t)) + newid = (mobile_id_t)turn_random(); + else { + newid = (mobile_id_t)turn_random(); + newid = (newid << 32) + (mobile_id_t)turn_random(); + } + if (!newid) { + continue; + } + newid = newid & 0x00FFFFFFFFFFFFFFLL; + if (!newid) { + continue; + } + newid = newid | sid; + } + } while (ur_map_get(map, (ur_map_key_type)newid, NULL)); + } + return newid; } -static void put_session_into_mobile_map(ts_ur_super_session *ss) -{ - if(ss && ss->server) { - turn_turnserver* server = (turn_turnserver*)(ss->server); - if(*(server->mobility) && server->mobile_connections_map) { - if(!(ss->mobile_id)) { - ss->mobile_id = get_new_mobile_id(server); - mobile_id_to_string(ss->mobile_id, ss->s_mobile_id, sizeof(ss->s_mobile_id)); - } - ur_map_put(server->mobile_connections_map, (ur_map_key_type)(ss->mobile_id), (ur_map_value_type)ss); - } - } - +static void put_session_into_mobile_map(ts_ur_super_session *ss) { + if (ss && ss->server) { + turn_turnserver *server = (turn_turnserver *)(ss->server); + if (*(server->mobility) && server->mobile_connections_map) { + if (!(ss->mobile_id)) { + ss->mobile_id = get_new_mobile_id(server); + mobile_id_to_string(ss->mobile_id, ss->s_mobile_id, sizeof(ss->s_mobile_id)); + } + ur_map_put(server->mobile_connections_map, (ur_map_key_type)(ss->mobile_id), (ur_map_value_type)ss); + } + } } -static void put_session_into_map(ts_ur_super_session *ss) -{ - if(ss && ss->server) { - turn_turnserver* server = (turn_turnserver*)(ss->server); - if(!(ss->id)) { - ss->id = (turnsession_id)((turnsession_id)server->id * TURN_SESSION_ID_FACTOR); - ss->id += ++(server->session_id_counter); - ss->start_time = server->ctime; - } - ur_map_put(server->sessions_map, (ur_map_key_type)(ss->id), (ur_map_value_type)ss); - put_session_into_mobile_map(ss); - } +static void put_session_into_map(ts_ur_super_session *ss) { + if (ss && ss->server) { + turn_turnserver *server = (turn_turnserver *)(ss->server); + if (!(ss->id)) { + ss->id = (turnsession_id)((turnsession_id)server->id * TURN_SESSION_ID_FACTOR); + ss->id += ++(server->session_id_counter); + ss->start_time = server->ctime; + } + ur_map_put(server->sessions_map, (ur_map_key_type)(ss->id), (ur_map_value_type)ss); + put_session_into_mobile_map(ss); + } } -static void delete_session_from_mobile_map(ts_ur_super_session *ss) -{ - if(ss && ss->server && ss->mobile_id) { - turn_turnserver* server = (turn_turnserver*)(ss->server); - if(server->mobile_connections_map) { - ur_map_del(server->mobile_connections_map, (ur_map_key_type)(ss->mobile_id), NULL); - } - ss->mobile_id = 0; - ss->s_mobile_id[0] = 0; - } +static void delete_session_from_mobile_map(ts_ur_super_session *ss) { + if (ss && ss->server && ss->mobile_id) { + turn_turnserver *server = (turn_turnserver *)(ss->server); + if (server->mobile_connections_map) { + ur_map_del(server->mobile_connections_map, (ur_map_key_type)(ss->mobile_id), NULL); + } + ss->mobile_id = 0; + ss->s_mobile_id[0] = 0; + } } -static void delete_session_from_map(ts_ur_super_session *ss) -{ - if(ss && ss->server) { - turn_turnserver* server = (turn_turnserver*)(ss->server); - ur_map_del(server->sessions_map, (ur_map_key_type)(ss->id), NULL); - delete_session_from_mobile_map(ss); - } +static void delete_session_from_map(ts_ur_super_session *ss) { + if (ss && ss->server) { + turn_turnserver *server = (turn_turnserver *)(ss->server); + ur_map_del(server->sessions_map, (ur_map_key_type)(ss->id), NULL); + delete_session_from_mobile_map(ss); + } } -static ts_ur_super_session* get_session_from_map(turn_turnserver* server, turnsession_id sid) -{ - ts_ur_super_session *ss = NULL; - if(server) { - ur_map_value_type value = 0; - if(ur_map_get(server->sessions_map, (ur_map_key_type)sid, &value) && value) { - ss = (ts_ur_super_session*)value; - } - } - return ss; +static ts_ur_super_session *get_session_from_map(turn_turnserver *server, turnsession_id sid) { + ts_ur_super_session *ss = NULL; + if (server) { + ur_map_value_type value = 0; + if (ur_map_get(server->sessions_map, (ur_map_key_type)sid, &value) && value) { + ss = (ts_ur_super_session *)value; + } + } + return ss; } -void turn_cancel_session(turn_turnserver *server, turnsession_id sid) -{ - if(server) { - ts_ur_super_session* ts = get_session_from_map(server, sid); - if(ts) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Session %018llu to be forcefully canceled\n",(unsigned long long)sid); - shutdown_client_connection(server, ts, 0, "Forceful shutdown"); - } - } +void turn_cancel_session(turn_turnserver *server, turnsession_id sid) { + if (server) { + ts_ur_super_session *ts = get_session_from_map(server, sid); + if (ts) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Session %018llu to be forcefully canceled\n", (unsigned long long)sid); + shutdown_client_connection(server, ts, 0, "Forceful shutdown"); + } + } } -static ts_ur_super_session* get_session_from_mobile_map(turn_turnserver* server, mobile_id_t mid) -{ - ts_ur_super_session *ss = NULL; - if(server && *(server->mobility) && server->mobile_connections_map && mid) { - ur_map_value_type value = 0; - if(ur_map_get(server->mobile_connections_map, (ur_map_key_type)mid, &value) && value) { - ss = (ts_ur_super_session*)value; - } - } - return ss; +static ts_ur_super_session *get_session_from_mobile_map(turn_turnserver *server, mobile_id_t mid) { + ts_ur_super_session *ss = NULL; + if (server && *(server->mobility) && server->mobile_connections_map && mid) { + ur_map_value_type value = 0; + if (ur_map_get(server->mobile_connections_map, (ur_map_key_type)mid, &value) && value) { + ss = (ts_ur_super_session *)value; + } + } + return ss; } -static ts_ur_super_session* create_new_ss(turn_turnserver* server) { - // - //printf("%s: 111.111: session size=%lu\n",__FUNCTION__,(unsigned long)sizeof(ts_ur_super_session)); - // - ts_ur_super_session *ss = (ts_ur_super_session*)calloc(sizeof(ts_ur_super_session), 1); - ss->server = server; - get_default_realm_options(&(ss->realm_options)); - put_session_into_map(ss); - init_allocation(ss,&(ss->alloc), server->tcp_relay_connections); - return ss; +static ts_ur_super_session *create_new_ss(turn_turnserver *server) { + // + // printf("%s: 111.111: session size=%lu\n",__FUNCTION__,(unsigned long)sizeof(ts_ur_super_session)); + // + ts_ur_super_session *ss = (ts_ur_super_session *)calloc(sizeof(ts_ur_super_session), 1); + ss->server = server; + get_default_realm_options(&(ss->realm_options)); + put_session_into_map(ss); + init_allocation(ss, &(ss->alloc), server->tcp_relay_connections); + return ss; } static void delete_ur_map_ss(void *p, SOCKET_TYPE socket_type) { - if (p) { - ts_ur_super_session* ss = (ts_ur_super_session*) p; - delete_session_from_map(ss); - IOA_CLOSE_SOCKET(ss->client_socket); - clear_allocation(get_allocation_ss(ss), socket_type); - IOA_EVENT_DEL(ss->to_be_allocated_timeout_ev); - free(p); - } + if (p) { + ts_ur_super_session *ss = (ts_ur_super_session *)p; + delete_session_from_map(ss); + IOA_CLOSE_SOCKET(ss->client_socket); + clear_allocation(get_allocation_ss(ss), socket_type); + IOA_EVENT_DEL(ss->to_be_allocated_timeout_ev); + free(p); + } } /////////// clean all ///////////////////// -static int turn_server_remove_all_from_ur_map_ss(ts_ur_super_session* ss, SOCKET_TYPE socket_type) { - if (!ss) - return 0; - else { - int ret = 0; - if (ss->client_socket) { - clear_ioa_socket_session_if(ss->client_socket, ss); - } - if (get_relay_socket_ss(ss,AF_INET)) { - clear_ioa_socket_session_if(get_relay_socket_ss(ss,AF_INET), ss); - } - if (get_relay_socket_ss(ss,AF_INET6)) { - clear_ioa_socket_session_if(get_relay_socket_ss(ss,AF_INET6), ss); - } - delete_ur_map_ss(ss, socket_type); - return ret; - } +static int turn_server_remove_all_from_ur_map_ss(ts_ur_super_session *ss, SOCKET_TYPE socket_type) { + if (!ss) + return 0; + else { + int ret = 0; + if (ss->client_socket) { + clear_ioa_socket_session_if(ss->client_socket, ss); + } + if (get_relay_socket_ss(ss, AF_INET)) { + clear_ioa_socket_session_if(get_relay_socket_ss(ss, AF_INET), ss); + } + if (get_relay_socket_ss(ss, AF_INET6)) { + clear_ioa_socket_session_if(get_relay_socket_ss(ss, AF_INET6), ss); + } + delete_ur_map_ss(ss, socket_type); + return ret; + } } ///////////////////////////////////////////////////////////////// -static void client_ss_channel_timeout_handler(ioa_engine_handle e, void* arg) { +static void client_ss_channel_timeout_handler(ioa_engine_handle e, void *arg) { - UNUSED_ARG(e); + UNUSED_ARG(e); - if (!arg) - return; + if (!arg) + return; - ch_info* chn = (ch_info*) arg; + ch_info *chn = (ch_info *)arg; - turn_channel_delete(chn); + turn_channel_delete(chn); } -static void client_ss_perm_timeout_handler(ioa_engine_handle e, void* arg) { +static void client_ss_perm_timeout_handler(ioa_engine_handle e, void *arg) { - UNUSED_ARG(e); + UNUSED_ARG(e); - if (!arg) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: empty permission to be cleaned\n",__FUNCTION__); - return; - } + if (!arg) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: empty permission to be cleaned\n", __FUNCTION__); + return; + } - turn_permission_info* tinfo = (turn_permission_info*) arg; + turn_permission_info *tinfo = (turn_permission_info *)arg; - if(!(tinfo->allocated)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: unallocated permission to be cleaned\n",__FUNCTION__); - return; - } + if (!(tinfo->allocated)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: unallocated permission to be cleaned\n", __FUNCTION__); + return; + } - if(!(tinfo->lifetime_ev)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: strange (1) permission to be cleaned\n",__FUNCTION__); - } + if (!(tinfo->lifetime_ev)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: strange (1) permission to be cleaned\n", __FUNCTION__); + } - if(!(tinfo->owner)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: strange (2) permission to be cleaned\n",__FUNCTION__); - } + if (!(tinfo->owner)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: strange (2) permission to be cleaned\n", __FUNCTION__); + } - turn_permission_clean(tinfo); + turn_permission_clean(tinfo); } /////////////////////////////////////////////////////////////////// -static int update_turn_permission_lifetime(ts_ur_super_session *ss, turn_permission_info *tinfo, turn_time_t time_delta) { +static int update_turn_permission_lifetime(ts_ur_super_session *ss, turn_permission_info *tinfo, + turn_time_t time_delta) { - if (ss && tinfo && tinfo->owner) { + if (ss && tinfo && tinfo->owner) { - turn_turnserver *server = (turn_turnserver *) (ss->server); + turn_turnserver *server = (turn_turnserver *)(ss->server); - if (server) { + if (server) { - if(!time_delta) time_delta = *(server->permission_lifetime); - tinfo->expiration_time = server->ctime + time_delta; + if (!time_delta) + time_delta = *(server->permission_lifetime); + tinfo->expiration_time = server->ctime + time_delta; - IOA_EVENT_DEL(tinfo->lifetime_ev); - tinfo->lifetime_ev = set_ioa_timer(server->e, time_delta, 0, - client_ss_perm_timeout_handler, tinfo, 0, - "client_ss_channel_timeout_handler"); + IOA_EVENT_DEL(tinfo->lifetime_ev); + tinfo->lifetime_ev = set_ioa_timer(server->e, time_delta, 0, client_ss_perm_timeout_handler, tinfo, 0, + "client_ss_channel_timeout_handler"); - if(server->verbose) { - tinfo->verbose = 1; - tinfo->session_id = ss->id; - char s[257]="\0"; - addr_to_string(&(tinfo->addr),(uint8_t*)s); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "session %018llu: peer %s lifetime updated: %lu\n",(unsigned long long)ss->id,s,(unsigned long)time_delta); - } + if (server->verbose) { + tinfo->verbose = 1; + tinfo->session_id = ss->id; + char s[257] = "\0"; + addr_to_string(&(tinfo->addr), (uint8_t *)s); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "session %018llu: peer %s lifetime updated: %lu\n", + (unsigned long long)ss->id, s, (unsigned long)time_delta); + } - return 0; - } - } - return -1; + return 0; + } + } + return -1; } -static int update_channel_lifetime(ts_ur_super_session *ss, ch_info* chn) -{ +static int update_channel_lifetime(ts_ur_super_session *ss, ch_info *chn) { - if (chn) { + if (chn) { - turn_permission_info* tinfo = (turn_permission_info*) (chn->owner); + turn_permission_info *tinfo = (turn_permission_info *)(chn->owner); - if (tinfo && tinfo->owner) { + if (tinfo && tinfo->owner) { - turn_turnserver *server = (turn_turnserver *) (ss->server); + turn_turnserver *server = (turn_turnserver *)(ss->server); - if (server) { + if (server) { - if (update_turn_permission_lifetime(ss, tinfo, *(server->channel_lifetime)) < 0) - return -1; + if (update_turn_permission_lifetime(ss, tinfo, *(server->channel_lifetime)) < 0) + return -1; - chn->expiration_time = server->ctime + *(server->channel_lifetime); + chn->expiration_time = server->ctime + *(server->channel_lifetime); - IOA_EVENT_DEL(chn->lifetime_ev); - chn->lifetime_ev = set_ioa_timer(server->e, *(server->channel_lifetime), 0, - client_ss_channel_timeout_handler, - chn, 0, - "client_ss_channel_timeout_handler"); + IOA_EVENT_DEL(chn->lifetime_ev); + chn->lifetime_ev = set_ioa_timer(server->e, *(server->channel_lifetime), 0, client_ss_channel_timeout_handler, + chn, 0, "client_ss_channel_timeout_handler"); - return 0; - } - } - } - return -1; + return 0; + } + } + } + return -1; } /////////////// TURN /////////////////////////// -#define SKIP_ATTRIBUTES case STUN_ATTRIBUTE_OAUTH_ACCESS_TOKEN: case STUN_ATTRIBUTE_PRIORITY: case STUN_ATTRIBUTE_FINGERPRINT: case STUN_ATTRIBUTE_MESSAGE_INTEGRITY: break; \ - case STUN_ATTRIBUTE_USERNAME: case STUN_ATTRIBUTE_REALM: case STUN_ATTRIBUTE_NONCE: case STUN_ATTRIBUTE_ORIGIN: \ - sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh),\ - ioa_network_buffer_get_size(in_buffer->nbh), sar); \ - continue +#define SKIP_ATTRIBUTES \ + case STUN_ATTRIBUTE_OAUTH_ACCESS_TOKEN: \ + case STUN_ATTRIBUTE_PRIORITY: \ + case STUN_ATTRIBUTE_FINGERPRINT: \ + case STUN_ATTRIBUTE_MESSAGE_INTEGRITY: \ + break; \ + case STUN_ATTRIBUTE_USERNAME: \ + case STUN_ATTRIBUTE_REALM: \ + case STUN_ATTRIBUTE_NONCE: \ + case STUN_ATTRIBUTE_ORIGIN: \ + sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), \ + sar); \ + continue static uint8_t get_transport_value(const uint8_t *value) { - if((value[0] == STUN_ATTRIBUTE_TRANSPORT_UDP_VALUE)|| - (value[0] == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE)) { - return value[0]; - } - return 0; + if ((value[0] == STUN_ATTRIBUTE_TRANSPORT_UDP_VALUE) || (value[0] == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE)) { + return value[0]; + } + return 0; } -static int handle_turn_allocate(turn_turnserver *server, - ts_ur_super_session *ss, stun_tid *tid, int *resp_constructed, - int *err_code, const uint8_t **reason, uint16_t *unknown_attrs, uint16_t *ua_num, - ioa_net_data *in_buffer, ioa_network_buffer_handle nbh) { +static int handle_turn_allocate(turn_turnserver *server, ts_ur_super_session *ss, stun_tid *tid, int *resp_constructed, + int *err_code, const uint8_t **reason, uint16_t *unknown_attrs, uint16_t *ua_num, + ioa_net_data *in_buffer, ioa_network_buffer_handle nbh) { + int err_code4 = 0; + int err_code6 = 0; - int err_code4 = 0; - int err_code6 = 0; + allocation *alloc = get_allocation_ss(ss); - allocation* alloc = get_allocation_ss(ss); + if (is_allocation_valid(alloc)) { - if (is_allocation_valid(alloc)) { + if (!stun_tid_equals(tid, &(alloc->tid))) { + *err_code = 437; + *reason = (const uint8_t *)"Wrong TID"; + } else { + size_t len = ioa_network_buffer_get_size(nbh); + ioa_addr xor_relayed_addr1, *pxor_relayed_addr1 = NULL; + ioa_addr xor_relayed_addr2, *pxor_relayed_addr2 = NULL; + ioa_addr *relayed_addr1 = get_local_addr_from_ioa_socket(get_relay_socket_ss(ss, AF_INET)); + ioa_addr *relayed_addr2 = get_local_addr_from_ioa_socket(get_relay_socket_ss(ss, AF_INET6)); - if (!stun_tid_equals(tid, &(alloc->tid))) { - *err_code = 437; - *reason = (const uint8_t *)"Wrong TID"; - } else { - size_t len = ioa_network_buffer_get_size(nbh); - ioa_addr xor_relayed_addr1, *pxor_relayed_addr1=NULL; - ioa_addr xor_relayed_addr2, *pxor_relayed_addr2=NULL; - ioa_addr *relayed_addr1 = get_local_addr_from_ioa_socket(get_relay_socket_ss(ss,AF_INET)); - ioa_addr *relayed_addr2 = get_local_addr_from_ioa_socket(get_relay_socket_ss(ss,AF_INET6)); + if (get_relay_session_failure(alloc, AF_INET)) { + addr_set_any(&xor_relayed_addr1); + pxor_relayed_addr1 = &xor_relayed_addr1; + } else if (relayed_addr1) { + if (server->external_ip_set) { + addr_cpy(&xor_relayed_addr1, &(server->external_ip)); + addr_set_port(&xor_relayed_addr1, addr_get_port(relayed_addr1)); + } else { + addr_cpy(&xor_relayed_addr1, relayed_addr1); + } + pxor_relayed_addr1 = &xor_relayed_addr1; + } - if(get_relay_session_failure(alloc,AF_INET)) { - addr_set_any(&xor_relayed_addr1); - pxor_relayed_addr1 = &xor_relayed_addr1; - } else if(relayed_addr1) { - if(server->external_ip_set) { - addr_cpy(&xor_relayed_addr1, &(server->external_ip)); - addr_set_port(&xor_relayed_addr1,addr_get_port(relayed_addr1)); - } else { - addr_cpy(&xor_relayed_addr1, relayed_addr1); - } - pxor_relayed_addr1 = &xor_relayed_addr1; - } + if (get_relay_session_failure(alloc, AF_INET6)) { + addr_set_any(&xor_relayed_addr2); + pxor_relayed_addr2 = &xor_relayed_addr2; + } else if (relayed_addr2) { + if (server->external_ip_set) { + addr_cpy(&xor_relayed_addr2, &(server->external_ip)); + addr_set_port(&xor_relayed_addr2, addr_get_port(relayed_addr2)); + } else { + addr_cpy(&xor_relayed_addr2, relayed_addr2); + } + pxor_relayed_addr2 = &xor_relayed_addr2; + } - if(get_relay_session_failure(alloc,AF_INET6)) { - addr_set_any(&xor_relayed_addr2); - pxor_relayed_addr2 = &xor_relayed_addr2; - } else if(relayed_addr2) { - if(server->external_ip_set) { - addr_cpy(&xor_relayed_addr2, &(server->external_ip)); - addr_set_port(&xor_relayed_addr2,addr_get_port(relayed_addr2)); - } else { - addr_cpy(&xor_relayed_addr2, relayed_addr2); - } - pxor_relayed_addr2 = &xor_relayed_addr2; - } + if (pxor_relayed_addr1 || pxor_relayed_addr2) { + uint32_t lifetime = 0; + if (pxor_relayed_addr1) { + lifetime = (get_relay_session(alloc, pxor_relayed_addr1->ss.sa_family)->expiration_time - server->ctime); + } else if (pxor_relayed_addr2) { + lifetime = (get_relay_session(alloc, pxor_relayed_addr2->ss.sa_family)->expiration_time - server->ctime); + } + stun_set_allocate_response_str(ioa_network_buffer_data(nbh), &len, tid, pxor_relayed_addr1, pxor_relayed_addr2, + get_remote_addr_from_ioa_socket(ss->client_socket), lifetime, + *(server->max_allocate_lifetime), 0, NULL, 0, ss->s_mobile_id); + ioa_network_buffer_set_size(nbh, len); + *resp_constructed = 1; + } + } - if(pxor_relayed_addr1 || pxor_relayed_addr2) { - uint32_t lifetime = 0; - if(pxor_relayed_addr1) { - lifetime = (get_relay_session(alloc,pxor_relayed_addr1->ss.sa_family)->expiration_time - server->ctime); - } else if(pxor_relayed_addr2) { - lifetime = (get_relay_session(alloc,pxor_relayed_addr2->ss.sa_family)->expiration_time - server->ctime); - } - stun_set_allocate_response_str(ioa_network_buffer_data(nbh), &len, - tid, - pxor_relayed_addr1, pxor_relayed_addr2, - get_remote_addr_from_ioa_socket(ss->client_socket), - lifetime,*(server->max_allocate_lifetime), 0, NULL, 0, - ss->s_mobile_id); - ioa_network_buffer_set_size(nbh,len); - *resp_constructed = 1; - } - } + } else { - } else { + uint8_t transport = 0; + turn_time_t lifetime = 0; + int even_port = -1; + int dont_fragment = 0; + uint64_t in_reservation_token = 0; + int af4 = 0; + int af6 = 0; + uint8_t username[STUN_MAX_USERNAME_SIZE + 1] = "\0"; + size_t ulen = 0; + band_limit_t bps = 0; + band_limit_t max_bps = 0; - uint8_t transport = 0; - turn_time_t lifetime = 0; - int even_port = -1; - int dont_fragment = 0; - uint64_t in_reservation_token = 0; - int af4 = 0; - int af6 = 0; - uint8_t username[STUN_MAX_USERNAME_SIZE+1]="\0"; - size_t ulen = 0; - band_limit_t bps = 0; - band_limit_t max_bps = 0; + stun_attr_ref sar = + stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh)); + while (sar && (!(*err_code)) && (*ua_num < MAX_NUMBER_OF_UNKNOWN_ATTRS)) { - stun_attr_ref sar = stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh)); - while (sar && (!(*err_code)) && (*ua_num < MAX_NUMBER_OF_UNKNOWN_ATTRS)) { + int attr_type = stun_attr_get_type(sar); - int attr_type = stun_attr_get_type(sar); + if (attr_type == STUN_ATTRIBUTE_USERNAME) { + const uint8_t *value = stun_attr_get_value(sar); + if (value) { + ulen = stun_attr_get_len(sar); + if (ulen >= sizeof(username)) { + *err_code = 400; + *reason = (const uint8_t *)"User name is too long"; + break; + } + memcpy(username, value, ulen); + username[ulen] = 0; + if (!is_secure_string(username, 1)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: wrong username: %s\n", __FUNCTION__, (char *)username); + username[0] = 0; + *err_code = 400; + break; + } + } + } - if(attr_type == STUN_ATTRIBUTE_USERNAME) { - const uint8_t* value = stun_attr_get_value(sar); - if (value) { - ulen = stun_attr_get_len(sar); - if(ulen>=sizeof(username)) { - *err_code = 400; - *reason = (const uint8_t *)"User name is too long"; - break; - } - memcpy(username,value,ulen); - username[ulen]=0; - if(!is_secure_string(username,1)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: wrong username: %s\n", __FUNCTION__, (char*)username); - username[0]=0; - *err_code = 400; - break; - } - } - } + switch (attr_type) { + SKIP_ATTRIBUTES; + case STUN_ATTRIBUTE_NEW_BANDWIDTH: + bps = stun_attr_get_bandwidth(sar); + break; + case STUN_ATTRIBUTE_MOBILITY_TICKET: + if (!(*(server->mobility))) { + *err_code = 405; + *reason = (const uint8_t *)"Mobility Forbidden"; + } else if (stun_attr_get_len(sar) != 0) { + *err_code = 400; + *reason = (const uint8_t *)"Wrong Mobility Field"; + } else { + ss->is_mobile = 1; + } + break; + case STUN_ATTRIBUTE_REQUESTED_TRANSPORT: { + if (stun_attr_get_len(sar) != 4) { + *err_code = 400; + *reason = (const uint8_t *)"Wrong Transport Field"; + } else if (transport) { + *err_code = 400; + *reason = (const uint8_t *)"Duplicate Transport Fields"; + } else { + const uint8_t *value = stun_attr_get_value(sar); + if (value) { + transport = get_transport_value(value); + if (!transport) { + *err_code = 442; + } + if ((transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE) && *(server->no_tcp_relay)) { + *err_code = 442; + *reason = (const uint8_t *)"TCP Transport is not allowed by the TURN Server configuration"; + } else if ((transport == STUN_ATTRIBUTE_TRANSPORT_UDP_VALUE) && *(server->no_udp_relay)) { + *err_code = 442; + *reason = (const uint8_t *)"UDP Transport is not allowed by the TURN Server configuration"; + } else if (ss->client_socket) { + SOCKET_TYPE cst = get_ioa_socket_type(ss->client_socket); + if ((transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE) && !is_stream_socket(cst)) { + *err_code = 400; + *reason = (const uint8_t *)"Wrong Transport Data"; + } else { + ss->is_tcp_relay = (transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE); + } + } + } else { + *err_code = 400; + *reason = (const uint8_t *)"Wrong Transport Data"; + } + } + } break; + case STUN_ATTRIBUTE_DONT_FRAGMENT: + dont_fragment = 1; + if (!(server->dont_fragment)) + unknown_attrs[(*ua_num)++] = nswap16(attr_type); + break; + case STUN_ATTRIBUTE_LIFETIME: { + if (stun_attr_get_len(sar) != 4) { + *err_code = 400; + *reason = (const uint8_t *)"Wrong Lifetime Field"; + } else { + const uint8_t *value = stun_attr_get_value(sar); + if (!value) { + *err_code = 400; + *reason = (const uint8_t *)"Wrong Lifetime Data"; + } else { + lifetime = nswap32(*((const uint32_t *)value)); + } + } + } break; + case STUN_ATTRIBUTE_EVEN_PORT: { + if (in_reservation_token) { + *err_code = 400; + *reason = (const uint8_t *)"Even Port and Reservation Token cannot be used together"; + } else { + even_port = stun_attr_get_even_port(sar); + if (even_port) { + if (af4 && af6) { + *err_code = 400; + *reason = (const uint8_t *)"Even Port cannot be used with Dual Allocation"; + } + } + } + } break; + case STUN_ATTRIBUTE_RESERVATION_TOKEN: { + int len = stun_attr_get_len(sar); + if (len != 8) { + *err_code = 400; + *reason = (const uint8_t *)"Wrong Format of Reservation Token"; + } else if (af4 || af6) { + *err_code = 400; + *reason = (const uint8_t *)"Address family attribute can not be used with reservation token request"; + } else { + if (even_port >= 0) { + *err_code = 400; + *reason = (const uint8_t *)"Reservation Token cannot be used in this request with even port"; + } else if (in_reservation_token) { + *err_code = 400; + *reason = (const uint8_t *)"Reservation Token cannot be used in this request"; + } else { + in_reservation_token = stun_attr_get_reservation_token_value(sar); + } + } + } break; + case STUN_ATTRIBUTE_ADDITIONAL_ADDRESS_FAMILY: + if (even_port > 0) { + *err_code = 400; + *reason = (const uint8_t *)"Even Port cannot be used with Dual Allocation"; + break; + } + /* Falls through. */ + case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY: { + if (in_reservation_token) { + *err_code = 400; + *reason = (const uint8_t *)"Address family attribute can not be used with reservation token request"; + } else if (af4 || af6) { + *err_code = 400; + *reason = (const uint8_t *)"Extra address family attribute can not be used in the request"; + } else { + int af_req = stun_get_requested_address_family(sar); + switch (af_req) { + case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4: + if (attr_type == STUN_ATTRIBUTE_ADDITIONAL_ADDRESS_FAMILY) { + *err_code = 400; + *reason = (const uint8_t *)"Invalid value of the additional address family attribute"; + } else { + af4 = af_req; + } + break; + case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6: + if (attr_type == STUN_ATTRIBUTE_ADDITIONAL_ADDRESS_FAMILY) { + af4 = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4; + } + af6 = af_req; + break; + default: + *err_code = 440; + } + } + } break; + default: + if (attr_type >= 0x0000 && attr_type <= 0x7FFF) + unknown_attrs[(*ua_num)++] = nswap16(attr_type); + }; + sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), + sar); + } - switch (attr_type) { - SKIP_ATTRIBUTES; - case STUN_ATTRIBUTE_NEW_BANDWIDTH: - bps = stun_attr_get_bandwidth(sar); - break; - case STUN_ATTRIBUTE_MOBILITY_TICKET: - if(!(*(server->mobility))) { - *err_code = 405; - *reason = (const uint8_t *)"Mobility Forbidden"; - } else if (stun_attr_get_len(sar) != 0) { - *err_code = 400; - *reason = (const uint8_t *)"Wrong Mobility Field"; - } else { - ss->is_mobile = 1; - } - break; - case STUN_ATTRIBUTE_REQUESTED_TRANSPORT: { - if (stun_attr_get_len(sar) != 4) { - *err_code = 400; - *reason = (const uint8_t *)"Wrong Transport Field"; - } else if(transport) { - *err_code = 400; - *reason = (const uint8_t *)"Duplicate Transport Fields"; - } else { - const uint8_t* value = stun_attr_get_value(sar); - if (value) { - transport = get_transport_value(value); - if (!transport) { - *err_code = 442; - } - if((transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE) && *(server->no_tcp_relay)) { - *err_code = 442; - *reason = (const uint8_t *)"TCP Transport is not allowed by the TURN Server configuration"; - } else if((transport == STUN_ATTRIBUTE_TRANSPORT_UDP_VALUE) && *(server->no_udp_relay)) { - *err_code = 442; - *reason = (const uint8_t *)"UDP Transport is not allowed by the TURN Server configuration"; - } else if(ss->client_socket) { - SOCKET_TYPE cst = get_ioa_socket_type(ss->client_socket); - if((transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE) && !is_stream_socket(cst)) { - *err_code = 400; - *reason = (const uint8_t *)"Wrong Transport Data"; - } else { - ss->is_tcp_relay = (transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE); - } - } - } else { - *err_code = 400; - *reason = (const uint8_t *)"Wrong Transport Data"; - } - } - } - break; - case STUN_ATTRIBUTE_DONT_FRAGMENT: - dont_fragment = 1; - if(!(server->dont_fragment)) - unknown_attrs[(*ua_num)++] = nswap16(attr_type); - break; - case STUN_ATTRIBUTE_LIFETIME: { - if (stun_attr_get_len(sar) != 4) { - *err_code = 400; - *reason = (const uint8_t *)"Wrong Lifetime Field"; - } else { - const uint8_t* value = stun_attr_get_value(sar); - if (!value) { - *err_code = 400; - *reason = (const uint8_t *)"Wrong Lifetime Data"; - } else { - lifetime = nswap32(*((const uint32_t*)value)); - } - } - } - break; - case STUN_ATTRIBUTE_EVEN_PORT: { - if (in_reservation_token) { - *err_code = 400; - *reason = (const uint8_t *)"Even Port and Reservation Token cannot be used together"; - } else { - even_port = stun_attr_get_even_port(sar); - if(even_port) { - if (af4 && af6) { - *err_code = 400; - *reason = (const uint8_t *)"Even Port cannot be used with Dual Allocation"; - } - } - } - } - break; - case STUN_ATTRIBUTE_RESERVATION_TOKEN: { - int len = stun_attr_get_len(sar); - if (len != 8) { - *err_code = 400; - *reason = (const uint8_t *)"Wrong Format of Reservation Token"; - } else if(af4 || af6) { - *err_code = 400; - *reason = (const uint8_t *)"Address family attribute can not be used with reservation token request"; - } else { - if (even_port >= 0) { - *err_code = 400; - *reason = (const uint8_t *)"Reservation Token cannot be used in this request with even port"; - } else if (in_reservation_token) { - *err_code = 400; - *reason = (const uint8_t *)"Reservation Token cannot be used in this request"; - } else { - in_reservation_token = stun_attr_get_reservation_token_value(sar); - } - } - } - break; - case STUN_ATTRIBUTE_ADDITIONAL_ADDRESS_FAMILY: - if(even_port>0) { - *err_code = 400; - *reason = (const uint8_t *)"Even Port cannot be used with Dual Allocation"; - break; - } - /* Falls through. */ - case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY: { - if(in_reservation_token) { - *err_code = 400; - *reason = (const uint8_t *)"Address family attribute can not be used with reservation token request"; - } else if(af4 || af6) { - *err_code = 400; - *reason = (const uint8_t *)"Extra address family attribute can not be used in the request"; - } else { - int af_req = stun_get_requested_address_family(sar); - switch (af_req) { - case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4: - if(attr_type == STUN_ATTRIBUTE_ADDITIONAL_ADDRESS_FAMILY) { - *err_code = 400; - *reason = (const uint8_t *)"Invalid value of the additional address family attribute"; - } else { - af4 = af_req; - } - break; - case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6: - if(attr_type == STUN_ATTRIBUTE_ADDITIONAL_ADDRESS_FAMILY) { - af4 = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4; - } - af6 = af_req; - break; - default: - *err_code = 440; - } - } - } - break; - default: - if(attr_type>=0x0000 && attr_type<=0x7FFF) - unknown_attrs[(*ua_num)++] = nswap16(attr_type); - }; - sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - sar); - } + if (!transport) { - if (!transport) { + *err_code = 400; + if (!(*reason)) + *reason = (const uint8_t *)"Transport field missed or wrong"; - *err_code = 400; - if(!(*reason)) - *reason = (const uint8_t *)"Transport field missed or wrong"; - - } else if (*ua_num > 0) { + } else if (*ua_num > 0) { - *err_code = 420; + *err_code = 420; - } else if (*err_code) { + } else if (*err_code) { - ; + ; - } else if((transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE) && (dont_fragment || in_reservation_token || (even_port!=-1))) { + } else if ((transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE) && + (dont_fragment || in_reservation_token || (even_port != -1))) { - *err_code = 400; - if(!(*reason)) - *reason = (const uint8_t *)"Request parameters are incompatible with TCP transport"; + *err_code = 400; + if (!(*reason)) + *reason = (const uint8_t *)"Request parameters are incompatible with TCP transport"; - } else { + } else { - if(*(server->mobility)) { - if(!(ss->is_mobile)) { - delete_session_from_mobile_map(ss); - } - } + if (*(server->mobility)) { + if (!(ss->is_mobile)) { + delete_session_from_mobile_map(ss); + } + } - lifetime = stun_adjust_allocate_lifetime(lifetime, *(server->max_allocate_lifetime), ss->max_session_time_auth); - uint64_t out_reservation_token = 0; + lifetime = stun_adjust_allocate_lifetime(lifetime, *(server->max_allocate_lifetime), ss->max_session_time_auth); + uint64_t out_reservation_token = 0; - if(inc_quota(ss, username)<0) { + if (inc_quota(ss, username) < 0) { - *err_code = 486; + *err_code = 486; - } else { + } else { - if(server->allocate_bps_func) { - max_bps = ss->realm_options.perf_options.max_bps; - if(max_bps && (!bps || (bps && (bps>max_bps)))) { - bps = max_bps; - } - if(bps && (ss->bps == 0)) { - ss->bps = server->allocate_bps_func(bps,1); - if(!(ss->bps)) { - *err_code = 486; - *reason = (const uint8_t *)"Allocation Bandwidth Quota Reached"; - } - } - } + if (server->allocate_bps_func) { + max_bps = ss->realm_options.perf_options.max_bps; + if (max_bps && (!bps || (bps && (bps > max_bps)))) { + bps = max_bps; + } + if (bps && (ss->bps == 0)) { + ss->bps = server->allocate_bps_func(bps, 1); + if (!(ss->bps)) { + *err_code = 486; + *reason = (const uint8_t *)"Allocation Bandwidth Quota Reached"; + } + } + } - if(af4) af4 = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4; - if(af6) af6 = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; + if (af4) + af4 = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4; + if (af6) + af6 = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; - if(af4 && af6) { - if(server->external_ip_set) { - *err_code = 440; - *reason = (const uint8_t *)"Dual allocation cannot be supported in the current server configuration"; - } - if(even_port > 0) { - *err_code = 440; - *reason = (const uint8_t *)"Dual allocation cannot be supported with even-port functionality"; - } - } + if (af4 && af6) { + if (server->external_ip_set) { + *err_code = 440; + *reason = (const uint8_t *)"Dual allocation cannot be supported in the current server configuration"; + } + if (even_port > 0) { + *err_code = 440; + *reason = (const uint8_t *)"Dual allocation cannot be supported with even-port functionality"; + } + } - if(!(*err_code)) { - if(!af4 && !af6) { - switch (server->allocation_default_address_family) { - case ALLOCATION_DEFAULT_ADDRESS_FAMILY_KEEP: - switch(get_ioa_socket_address_family(ss->client_socket)) { - case AF_INET6 : - af6 = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; - break; - case AF_INET : - default: - af4 = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4; - break; - } - break; - case ALLOCATION_DEFAULT_ADDRESS_FAMILY_IPV6: - af6 = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; - break; - case ALLOCATION_DEFAULT_ADDRESS_FAMILY_IPV4: - /* no break */ - /* Falls through. */ - default: - af4 = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4; - break; - } - } - if(!af4 && af6) { - int af6res = create_relay_connection(server, ss, lifetime, - af6, transport, - even_port, in_reservation_token, &out_reservation_token, - err_code, reason, - tcp_peer_accept_connection); - if(af6res<0) { - set_relay_session_failure(alloc,AF_INET6); - if(!(*err_code)) { - *err_code = 437; - } - } - } else if(af4 && !af6) { - int af4res = create_relay_connection(server, ss, lifetime, - af4, transport, - even_port, in_reservation_token, &out_reservation_token, - err_code, reason, - tcp_peer_accept_connection); - if(af4res<0) { - set_relay_session_failure(alloc,AF_INET); - if(!(*err_code)) { - *err_code = 437; - } - } - } else { - const uint8_t *reason4 = NULL; - const uint8_t *reason6 = NULL; - { - int af4res = create_relay_connection(server, ss, lifetime, - af4, transport, - even_port, in_reservation_token, &out_reservation_token, - &err_code4, &reason4, - tcp_peer_accept_connection); - if(af4res<0) { - set_relay_session_failure(alloc,AF_INET); - if(!err_code4) { - err_code4 = 440; - } - } - } - { - int af6res = create_relay_connection(server, ss, lifetime, - af6, transport, - even_port, in_reservation_token, &out_reservation_token, - &err_code6, &reason6, - tcp_peer_accept_connection); - if(af6res<0) { - set_relay_session_failure(alloc,AF_INET6); - if(!err_code6) { - err_code6 = 440; - } - } - } + if (!(*err_code)) { + if (!af4 && !af6) { + switch (server->allocation_default_address_family) { + case ALLOCATION_DEFAULT_ADDRESS_FAMILY_KEEP: + switch (get_ioa_socket_address_family(ss->client_socket)) { + case AF_INET6: + af6 = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; + break; + case AF_INET: + default: + af4 = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4; + break; + } + break; + case ALLOCATION_DEFAULT_ADDRESS_FAMILY_IPV6: + af6 = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; + break; + case ALLOCATION_DEFAULT_ADDRESS_FAMILY_IPV4: + /* no break */ + /* Falls through. */ + default: + af4 = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4; + break; + } + } + if (!af4 && af6) { + int af6res = create_relay_connection(server, ss, lifetime, af6, transport, even_port, in_reservation_token, + &out_reservation_token, err_code, reason, tcp_peer_accept_connection); + if (af6res < 0) { + set_relay_session_failure(alloc, AF_INET6); + if (!(*err_code)) { + *err_code = 437; + } + } + } else if (af4 && !af6) { + int af4res = create_relay_connection(server, ss, lifetime, af4, transport, even_port, in_reservation_token, + &out_reservation_token, err_code, reason, tcp_peer_accept_connection); + if (af4res < 0) { + set_relay_session_failure(alloc, AF_INET); + if (!(*err_code)) { + *err_code = 437; + } + } + } else { + const uint8_t *reason4 = NULL; + const uint8_t *reason6 = NULL; + { + int af4res = + create_relay_connection(server, ss, lifetime, af4, transport, even_port, in_reservation_token, + &out_reservation_token, &err_code4, &reason4, tcp_peer_accept_connection); + if (af4res < 0) { + set_relay_session_failure(alloc, AF_INET); + if (!err_code4) { + err_code4 = 440; + } + } + } + { + int af6res = + create_relay_connection(server, ss, lifetime, af6, transport, even_port, in_reservation_token, + &out_reservation_token, &err_code6, &reason6, tcp_peer_accept_connection); + if (af6res < 0) { + set_relay_session_failure(alloc, AF_INET6); + if (!err_code6) { + err_code6 = 440; + } + } + } - if(err_code4 && err_code6) { - if(reason4) { - *err_code = err_code4; - *reason = reason4; - } else if(reason6) { - *err_code = err_code6; - *reason = reason6; - } else { - *err_code = err_code4; - } - } - } - } + if (err_code4 && err_code6) { + if (reason4) { + *err_code = err_code4; + *reason = reason4; + } else if (reason6) { + *err_code = err_code6; + *reason = reason6; + } else { + *err_code = err_code4; + } + } + } + } - if (*err_code) { + if (*err_code) { - if(!(*reason)) { - *reason = (const uint8_t *)"Cannot create relay endpoint(s)"; - } + if (!(*reason)) { + *reason = (const uint8_t *)"Cannot create relay endpoint(s)"; + } - } else { + } else { - set_allocation_valid(alloc,1); + set_allocation_valid(alloc, 1); - stun_tid_cpy(&(alloc->tid), tid); + stun_tid_cpy(&(alloc->tid), tid); - size_t len = ioa_network_buffer_get_size(nbh); + size_t len = ioa_network_buffer_get_size(nbh); - ioa_addr xor_relayed_addr1, *pxor_relayed_addr1=NULL; - ioa_addr xor_relayed_addr2, *pxor_relayed_addr2=NULL; - ioa_addr *relayed_addr1 = get_local_addr_from_ioa_socket(get_relay_socket_ss(ss,AF_INET)); - ioa_addr *relayed_addr2 = get_local_addr_from_ioa_socket(get_relay_socket_ss(ss,AF_INET6)); + ioa_addr xor_relayed_addr1, *pxor_relayed_addr1 = NULL; + ioa_addr xor_relayed_addr2, *pxor_relayed_addr2 = NULL; + ioa_addr *relayed_addr1 = get_local_addr_from_ioa_socket(get_relay_socket_ss(ss, AF_INET)); + ioa_addr *relayed_addr2 = get_local_addr_from_ioa_socket(get_relay_socket_ss(ss, AF_INET6)); - if(get_relay_session_failure(alloc,AF_INET)) { - addr_set_any(&xor_relayed_addr1); - pxor_relayed_addr1 = &xor_relayed_addr1; - } else if(relayed_addr1) { - if(server->external_ip_set) { - addr_cpy(&xor_relayed_addr1, &(server->external_ip)); - addr_set_port(&xor_relayed_addr1,addr_get_port(relayed_addr1)); - } else { - addr_cpy(&xor_relayed_addr1, relayed_addr1); - } - pxor_relayed_addr1 = &xor_relayed_addr1; - } + if (get_relay_session_failure(alloc, AF_INET)) { + addr_set_any(&xor_relayed_addr1); + pxor_relayed_addr1 = &xor_relayed_addr1; + } else if (relayed_addr1) { + if (server->external_ip_set) { + addr_cpy(&xor_relayed_addr1, &(server->external_ip)); + addr_set_port(&xor_relayed_addr1, addr_get_port(relayed_addr1)); + } else { + addr_cpy(&xor_relayed_addr1, relayed_addr1); + } + pxor_relayed_addr1 = &xor_relayed_addr1; + } - if(get_relay_session_failure(alloc,AF_INET6)) { - addr_set_any(&xor_relayed_addr2); - pxor_relayed_addr2 = &xor_relayed_addr2; - } else if(relayed_addr2) { - if(server->external_ip_set) { - addr_cpy(&xor_relayed_addr2, &(server->external_ip)); - addr_set_port(&xor_relayed_addr2,addr_get_port(relayed_addr2)); - } else { - addr_cpy(&xor_relayed_addr2, relayed_addr2); - } - pxor_relayed_addr2 = &xor_relayed_addr2; - } + if (get_relay_session_failure(alloc, AF_INET6)) { + addr_set_any(&xor_relayed_addr2); + pxor_relayed_addr2 = &xor_relayed_addr2; + } else if (relayed_addr2) { + if (server->external_ip_set) { + addr_cpy(&xor_relayed_addr2, &(server->external_ip)); + addr_set_port(&xor_relayed_addr2, addr_get_port(relayed_addr2)); + } else { + addr_cpy(&xor_relayed_addr2, relayed_addr2); + } + pxor_relayed_addr2 = &xor_relayed_addr2; + } - if(pxor_relayed_addr1 || pxor_relayed_addr2) { + if (pxor_relayed_addr1 || pxor_relayed_addr2) { - stun_set_allocate_response_str(ioa_network_buffer_data(nbh), &len, tid, - pxor_relayed_addr1, pxor_relayed_addr2, - get_remote_addr_from_ioa_socket(ss->client_socket), lifetime, - *(server->max_allocate_lifetime),0,NULL, - out_reservation_token, - ss->s_mobile_id); + stun_set_allocate_response_str(ioa_network_buffer_data(nbh), &len, tid, pxor_relayed_addr1, + pxor_relayed_addr2, get_remote_addr_from_ioa_socket(ss->client_socket), + lifetime, *(server->max_allocate_lifetime), 0, NULL, out_reservation_token, + ss->s_mobile_id); - if(ss->bps) { - stun_attr_add_bandwidth_str(ioa_network_buffer_data(nbh), &len, ss->bps); - } + if (ss->bps) { + stun_attr_add_bandwidth_str(ioa_network_buffer_data(nbh), &len, ss->bps); + } - ioa_network_buffer_set_size(nbh,len); - *resp_constructed = 1; + ioa_network_buffer_set_size(nbh, len); + *resp_constructed = 1; - turn_report_allocation_set(&(ss->alloc), lifetime, 0); - } - } - } - } - } + turn_report_allocation_set(&(ss->alloc), lifetime, 0); + } + } + } + } + } - if (!(*resp_constructed)) { + if (!(*resp_constructed)) { - if (!(*err_code)) { - *err_code = 437; - } + if (!(*err_code)) { + *err_code = 437; + } - size_t len = ioa_network_buffer_get_size(nbh); - stun_set_allocate_response_str(ioa_network_buffer_data(nbh), &len, tid, NULL, NULL, NULL, 0, *(server->max_allocate_lifetime), *err_code, *reason, 0, ss->s_mobile_id); - ioa_network_buffer_set_size(nbh,len); - *resp_constructed = 1; - } + size_t len = ioa_network_buffer_get_size(nbh); + stun_set_allocate_response_str(ioa_network_buffer_data(nbh), &len, tid, NULL, NULL, NULL, 0, + *(server->max_allocate_lifetime), *err_code, *reason, 0, ss->s_mobile_id); + ioa_network_buffer_set_size(nbh, len); + *resp_constructed = 1; + } - if(*resp_constructed && !(*err_code)) { - if(err_code4) { - size_t len = ioa_network_buffer_get_size(nbh); - stun_attr_add_address_error_code(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4, err_code4); - ioa_network_buffer_set_size(nbh,len); - } - if(err_code6) { - size_t len = ioa_network_buffer_get_size(nbh); - stun_attr_add_address_error_code(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6, err_code6); - ioa_network_buffer_set_size(nbh,len); - } - } + if (*resp_constructed && !(*err_code)) { + if (err_code4) { + size_t len = ioa_network_buffer_get_size(nbh); + stun_attr_add_address_error_code(ioa_network_buffer_data(nbh), &len, + STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4, err_code4); + ioa_network_buffer_set_size(nbh, len); + } + if (err_code6) { + size_t len = ioa_network_buffer_get_size(nbh); + stun_attr_add_address_error_code(ioa_network_buffer_data(nbh), &len, + STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6, err_code6); + ioa_network_buffer_set_size(nbh, len); + } + } - return 0; + return 0; } static void copy_auth_parameters(ts_ur_super_session *orig_ss, ts_ur_super_session *ss) { - if(orig_ss && ss) { - dec_quota(ss); - memcpy(ss->nonce,orig_ss->nonce,sizeof(ss->nonce)); - ss->nonce_expiration_time = orig_ss->nonce_expiration_time; - memcpy(&(ss->realm_options),&(orig_ss->realm_options),sizeof(ss->realm_options)); - memcpy(ss->username,orig_ss->username,sizeof(ss->username)); - ss->hmackey_set = orig_ss->hmackey_set; - memcpy(ss->hmackey,orig_ss->hmackey,sizeof(ss->hmackey)); - ss->oauth = orig_ss->oauth; - memcpy(ss->origin,orig_ss->origin,sizeof(ss->origin)); - ss->origin_set = orig_ss->origin_set; - memcpy(ss->pwd,orig_ss->pwd,sizeof(ss->pwd)); - ss->max_session_time_auth = orig_ss->max_session_time_auth; - inc_quota(ss,ss->username); - } + if (orig_ss && ss) { + dec_quota(ss); + memcpy(ss->nonce, orig_ss->nonce, sizeof(ss->nonce)); + ss->nonce_expiration_time = orig_ss->nonce_expiration_time; + memcpy(&(ss->realm_options), &(orig_ss->realm_options), sizeof(ss->realm_options)); + memcpy(ss->username, orig_ss->username, sizeof(ss->username)); + ss->hmackey_set = orig_ss->hmackey_set; + memcpy(ss->hmackey, orig_ss->hmackey, sizeof(ss->hmackey)); + ss->oauth = orig_ss->oauth; + memcpy(ss->origin, orig_ss->origin, sizeof(ss->origin)); + ss->origin_set = orig_ss->origin_set; + memcpy(ss->pwd, orig_ss->pwd, sizeof(ss->pwd)); + ss->max_session_time_auth = orig_ss->max_session_time_auth; + inc_quota(ss, ss->username); + } } -static int handle_turn_refresh(turn_turnserver *server, - ts_ur_super_session *ss, stun_tid *tid, int *resp_constructed, - int *err_code, const uint8_t **reason, uint16_t *unknown_attrs, uint16_t *ua_num, - ioa_net_data *in_buffer, ioa_network_buffer_handle nbh, - int message_integrity, int *no_response, int can_resume) { - - allocation* a = get_allocation_ss(ss); - int af4c = 0; - int af6c = 0; - int af4 = 0; - int af6 = 0; - { - int i; - for(i = 0;irelay_sessions[i].s && !ioa_socket_tobeclosed(a->relay_sessions[i].s)) { - int family = get_ioa_socket_address_family(a->relay_sessions[i].s); - if(AF_INET == family) { - af4c = 1; - } else if(AF_INET6 == family) { - af6c = 1; - } - } - } - } - - if (!is_allocation_valid(a) && !(*(server->mobility))) { - - *err_code = 437; - *reason = (const uint8_t *)"Invalid allocation"; - - } else { - - turn_time_t lifetime = 0; - int to_delete = 0; - mobile_id_t mid = 0; - char smid[sizeof(ss->s_mobile_id)] = "\0"; - - stun_attr_ref sar = stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh)); - while (sar && (!(*err_code)) && (*ua_num < MAX_NUMBER_OF_UNKNOWN_ATTRS)) { - int attr_type = stun_attr_get_type(sar); - switch (attr_type) { - SKIP_ATTRIBUTES; - case STUN_ATTRIBUTE_MOBILITY_TICKET: { - if(!(*(server->mobility))) { - *err_code = 405; - *reason = (const uint8_t *)"Mobility forbidden"; - } else { - int smid_len = stun_attr_get_len(sar); - if(smid_len>0 && (((size_t)smid_len)old_mobile_id)) { - *err_code = 400; - *reason = (const uint8_t *)"Mobility ticket cannot be used for a stable, already established allocation"; - } - } - } else { - *err_code = 400; - *reason = (const uint8_t *)"Mobility ticket has wrong length"; - } - } - } - break; - case STUN_ATTRIBUTE_LIFETIME: { - if (stun_attr_get_len(sar) != 4) { - *err_code = 400; - *reason = (const uint8_t *)"Wrong Lifetime field format"; - } else { - const uint8_t* value = stun_attr_get_value(sar); - if (!value) { - *err_code = 400; - *reason = (const uint8_t *)"Wrong lifetime field data"; - } else { - lifetime = nswap32(*((const uint32_t*)value)); - if (!lifetime) - to_delete = 1; - } - } - } - break; - case STUN_ATTRIBUTE_ADDITIONAL_ADDRESS_FAMILY: /* deprecated, for backward compatibility with older versions of TURN-bis */ - case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY: { - int af_req = stun_get_requested_address_family(sar); - { - int is_err = 0; - switch (af_req) { - case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4: - if(!af4c) { - is_err = 1; - } else { - af4 = 1; - } - break; - case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6: - if(!af6c) { - is_err = 1; - } else { - af6 = 1; - } - break; - default: - is_err = 1; - } - - if(is_err) { - *err_code = 443; - *reason = (const uint8_t *)"Peer Address Family Mismatch (1)"; - } - } - } - break; - default: - if(attr_type>=0x0000 && attr_type<=0x7FFF) - unknown_attrs[(*ua_num)++] = nswap16(attr_type); - }; - sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), sar); - } - - if (*ua_num > 0) { - - *err_code = 420; - - } else if (*err_code) { - - ; - - } else if(!is_allocation_valid(a)) { - - if(mid && smid[0]) { - - turnserver_id tsid = ((0xFF00000000000000LL) & mid)>>56; - - if(tsid != server->id) { - - if(server->send_socket_to_relay) { - ioa_socket_handle new_s = detach_ioa_socket(ss->client_socket); - if(new_s) { - if(server->send_socket_to_relay(tsid, mid, tid, new_s, message_integrity, - RMT_MOBILE_SOCKET, in_buffer, can_resume)<0) { - *err_code = 400; - *reason = (const uint8_t *)"Wrong mobile ticket"; - } else { - *no_response = 1; - } - } else { - *err_code = 500; - *reason = (const uint8_t *)"Cannot create new socket"; - return -1; - } - } else { - *err_code = 500; - *reason = (const uint8_t *)"Server send socket procedure is not set"; - } - - ss->to_be_closed = 1; - - } else { - - ts_ur_super_session *orig_ss = get_session_from_mobile_map(server, mid); - if(!orig_ss || orig_ss->to_be_closed || ioa_socket_tobeclosed(orig_ss->client_socket)) { - *err_code = 404; - *reason = (const uint8_t *)"Allocation not found"; - } else if(orig_ss == ss) { - *err_code = 437; - *reason = (const uint8_t *)"Invalid allocation"; - } else if(!(orig_ss->is_mobile)) { - *err_code = 500; - *reason = (const uint8_t *)"Software error: invalid mobile allocation"; - } else if(orig_ss->client_socket == ss->client_socket) { - *err_code = 500; - *reason = (const uint8_t *)"Software error: invalid mobile client socket (orig)"; - } else if(!(ss->client_socket)) { - *err_code = 500; - *reason = (const uint8_t *)"Software error: invalid mobile client socket (new)"; - } else { - - get_realm_options_by_name(orig_ss->realm_options.name, &(ss->realm_options)); - - //Check security: - int postpone_reply = 0; - - if(!(ss->hmackey_set)) { - copy_auth_parameters(orig_ss,ss); - } - - if(check_stun_auth(server, ss, tid, resp_constructed, err_code, reason, in_buffer, nbh, - STUN_METHOD_REFRESH, &message_integrity, &postpone_reply, can_resume)<0) { - if(!(*err_code)) { - *err_code = 401; - } - } - - if(postpone_reply) { - - *no_response = 1; - - } else if(!(*err_code)) { - - //Session transfer: - - if (to_delete) - lifetime = 0; - else { - lifetime = stun_adjust_allocate_lifetime(lifetime, *(server->max_allocate_lifetime), ss->max_session_time_auth); - } - - if (af4c && refresh_relay_connection(server, orig_ss, lifetime, 0, 0, 0, - err_code, AF_INET) < 0) { - - if (!(*err_code)) { - *err_code = 437; - *reason = (const uint8_t *)"Cannot refresh relay connection (internal error)"; - } - - } else if (af6c && refresh_relay_connection(server, orig_ss, lifetime, 0, 0, 0, - err_code, AF_INET6) < 0) { - - if (!(*err_code)) { - *err_code = 437; - *reason = (const uint8_t *)"Cannot refresh relay connection (internal error)"; - } - - } else { - - //Transfer socket: - - ioa_socket_handle s = detach_ioa_socket(ss->client_socket); - - ss->to_be_closed = 1; - - if(!s) { - *err_code = 500; - } else { - - if(attach_socket_to_session(server, s, orig_ss) < 0) { - if(orig_ss->client_socket != s) { - IOA_CLOSE_SOCKET(s); - } - *err_code = 500; - } else { - - if(ss->hmackey_set) { - copy_auth_parameters(ss,orig_ss); - } - - delete_session_from_mobile_map(ss); - delete_session_from_mobile_map(orig_ss); - put_session_into_mobile_map(orig_ss); - - //Use new buffer and redefine ss: - nbh = ioa_network_buffer_allocate(server->e); - - dec_quota(ss); - ss = orig_ss; - inc_quota(ss,ss->username); - - ss->old_mobile_id = mid; - size_t len = ioa_network_buffer_get_size(nbh); - - turn_report_allocation_set(&(ss->alloc), lifetime, 1); - - stun_init_success_response_str(STUN_METHOD_REFRESH, ioa_network_buffer_data(nbh), &len, tid); - uint32_t lt = nswap32(lifetime); - - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_LIFETIME, - (const uint8_t*) <, 4); - ioa_network_buffer_set_size(nbh,len); - - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, - STUN_ATTRIBUTE_MOBILITY_TICKET, - (uint8_t*)ss->s_mobile_id,strlen(ss->s_mobile_id)); - ioa_network_buffer_set_size(nbh,len); +static int handle_turn_refresh(turn_turnserver *server, ts_ur_super_session *ss, stun_tid *tid, int *resp_constructed, + int *err_code, const uint8_t **reason, uint16_t *unknown_attrs, uint16_t *ua_num, + ioa_net_data *in_buffer, ioa_network_buffer_handle nbh, int message_integrity, + int *no_response, int can_resume) { + + allocation *a = get_allocation_ss(ss); + int af4c = 0; + int af6c = 0; + int af4 = 0; + int af6 = 0; + { + int i; + for (i = 0; i < ALLOC_PROTOCOLS_NUMBER; ++i) { + if (a->relay_sessions[i].s && !ioa_socket_tobeclosed(a->relay_sessions[i].s)) { + int family = get_ioa_socket_address_family(a->relay_sessions[i].s); + if (AF_INET == family) { + af4c = 1; + } else if (AF_INET6 == family) { + af6c = 1; + } + } + } + } + + if (!is_allocation_valid(a) && !(*(server->mobility))) { + + *err_code = 437; + *reason = (const uint8_t *)"Invalid allocation"; + + } else { + + turn_time_t lifetime = 0; + int to_delete = 0; + mobile_id_t mid = 0; + char smid[sizeof(ss->s_mobile_id)] = "\0"; + + stun_attr_ref sar = + stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh)); + while (sar && (!(*err_code)) && (*ua_num < MAX_NUMBER_OF_UNKNOWN_ATTRS)) { + int attr_type = stun_attr_get_type(sar); + switch (attr_type) { + SKIP_ATTRIBUTES; + case STUN_ATTRIBUTE_MOBILITY_TICKET: { + if (!(*(server->mobility))) { + *err_code = 405; + *reason = (const uint8_t *)"Mobility forbidden"; + } else { + int smid_len = stun_attr_get_len(sar); + if (smid_len > 0 && (((size_t)smid_len) < sizeof(smid))) { + const uint8_t *smid_val = stun_attr_get_value(sar); + if (smid_val) { + memcpy(smid, smid_val, (size_t)smid_len); + mid = string_to_mobile_id(smid); + if (is_allocation_valid(a) && (mid != ss->old_mobile_id)) { + *err_code = 400; + *reason = + (const uint8_t *)"Mobility ticket cannot be used for a stable, already established allocation"; + } + } + } else { + *err_code = 400; + *reason = (const uint8_t *)"Mobility ticket has wrong length"; + } + } + } break; + case STUN_ATTRIBUTE_LIFETIME: { + if (stun_attr_get_len(sar) != 4) { + *err_code = 400; + *reason = (const uint8_t *)"Wrong Lifetime field format"; + } else { + const uint8_t *value = stun_attr_get_value(sar); + if (!value) { + *err_code = 400; + *reason = (const uint8_t *)"Wrong lifetime field data"; + } else { + lifetime = nswap32(*((const uint32_t *)value)); + if (!lifetime) + to_delete = 1; + } + } + } break; + case STUN_ATTRIBUTE_ADDITIONAL_ADDRESS_FAMILY: /* deprecated, for backward compatibility with older versions of + TURN-bis */ + case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY: { + int af_req = stun_get_requested_address_family(sar); + { + int is_err = 0; + switch (af_req) { + case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4: + if (!af4c) { + is_err = 1; + } else { + af4 = 1; + } + break; + case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6: + if (!af6c) { + is_err = 1; + } else { + af6 = 1; + } + break; + default: + is_err = 1; + } + + if (is_err) { + *err_code = 443; + *reason = (const uint8_t *)"Peer Address Family Mismatch (1)"; + } + } + } break; + default: + if (attr_type >= 0x0000 && attr_type <= 0x7FFF) + unknown_attrs[(*ua_num)++] = nswap16(attr_type); + }; + sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), + sar); + } + + if (*ua_num > 0) { + + *err_code = 420; + + } else if (*err_code) { + + ; + + } else if (!is_allocation_valid(a)) { + + if (mid && smid[0]) { + + turnserver_id tsid = ((0xFF00000000000000LL) & mid) >> 56; + + if (tsid != server->id) { + + if (server->send_socket_to_relay) { + ioa_socket_handle new_s = detach_ioa_socket(ss->client_socket); + if (new_s) { + if (server->send_socket_to_relay(tsid, mid, tid, new_s, message_integrity, RMT_MOBILE_SOCKET, in_buffer, + can_resume) < 0) { + *err_code = 400; + *reason = (const uint8_t *)"Wrong mobile ticket"; + } else { + *no_response = 1; + } + } else { + *err_code = 500; + *reason = (const uint8_t *)"Cannot create new socket"; + return -1; + } + } else { + *err_code = 500; + *reason = (const uint8_t *)"Server send socket procedure is not set"; + } + + ss->to_be_closed = 1; + + } else { + + ts_ur_super_session *orig_ss = get_session_from_mobile_map(server, mid); + if (!orig_ss || orig_ss->to_be_closed || ioa_socket_tobeclosed(orig_ss->client_socket)) { + *err_code = 404; + *reason = (const uint8_t *)"Allocation not found"; + } else if (orig_ss == ss) { + *err_code = 437; + *reason = (const uint8_t *)"Invalid allocation"; + } else if (!(orig_ss->is_mobile)) { + *err_code = 500; + *reason = (const uint8_t *)"Software error: invalid mobile allocation"; + } else if (orig_ss->client_socket == ss->client_socket) { + *err_code = 500; + *reason = (const uint8_t *)"Software error: invalid mobile client socket (orig)"; + } else if (!(ss->client_socket)) { + *err_code = 500; + *reason = (const uint8_t *)"Software error: invalid mobile client socket (new)"; + } else { + + get_realm_options_by_name(orig_ss->realm_options.name, &(ss->realm_options)); + + // Check security: + int postpone_reply = 0; + + if (!(ss->hmackey_set)) { + copy_auth_parameters(orig_ss, ss); + } + + if (check_stun_auth(server, ss, tid, resp_constructed, err_code, reason, in_buffer, nbh, + STUN_METHOD_REFRESH, &message_integrity, &postpone_reply, can_resume) < 0) { + if (!(*err_code)) { + *err_code = 401; + } + } + + if (postpone_reply) { + + *no_response = 1; + + } else if (!(*err_code)) { + + // Session transfer: + + if (to_delete) + lifetime = 0; + else { + lifetime = stun_adjust_allocate_lifetime(lifetime, *(server->max_allocate_lifetime), + ss->max_session_time_auth); + } + + if (af4c && refresh_relay_connection(server, orig_ss, lifetime, 0, 0, 0, err_code, AF_INET) < 0) { + + if (!(*err_code)) { + *err_code = 437; + *reason = (const uint8_t *)"Cannot refresh relay connection (internal error)"; + } + + } else if (af6c && refresh_relay_connection(server, orig_ss, lifetime, 0, 0, 0, err_code, AF_INET6) < 0) { + + if (!(*err_code)) { + *err_code = 437; + *reason = (const uint8_t *)"Cannot refresh relay connection (internal error)"; + } + + } else { + + // Transfer socket: + + ioa_socket_handle s = detach_ioa_socket(ss->client_socket); + + ss->to_be_closed = 1; + + if (!s) { + *err_code = 500; + } else { + + if (attach_socket_to_session(server, s, orig_ss) < 0) { + if (orig_ss->client_socket != s) { + IOA_CLOSE_SOCKET(s); + } + *err_code = 500; + } else { + + if (ss->hmackey_set) { + copy_auth_parameters(ss, orig_ss); + } + + delete_session_from_mobile_map(ss); + delete_session_from_mobile_map(orig_ss); + put_session_into_mobile_map(orig_ss); + + // Use new buffer and redefine ss: + nbh = ioa_network_buffer_allocate(server->e); + + dec_quota(ss); + ss = orig_ss; + inc_quota(ss, ss->username); + + ss->old_mobile_id = mid; + size_t len = ioa_network_buffer_get_size(nbh); + + turn_report_allocation_set(&(ss->alloc), lifetime, 1); + + stun_init_success_response_str(STUN_METHOD_REFRESH, ioa_network_buffer_data(nbh), &len, tid); + uint32_t lt = nswap32(lifetime); + + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_LIFETIME, (const uint8_t *)<, + 4); + ioa_network_buffer_set_size(nbh, len); - if(!(*server->no_software_attribute)) - { - const uint8_t *field = (const uint8_t *) get_version(server); - size_t fsz = strlen(get_version(server)); - size_t len = ioa_network_buffer_get_size(nbh); - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_SOFTWARE, field, fsz); - ioa_network_buffer_set_size(nbh, len); - } - - if(message_integrity) { - size_t len = ioa_network_buffer_get_size(nbh); - stun_attr_add_integrity_str(server->ct,ioa_network_buffer_data(nbh),&len,ss->hmackey,ss->pwd,SHATYPE_DEFAULT); - ioa_network_buffer_set_size(nbh,len); - } + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_MOBILITY_TICKET, + (uint8_t *)ss->s_mobile_id, strlen(ss->s_mobile_id)); + ioa_network_buffer_set_size(nbh, len); - if ((server->fingerprint) || ss->enforce_fingerprints) { - size_t len = ioa_network_buffer_get_size(nbh); - if (stun_attr_add_fingerprint_str(ioa_network_buffer_data(nbh), &len) < 0) { - *err_code = 500; - ioa_network_buffer_delete(server->e, nbh); - return -1; - } - ioa_network_buffer_set_size(nbh, len); - } + if (!(*server->no_software_attribute)) { + const uint8_t *field = (const uint8_t *)get_version(server); + size_t fsz = strlen(get_version(server)); + size_t len = ioa_network_buffer_get_size(nbh); + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_SOFTWARE, field, fsz); + ioa_network_buffer_set_size(nbh, len); + } - *no_response = 1; - - return write_client_connection(server, ss, nbh, TTL_IGNORE, TOS_IGNORE); - } - } - } - } + if (message_integrity) { + size_t len = ioa_network_buffer_get_size(nbh); + stun_attr_add_integrity_str(server->ct, ioa_network_buffer_data(nbh), &len, ss->hmackey, ss->pwd, + SHATYPE_DEFAULT); + ioa_network_buffer_set_size(nbh, len); + } - report_turn_session_info(server,orig_ss,0); - } - } - } else { - *err_code = 437; - *reason = (const uint8_t *)"Invalid allocation"; - } + if ((server->fingerprint) || ss->enforce_fingerprints) { + size_t len = ioa_network_buffer_get_size(nbh); + if (stun_attr_add_fingerprint_str(ioa_network_buffer_data(nbh), &len) < 0) { + *err_code = 500; + ioa_network_buffer_delete(server->e, nbh); + return -1; + } + ioa_network_buffer_set_size(nbh, len); + } - } else { - - if (to_delete) - lifetime = 0; - else { - lifetime = stun_adjust_allocate_lifetime(lifetime, *(server->max_allocate_lifetime), ss->max_session_time_auth); - } + *no_response = 1; - if(!af4 && !af6) { - af4 = af4c; - af6 = af6c; - } - - if (af4 && refresh_relay_connection(server, ss, lifetime, 0, 0, 0, - err_code, AF_INET) < 0) { - - if (!(*err_code)) { - *err_code = 437; - *reason = (const uint8_t *)"Cannot refresh relay connection (internal error)"; - } - - } else if (af6 && refresh_relay_connection(server, ss, lifetime, 0, 0, 0, - err_code, AF_INET6) < 0) { - - if (!(*err_code)) { - *err_code = 437; - *reason = (const uint8_t *)"Cannot refresh relay connection (internal error)"; - } - - } else { - - turn_report_allocation_set(&(ss->alloc), lifetime, 1); - - size_t len = ioa_network_buffer_get_size(nbh); - stun_init_success_response_str(STUN_METHOD_REFRESH, ioa_network_buffer_data(nbh), &len, tid); - - if(ss->s_mobile_id[0]) { - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, - STUN_ATTRIBUTE_MOBILITY_TICKET, - (uint8_t*)ss->s_mobile_id,strlen(ss->s_mobile_id)); - ioa_network_buffer_set_size(nbh,len); - } - - uint32_t lt = nswap32(lifetime); - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_LIFETIME, - (const uint8_t*) <, 4); - - ioa_network_buffer_set_size(nbh,len); - - *resp_constructed = 1; - } - } - } - - if(!no_response) { - if (!(*resp_constructed)) { - - if (!(*err_code)) { - *err_code = 437; - } - - size_t len = ioa_network_buffer_get_size(nbh); - stun_init_error_response_str(STUN_METHOD_REFRESH, ioa_network_buffer_data(nbh), &len, *err_code, *reason, tid); - ioa_network_buffer_set_size(nbh,len); - - *resp_constructed = 1; - } - } - - return 0; + return write_client_connection(server, ss, nbh, TTL_IGNORE, TOS_IGNORE); + } + } + } + } + + report_turn_session_info(server, orig_ss, 0); + } + } + } else { + *err_code = 437; + *reason = (const uint8_t *)"Invalid allocation"; + } + + } else { + + if (to_delete) + lifetime = 0; + else { + lifetime = stun_adjust_allocate_lifetime(lifetime, *(server->max_allocate_lifetime), ss->max_session_time_auth); + } + + if (!af4 && !af6) { + af4 = af4c; + af6 = af6c; + } + + if (af4 && refresh_relay_connection(server, ss, lifetime, 0, 0, 0, err_code, AF_INET) < 0) { + + if (!(*err_code)) { + *err_code = 437; + *reason = (const uint8_t *)"Cannot refresh relay connection (internal error)"; + } + + } else if (af6 && refresh_relay_connection(server, ss, lifetime, 0, 0, 0, err_code, AF_INET6) < 0) { + + if (!(*err_code)) { + *err_code = 437; + *reason = (const uint8_t *)"Cannot refresh relay connection (internal error)"; + } + + } else { + + turn_report_allocation_set(&(ss->alloc), lifetime, 1); + + size_t len = ioa_network_buffer_get_size(nbh); + stun_init_success_response_str(STUN_METHOD_REFRESH, ioa_network_buffer_data(nbh), &len, tid); + + if (ss->s_mobile_id[0]) { + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_MOBILITY_TICKET, + (uint8_t *)ss->s_mobile_id, strlen(ss->s_mobile_id)); + ioa_network_buffer_set_size(nbh, len); + } + + uint32_t lt = nswap32(lifetime); + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_LIFETIME, (const uint8_t *)<, 4); + + ioa_network_buffer_set_size(nbh, len); + + *resp_constructed = 1; + } + } + } + + if (!no_response) { + if (!(*resp_constructed)) { + + if (!(*err_code)) { + *err_code = 437; + } + + size_t len = ioa_network_buffer_get_size(nbh); + stun_init_error_response_str(STUN_METHOD_REFRESH, ioa_network_buffer_data(nbh), &len, *err_code, *reason, tid); + ioa_network_buffer_set_size(nbh, len); + + *resp_constructed = 1; + } + } + + return 0; } /* RFC 6062 ==>> */ -static void tcp_deliver_delayed_buffer(unsent_buffer *ub, ioa_socket_handle s, ts_ur_super_session *ss) -{ - if(ub && s && ub->bufs && ub->sz && ss) { - size_t i = 0; - do { - ioa_network_buffer_handle nbh = top_unsent_buffer(ub); - if(!nbh) - break; +static void tcp_deliver_delayed_buffer(unsent_buffer *ub, ioa_socket_handle s, ts_ur_super_session *ss) { + if (ub && s && ub->bufs && ub->sz && ss) { + size_t i = 0; + do { + ioa_network_buffer_handle nbh = top_unsent_buffer(ub); + if (!nbh) + break; - uint32_t bytes = (uint32_t)ioa_network_buffer_get_size(nbh); + uint32_t bytes = (uint32_t)ioa_network_buffer_get_size(nbh); - int ret = send_data_from_ioa_socket_nbh(s, NULL, nbh, TTL_IGNORE, TOS_IGNORE, NULL); - if (ret < 0) { - set_ioa_socket_tobeclosed(s); - } else { - ++(ss->sent_packets); - ss->sent_bytes += bytes; - turn_report_session_usage(ss, 0); - } - pop_unsent_buffer(ub); - } while(!ioa_socket_tobeclosed(s) && ((i++)sent_packets); + ss->sent_bytes += bytes; + turn_report_session_usage(ss, 0); + } + pop_unsent_buffer(ub); + } while (!ioa_socket_tobeclosed(s) && ((i++) < MAX_UNSENT_BUFFER_SIZE)); + } } -static void tcp_peer_input_handler(ioa_socket_handle s, int event_type, ioa_net_data *in_buffer, void *arg, int can_resume) -{ - if (!(event_type & IOA_EV_READ) || !arg) - return; +static void tcp_peer_input_handler(ioa_socket_handle s, int event_type, ioa_net_data *in_buffer, void *arg, + int can_resume) { + if (!(event_type & IOA_EV_READ) || !arg) + return; - UNUSED_ARG(s); - UNUSED_ARG(can_resume); + UNUSED_ARG(s); + UNUSED_ARG(can_resume); - tcp_connection *tc = (tcp_connection*)arg; - ts_ur_super_session *ss=NULL; - allocation *a=(allocation*)tc->owner; - if(a) { - ss=(ts_ur_super_session*)a->owner; - } + tcp_connection *tc = (tcp_connection *)arg; + ts_ur_super_session *ss = NULL; + allocation *a = (allocation *)tc->owner; + if (a) { + ss = (ts_ur_super_session *)a->owner; + } - if((tc->state != TC_STATE_READY) || !(tc->client_s)) { - add_unsent_buffer(&(tc->ub_to_client), in_buffer->nbh); - in_buffer->nbh = NULL; - return; - } + if ((tc->state != TC_STATE_READY) || !(tc->client_s)) { + add_unsent_buffer(&(tc->ub_to_client), in_buffer->nbh); + in_buffer->nbh = NULL; + return; + } - ioa_network_buffer_handle nbh = in_buffer->nbh; - in_buffer->nbh = NULL; + ioa_network_buffer_handle nbh = in_buffer->nbh; + in_buffer->nbh = NULL; - uint32_t bytes = (uint32_t)ioa_network_buffer_get_size(nbh); + uint32_t bytes = (uint32_t)ioa_network_buffer_get_size(nbh); - if (ss) { - ++(ss->peer_received_packets); - ss->peer_received_bytes += bytes; - } + if (ss) { + ++(ss->peer_received_packets); + ss->peer_received_bytes += bytes; + } - int ret = send_data_from_ioa_socket_nbh(tc->client_s, NULL, nbh, TTL_IGNORE, TOS_IGNORE, NULL); - if (ret < 0) { - set_ioa_socket_tobeclosed(s); - } else if(ss) { - ++(ss->sent_packets); - ss->sent_bytes += bytes; - } + int ret = send_data_from_ioa_socket_nbh(tc->client_s, NULL, nbh, TTL_IGNORE, TOS_IGNORE, NULL); + if (ret < 0) { + set_ioa_socket_tobeclosed(s); + } else if (ss) { + ++(ss->sent_packets); + ss->sent_bytes += bytes; + } - if (ss) { - turn_report_session_usage(ss, 0); - } + if (ss) { + turn_report_session_usage(ss, 0); + } } -static void tcp_client_input_handler_rfc6062data(ioa_socket_handle s, int event_type, ioa_net_data *in_buffer, void *arg, int can_resume) -{ - if (!(event_type & IOA_EV_READ) || !arg) - return; +static void tcp_client_input_handler_rfc6062data(ioa_socket_handle s, int event_type, ioa_net_data *in_buffer, + void *arg, int can_resume) { + if (!(event_type & IOA_EV_READ) || !arg) + return; - UNUSED_ARG(s); - UNUSED_ARG(can_resume); + UNUSED_ARG(s); + UNUSED_ARG(can_resume); - tcp_connection *tc = (tcp_connection*)arg; - ts_ur_super_session *ss=NULL; - allocation *a=(allocation*)tc->owner; - if(a) { - ss=(ts_ur_super_session*)a->owner; - } + tcp_connection *tc = (tcp_connection *)arg; + ts_ur_super_session *ss = NULL; + allocation *a = (allocation *)tc->owner; + if (a) { + ss = (ts_ur_super_session *)a->owner; + } - if(tc->state != TC_STATE_READY) - return; + if (tc->state != TC_STATE_READY) + return; - if(!(tc->peer_s)) - return; + if (!(tc->peer_s)) + return; - ioa_network_buffer_handle nbh = in_buffer->nbh; - in_buffer->nbh = NULL; + ioa_network_buffer_handle nbh = in_buffer->nbh; + in_buffer->nbh = NULL; - uint32_t bytes = (uint32_t)ioa_network_buffer_get_size(nbh); - if(ss) { - ++(ss->received_packets); - ss->received_bytes += bytes; - } + uint32_t bytes = (uint32_t)ioa_network_buffer_get_size(nbh); + if (ss) { + ++(ss->received_packets); + ss->received_bytes += bytes; + } - int skip = 0; - int ret = send_data_from_ioa_socket_nbh(tc->peer_s, NULL, nbh, TTL_IGNORE, TOS_IGNORE, &skip); - if (ret < 0) { - set_ioa_socket_tobeclosed(s); - } + int skip = 0; + int ret = send_data_from_ioa_socket_nbh(tc->peer_s, NULL, nbh, TTL_IGNORE, TOS_IGNORE, &skip); + if (ret < 0) { + set_ioa_socket_tobeclosed(s); + } - if (!skip && ss) { - ++(ss->peer_sent_packets); - ss->peer_sent_bytes += bytes; - } + if (!skip && ss) { + ++(ss->peer_sent_packets); + ss->peer_sent_bytes += bytes; + } - if(ss) - turn_report_session_usage(ss, 0); + if (ss) + turn_report_session_usage(ss, 0); } -static void tcp_conn_bind_timeout_handler(ioa_engine_handle e, void *arg) -{ - UNUSED_ARG(e); - if(arg) { - tcp_connection *tc = (tcp_connection *)arg; - delete_tcp_connection(tc); - } +static void tcp_conn_bind_timeout_handler(ioa_engine_handle e, void *arg) { + UNUSED_ARG(e); + if (arg) { + tcp_connection *tc = (tcp_connection *)arg; + delete_tcp_connection(tc); + } } -static void tcp_peer_connection_completed_callback(int success, void *arg) -{ - if(arg) { - tcp_connection *tc = (tcp_connection *)arg; - allocation *a = (allocation*)(tc->owner); - ts_ur_super_session *ss = (ts_ur_super_session*)(a->owner); - turn_turnserver *server=(turn_turnserver*)(ss->server); - int err_code = 0; +static void tcp_peer_connection_completed_callback(int success, void *arg) { + if (arg) { + tcp_connection *tc = (tcp_connection *)arg; + allocation *a = (allocation *)(tc->owner); + ts_ur_super_session *ss = (ts_ur_super_session *)(a->owner); + turn_turnserver *server = (turn_turnserver *)(ss->server); + int err_code = 0; - IOA_EVENT_DEL(tc->peer_conn_timeout); + IOA_EVENT_DEL(tc->peer_conn_timeout); - ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(server->e); - size_t len = ioa_network_buffer_get_size(nbh); + ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(server->e); + size_t len = ioa_network_buffer_get_size(nbh); - if(success) { - if(register_callback_on_ioa_socket(server->e, tc->peer_s, IOA_EV_READ, tcp_peer_input_handler, tc, 1)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: cannot set TCP peer data input callback\n", __FUNCTION__); - success=0; - err_code = 500; - } - } + if (success) { + if (register_callback_on_ioa_socket(server->e, tc->peer_s, IOA_EV_READ, tcp_peer_input_handler, tc, 1) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: cannot set TCP peer data input callback\n", __FUNCTION__); + success = 0; + err_code = 500; + } + } - if(success) { - tc->state = TC_STATE_PEER_CONNECTED; - stun_init_success_response_str(STUN_METHOD_CONNECT, ioa_network_buffer_data(nbh), &len, &(tc->tid)); - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_CONNECTION_ID, - (const uint8_t*)&(tc->id), 4); + if (success) { + tc->state = TC_STATE_PEER_CONNECTED; + stun_init_success_response_str(STUN_METHOD_CONNECT, ioa_network_buffer_data(nbh), &len, &(tc->tid)); + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_CONNECTION_ID, (const uint8_t *)&(tc->id), + 4); - IOA_EVENT_DEL(tc->conn_bind_timeout); - tc->conn_bind_timeout = set_ioa_timer(server->e, TCP_CONN_BIND_TIMEOUT, 0, - tcp_conn_bind_timeout_handler, tc, 0, - "tcp_conn_bind_timeout_handler"); + IOA_EVENT_DEL(tc->conn_bind_timeout); + tc->conn_bind_timeout = set_ioa_timer(server->e, TCP_CONN_BIND_TIMEOUT, 0, tcp_conn_bind_timeout_handler, tc, 0, + "tcp_conn_bind_timeout_handler"); - } else { - tc->state = TC_STATE_FAILED; - if(!err_code) { - err_code = 447; - } - { - char ls[257]="\0"; - char rs[257]="\0"; - ioa_addr *laddr = get_local_addr_from_ioa_socket(ss->client_socket); - if(laddr) - addr_to_string(laddr,(uint8_t*)ls); - addr_to_string(&(tc->peer_addr),(uint8_t*)rs); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: failure to connect from %s to %s\n", __FUNCTION__, ls,rs); - } - stun_init_error_response_str(STUN_METHOD_CONNECT, ioa_network_buffer_data(nbh), &len, err_code, NULL, &(tc->tid)); - } + } else { + tc->state = TC_STATE_FAILED; + if (!err_code) { + err_code = 447; + } + { + char ls[257] = "\0"; + char rs[257] = "\0"; + ioa_addr *laddr = get_local_addr_from_ioa_socket(ss->client_socket); + if (laddr) + addr_to_string(laddr, (uint8_t *)ls); + addr_to_string(&(tc->peer_addr), (uint8_t *)rs); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: failure to connect from %s to %s\n", __FUNCTION__, ls, rs); + } + stun_init_error_response_str(STUN_METHOD_CONNECT, ioa_network_buffer_data(nbh), &len, err_code, NULL, &(tc->tid)); + } - ioa_network_buffer_set_size(nbh,len); + ioa_network_buffer_set_size(nbh, len); - if(need_stun_authentication(server, ss)) { - stun_attr_add_integrity_str(server->ct,ioa_network_buffer_data(nbh),&len,ss->hmackey,ss->pwd,SHATYPE_DEFAULT); - ioa_network_buffer_set_size(nbh,len); - } + if (need_stun_authentication(server, ss)) { + stun_attr_add_integrity_str(server->ct, ioa_network_buffer_data(nbh), &len, ss->hmackey, ss->pwd, + SHATYPE_DEFAULT); + ioa_network_buffer_set_size(nbh, len); + } - write_client_connection(server, ss, nbh, TTL_IGNORE, TOS_IGNORE); + write_client_connection(server, ss, nbh, TTL_IGNORE, TOS_IGNORE); - if(!success) { - delete_tcp_connection(tc); - } - /* test */ - else if(0) - { - int i = 0; - for(i=0;i<22;i++) { - ioa_network_buffer_handle nbh_test = ioa_network_buffer_allocate(server->e); - size_t len_test = ioa_network_buffer_get_size(nbh_test); - uint8_t *data = ioa_network_buffer_data(nbh_test); - const char* data_test="111.111.111.111.111"; - len_test = strlen(data_test); - memcpy(data,data_test,len_test); - ioa_network_buffer_set_size(nbh_test,len_test); - send_data_from_ioa_socket_nbh(tc->peer_s, NULL, nbh_test, TTL_IGNORE, TOS_IGNORE, NULL); - } - } - } + if (!success) { + delete_tcp_connection(tc); + } + /* test */ + else if (0) { + int i = 0; + for (i = 0; i < 22; i++) { + ioa_network_buffer_handle nbh_test = ioa_network_buffer_allocate(server->e); + size_t len_test = ioa_network_buffer_get_size(nbh_test); + uint8_t *data = ioa_network_buffer_data(nbh_test); + const char *data_test = "111.111.111.111.111"; + len_test = strlen(data_test); + memcpy(data, data_test, len_test); + ioa_network_buffer_set_size(nbh_test, len_test); + send_data_from_ioa_socket_nbh(tc->peer_s, NULL, nbh_test, TTL_IGNORE, TOS_IGNORE, NULL); + } + } + } } -static void tcp_peer_conn_timeout_handler(ioa_engine_handle e, void *arg) -{ - UNUSED_ARG(e); +static void tcp_peer_conn_timeout_handler(ioa_engine_handle e, void *arg) { + UNUSED_ARG(e); - tcp_peer_connection_completed_callback(0,arg); + tcp_peer_connection_completed_callback(0, arg); } -static int tcp_start_connection_to_peer(turn_turnserver *server, ts_ur_super_session *ss, stun_tid *tid, - allocation *a, ioa_addr *peer_addr, - int *err_code, const uint8_t **reason) -{ - FUNCSTART; +static int tcp_start_connection_to_peer(turn_turnserver *server, ts_ur_super_session *ss, stun_tid *tid, allocation *a, + ioa_addr *peer_addr, int *err_code, const uint8_t **reason) { + FUNCSTART; - if(!ss) { - *err_code = 500; - *reason = (const uint8_t *)"Server error: empty session"; - FUNCEND; - return -1; - } + if (!ss) { + *err_code = 500; + *reason = (const uint8_t *)"Server error: empty session"; + FUNCEND; + return -1; + } - if(!peer_addr) { - *err_code = 500; - *reason = (const uint8_t *)"Server error: empty peer addr"; - FUNCEND; - return -1; - } + if (!peer_addr) { + *err_code = 500; + *reason = (const uint8_t *)"Server error: empty peer addr"; + FUNCEND; + return -1; + } - if(!get_relay_socket(a,peer_addr->ss.sa_family)) { - *err_code = 500; - *reason = (const uint8_t *)"Server error: no relay connection created"; - FUNCEND; - return -1; - } + if (!get_relay_socket(a, peer_addr->ss.sa_family)) { + *err_code = 500; + *reason = (const uint8_t *)"Server error: no relay connection created"; + FUNCEND; + return -1; + } - tcp_connection *tc = get_tcp_connection_by_peer(a, peer_addr); - if(tc) { - *err_code = 446; - FUNCEND; - return -1; - } + tcp_connection *tc = get_tcp_connection_by_peer(a, peer_addr); + if (tc) { + *err_code = 446; + FUNCEND; + return -1; + } - tc = create_tcp_connection(server->id, a, tid, peer_addr, err_code); - if(!tc) { - if(!(*err_code)) { - *err_code = 500; - *reason = (const uint8_t *)"Server error: TCP connection object creation failed"; - } - FUNCEND; - return -1; - } else if(*err_code) { - delete_tcp_connection(tc); - FUNCEND; - return -1; - } + tc = create_tcp_connection(server->id, a, tid, peer_addr, err_code); + if (!tc) { + if (!(*err_code)) { + *err_code = 500; + *reason = (const uint8_t *)"Server error: TCP connection object creation failed"; + } + FUNCEND; + return -1; + } else if (*err_code) { + delete_tcp_connection(tc); + FUNCEND; + return -1; + } - IOA_EVENT_DEL(tc->peer_conn_timeout); - tc->peer_conn_timeout = set_ioa_timer(server->e, TCP_PEER_CONN_TIMEOUT, 0, - tcp_peer_conn_timeout_handler, tc, 0, - "tcp_peer_conn_timeout_handler"); + IOA_EVENT_DEL(tc->peer_conn_timeout); + tc->peer_conn_timeout = set_ioa_timer(server->e, TCP_PEER_CONN_TIMEOUT, 0, tcp_peer_conn_timeout_handler, tc, 0, + "tcp_peer_conn_timeout_handler"); - ioa_socket_handle tcs = ioa_create_connecting_tcp_relay_socket(get_relay_socket(a,peer_addr->ss.sa_family), - peer_addr, tcp_peer_connection_completed_callback, tc); - if(!tcs) { - delete_tcp_connection(tc); - *err_code = 500; - *reason = (const uint8_t *)"Server error: TCP relay socket for connection cannot be created"; - FUNCEND; - return -1; - } + ioa_socket_handle tcs = ioa_create_connecting_tcp_relay_socket(get_relay_socket(a, peer_addr->ss.sa_family), + peer_addr, tcp_peer_connection_completed_callback, tc); + if (!tcs) { + delete_tcp_connection(tc); + *err_code = 500; + *reason = (const uint8_t *)"Server error: TCP relay socket for connection cannot be created"; + FUNCEND; + return -1; + } - tc->state = TC_STATE_CLIENT_TO_PEER_CONNECTING; - if(tc->peer_s != tcs) { - IOA_CLOSE_SOCKET(tc->peer_s); - tc->peer_s = tcs; - } - set_ioa_socket_sub_session(tc->peer_s,tc); + tc->state = TC_STATE_CLIENT_TO_PEER_CONNECTING; + if (tc->peer_s != tcs) { + IOA_CLOSE_SOCKET(tc->peer_s); + tc->peer_s = tcs; + } + set_ioa_socket_sub_session(tc->peer_s, tc); - FUNCEND; - return 0; + FUNCEND; + return 0; } -static void tcp_peer_accept_connection(ioa_socket_handle s, void *arg) -{ - if(s) { +static void tcp_peer_accept_connection(ioa_socket_handle s, void *arg) { + if (s) { - if(!arg) { - close_ioa_socket(s); - return; - } + if (!arg) { + close_ioa_socket(s); + return; + } - ts_ur_super_session *ss = (ts_ur_super_session*)arg; - turn_turnserver *server=(turn_turnserver*)(ss->server); + ts_ur_super_session *ss = (ts_ur_super_session *)arg; + turn_turnserver *server = (turn_turnserver *)(ss->server); - FUNCSTART; + FUNCSTART; - allocation *a = &(ss->alloc); - ioa_addr *peer_addr = get_remote_addr_from_ioa_socket(s); - if(!peer_addr) { - close_ioa_socket(s); - FUNCEND; - return; - } + allocation *a = &(ss->alloc); + ioa_addr *peer_addr = get_remote_addr_from_ioa_socket(s); + if (!peer_addr) { + close_ioa_socket(s); + FUNCEND; + return; + } - tcp_connection *tc = get_tcp_connection_by_peer(a, peer_addr); - if(tc) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: peer data socket with this address already exist\n", __FUNCTION__); - if(tc->peer_s != s) - close_ioa_socket(s); - FUNCEND; - return; - } + tcp_connection *tc = get_tcp_connection_by_peer(a, peer_addr); + if (tc) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: peer data socket with this address already exist\n", __FUNCTION__); + if (tc->peer_s != s) + close_ioa_socket(s); + FUNCEND; + return; + } - if(!good_peer_addr(server, ss->realm_options.name, peer_addr)) { - uint8_t saddr[256]; - addr_to_string(peer_addr, saddr); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: an attempt to connect from a peer with forbidden address: %s\n", __FUNCTION__,saddr); - close_ioa_socket(s); - FUNCEND; - return; - } + if (!good_peer_addr(server, ss->realm_options.name, peer_addr)) { + uint8_t saddr[256]; + addr_to_string(peer_addr, saddr); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: an attempt to connect from a peer with forbidden address: %s\n", + __FUNCTION__, saddr); + close_ioa_socket(s); + FUNCEND; + return; + } - if(!can_accept_tcp_connection_from_peer(a,peer_addr,server->server_relay)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: peer has no permission to connect\n", __FUNCTION__); - close_ioa_socket(s); - FUNCEND; - return; - } + if (!can_accept_tcp_connection_from_peer(a, peer_addr, server->server_relay)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: peer has no permission to connect\n", __FUNCTION__); + close_ioa_socket(s); + FUNCEND; + return; + } - stun_tid tid; - memset(&tid, 0, sizeof(stun_tid)); - int err_code=0; - tc = create_tcp_connection(server->id, a, &tid, peer_addr, &err_code); - if(!tc) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: cannot create TCP connection\n", __FUNCTION__); - close_ioa_socket(s); - FUNCEND; - return; - } + stun_tid tid; + memset(&tid, 0, sizeof(stun_tid)); + int err_code = 0; + tc = create_tcp_connection(server->id, a, &tid, peer_addr, &err_code); + if (!tc) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: cannot create TCP connection\n", __FUNCTION__); + close_ioa_socket(s); + FUNCEND; + return; + } - tc->state = TC_STATE_PEER_CONNECTED; - tc->peer_s = s; + tc->state = TC_STATE_PEER_CONNECTED; + tc->peer_s = s; - set_ioa_socket_session(s,ss); - set_ioa_socket_sub_session(s,tc); + set_ioa_socket_session(s, ss); + set_ioa_socket_sub_session(s, tc); - if(register_callback_on_ioa_socket(server->e, s, IOA_EV_READ, tcp_peer_input_handler, tc, 1)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: cannot set TCP peer data input callback\n", __FUNCTION__); - IOA_CLOSE_SOCKET(tc->peer_s); - tc->state = TC_STATE_UNKNOWN; - FUNCEND; - return; - } + if (register_callback_on_ioa_socket(server->e, s, IOA_EV_READ, tcp_peer_input_handler, tc, 1) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: cannot set TCP peer data input callback\n", __FUNCTION__); + IOA_CLOSE_SOCKET(tc->peer_s); + tc->state = TC_STATE_UNKNOWN; + FUNCEND; + return; + } - IOA_EVENT_DEL(tc->conn_bind_timeout); - tc->conn_bind_timeout = set_ioa_timer(server->e, TCP_CONN_BIND_TIMEOUT, 0, - tcp_conn_bind_timeout_handler, tc, 0, - "tcp_conn_bind_timeout_handler"); + IOA_EVENT_DEL(tc->conn_bind_timeout); + tc->conn_bind_timeout = set_ioa_timer(server->e, TCP_CONN_BIND_TIMEOUT, 0, tcp_conn_bind_timeout_handler, tc, 0, + "tcp_conn_bind_timeout_handler"); - ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(server->e); - size_t len = ioa_network_buffer_get_size(nbh); + ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(server->e); + size_t len = ioa_network_buffer_get_size(nbh); - stun_init_indication_str(STUN_METHOD_CONNECTION_ATTEMPT, ioa_network_buffer_data(nbh), &len); - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_CONNECTION_ID, - (const uint8_t*)&(tc->id), 4); - stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, peer_addr); + stun_init_indication_str(STUN_METHOD_CONNECTION_ATTEMPT, ioa_network_buffer_data(nbh), &len); + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_CONNECTION_ID, (const uint8_t *)&(tc->id), 4); + stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, peer_addr); - ioa_network_buffer_set_size(nbh,len); + ioa_network_buffer_set_size(nbh, len); - if(!(*server->no_software_attribute)) - { - const uint8_t *field = (const uint8_t *) get_version(server); - size_t fsz = strlen(get_version(server)); - size_t len = ioa_network_buffer_get_size(nbh); - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_SOFTWARE, field, fsz); - ioa_network_buffer_set_size(nbh, len); - } + if (!(*server->no_software_attribute)) { + const uint8_t *field = (const uint8_t *)get_version(server); + size_t fsz = strlen(get_version(server)); + size_t len = ioa_network_buffer_get_size(nbh); + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_SOFTWARE, field, fsz); + ioa_network_buffer_set_size(nbh, len); + } - if ((server->fingerprint) || ss->enforce_fingerprints) { - size_t len = ioa_network_buffer_get_size(nbh); - stun_attr_add_fingerprint_str(ioa_network_buffer_data(nbh), &len); - ioa_network_buffer_set_size(nbh, len); - } + if ((server->fingerprint) || ss->enforce_fingerprints) { + size_t len = ioa_network_buffer_get_size(nbh); + stun_attr_add_fingerprint_str(ioa_network_buffer_data(nbh), &len); + ioa_network_buffer_set_size(nbh, len); + } - write_client_connection(server, ss, nbh, TTL_IGNORE, TOS_IGNORE); + write_client_connection(server, ss, nbh, TTL_IGNORE, TOS_IGNORE); - FUNCEND; - } + FUNCEND; + } } -static int handle_turn_connect(turn_turnserver *server, - ts_ur_super_session *ss, stun_tid *tid, - int *err_code, const uint8_t **reason, uint16_t *unknown_attrs, uint16_t *ua_num, - ioa_net_data *in_buffer) { +static int handle_turn_connect(turn_turnserver *server, ts_ur_super_session *ss, stun_tid *tid, int *err_code, + const uint8_t **reason, uint16_t *unknown_attrs, uint16_t *ua_num, + ioa_net_data *in_buffer) { - FUNCSTART; - ioa_addr peer_addr; - int peer_found = 0; - addr_set_any(&peer_addr); - allocation* a = get_allocation_ss(ss); + FUNCSTART; + ioa_addr peer_addr; + int peer_found = 0; + addr_set_any(&peer_addr); + allocation *a = get_allocation_ss(ss); - if(!(ss->is_tcp_relay)) { - *err_code = 403; - *reason = (const uint8_t *)"Connect cannot be used with UDP relay"; - } else if (!is_allocation_valid(a)) { - *err_code = 437; - } else { + if (!(ss->is_tcp_relay)) { + *err_code = 403; + *reason = (const uint8_t *)"Connect cannot be used with UDP relay"; + } else if (!is_allocation_valid(a)) { + *err_code = 437; + } else { - stun_attr_ref sar = stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh)); - while (sar && (!(*err_code)) && (*ua_num < MAX_NUMBER_OF_UNKNOWN_ATTRS)) { - int attr_type = stun_attr_get_type(sar); - switch (attr_type) { - SKIP_ATTRIBUTES; - case STUN_ATTRIBUTE_XOR_PEER_ADDRESS: - { - if(stun_attr_get_addr_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - sar, &peer_addr, - NULL) == -1) { - *err_code = 400; - *reason = (const uint8_t *)"Bad Peer Address"; - } else { - if(!get_relay_socket(a,peer_addr.ss.sa_family)) { - *err_code = 443; - *reason = (const uint8_t *)"Peer Address Family Mismatch (2)"; - } + stun_attr_ref sar = + stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh)); + while (sar && (!(*err_code)) && (*ua_num < MAX_NUMBER_OF_UNKNOWN_ATTRS)) { + int attr_type = stun_attr_get_type(sar); + switch (attr_type) { + SKIP_ATTRIBUTES; + case STUN_ATTRIBUTE_XOR_PEER_ADDRESS: { + if (stun_attr_get_addr_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), + sar, &peer_addr, NULL) == -1) { + *err_code = 400; + *reason = (const uint8_t *)"Bad Peer Address"; + } else { + if (!get_relay_socket(a, peer_addr.ss.sa_family)) { + *err_code = 443; + *reason = (const uint8_t *)"Peer Address Family Mismatch (2)"; + } - peer_found = 1; - } - break; - } - default: - if(attr_type>=0x0000 && attr_type<=0x7FFF) - unknown_attrs[(*ua_num)++] = nswap16(attr_type); - }; - sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - sar); - } + peer_found = 1; + } + break; + } + default: + if (attr_type >= 0x0000 && attr_type <= 0x7FFF) + unknown_attrs[(*ua_num)++] = nswap16(attr_type); + }; + sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), + sar); + } - if (*ua_num > 0) { + if (*ua_num > 0) { - *err_code = 420; + *err_code = 420; - } else if (*err_code) { + } else if (*err_code) { - ; + ; - } else if (!peer_found) { + } else if (!peer_found) { - *err_code = 400; - *reason = (const uint8_t *)"Where is Peer Address ?"; + *err_code = 400; + *reason = (const uint8_t *)"Where is Peer Address ?"; - } else { - if(!good_peer_addr(server,ss->realm_options.name,&peer_addr)) { - *err_code = 403; - *reason = (const uint8_t *) "Forbidden IP"; - } else { - tcp_start_connection_to_peer(server, ss, tid, a, &peer_addr, err_code, reason); - } - } - } + } else { + if (!good_peer_addr(server, ss->realm_options.name, &peer_addr)) { + *err_code = 403; + *reason = (const uint8_t *)"Forbidden IP"; + } else { + tcp_start_connection_to_peer(server, ss, tid, a, &peer_addr, err_code, reason); + } + } + } - FUNCEND; - return 0; + FUNCEND; + return 0; } -static int handle_turn_connection_bind(turn_turnserver *server, - ts_ur_super_session *ss, stun_tid *tid, int *resp_constructed, - int *err_code, const uint8_t **reason, uint16_t *unknown_attrs, uint16_t *ua_num, - ioa_net_data *in_buffer, ioa_network_buffer_handle nbh, int message_integrity, - int can_resume) { +static int handle_turn_connection_bind(turn_turnserver *server, ts_ur_super_session *ss, stun_tid *tid, + int *resp_constructed, int *err_code, const uint8_t **reason, + uint16_t *unknown_attrs, uint16_t *ua_num, ioa_net_data *in_buffer, + ioa_network_buffer_handle nbh, int message_integrity, int can_resume) { - allocation* a = get_allocation_ss(ss); + allocation *a = get_allocation_ss(ss); - uint16_t method = STUN_METHOD_CONNECTION_BIND; + uint16_t method = STUN_METHOD_CONNECTION_BIND; - if(ss->to_be_closed) { + if (ss->to_be_closed) { - *err_code = 400; + *err_code = 400; - } else if (is_allocation_valid(a)) { + } else if (is_allocation_valid(a)) { - *err_code = 400; - *reason = (const uint8_t *)"Bad request: CONNECTION_BIND cannot be issued after allocation"; + *err_code = 400; + *reason = (const uint8_t *)"Bad request: CONNECTION_BIND cannot be issued after allocation"; - } else if(!is_stream_socket(get_ioa_socket_type(ss->client_socket))) { + } else if (!is_stream_socket(get_ioa_socket_type(ss->client_socket))) { - *err_code = 400; - *reason = (const uint8_t *)"Bad request: CONNECTION_BIND only possible with TCP/TLS"; + *err_code = 400; + *reason = (const uint8_t *)"Bad request: CONNECTION_BIND only possible with TCP/TLS"; - } else { - tcp_connection_id id = 0; + } else { + tcp_connection_id id = 0; - stun_attr_ref sar = stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh)); - while (sar && (!(*err_code)) && (*ua_num < MAX_NUMBER_OF_UNKNOWN_ATTRS)) { - int attr_type = stun_attr_get_type(sar); - switch (attr_type) { - SKIP_ATTRIBUTES; - case STUN_ATTRIBUTE_CONNECTION_ID: { - if (stun_attr_get_len(sar) != 4) { - *err_code = 400; - *reason = (const uint8_t *)"Wrong Connection ID field format"; - } else { - const uint8_t* value = stun_attr_get_value(sar); - if (!value) { - *err_code = 400; - *reason = (const uint8_t *)"Wrong Connection ID field data"; - } else { - id = *((const uint32_t*)value); //AS-IS encoding, no conversion to/from network byte order - } - } - } - break; - default: - if(attr_type>=0x0000 && attr_type<=0x7FFF) - unknown_attrs[(*ua_num)++] = nswap16(attr_type); - }; - sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), sar); - } + stun_attr_ref sar = + stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh)); + while (sar && (!(*err_code)) && (*ua_num < MAX_NUMBER_OF_UNKNOWN_ATTRS)) { + int attr_type = stun_attr_get_type(sar); + switch (attr_type) { + SKIP_ATTRIBUTES; + case STUN_ATTRIBUTE_CONNECTION_ID: { + if (stun_attr_get_len(sar) != 4) { + *err_code = 400; + *reason = (const uint8_t *)"Wrong Connection ID field format"; + } else { + const uint8_t *value = stun_attr_get_value(sar); + if (!value) { + *err_code = 400; + *reason = (const uint8_t *)"Wrong Connection ID field data"; + } else { + id = *((const uint32_t *)value); // AS-IS encoding, no conversion to/from network byte order + } + } + } break; + default: + if (attr_type >= 0x0000 && attr_type <= 0x7FFF) + unknown_attrs[(*ua_num)++] = nswap16(attr_type); + }; + sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), + sar); + } - if (*ua_num > 0) { + if (*ua_num > 0) { - *err_code = 420; + *err_code = 420; - } else if (*err_code) { + } else if (*err_code) { - ; + ; - } else { - if(server->send_socket_to_relay) { - turnserver_id sid = (id & 0xFF000000)>>24; - ioa_socket_handle s = ss->client_socket; - if(s && !ioa_socket_tobeclosed(s)) { - ioa_socket_handle new_s = detach_ioa_socket(s); - if(new_s) { - if(server->send_socket_to_relay(sid, id, tid, new_s, message_integrity, RMT_CB_SOCKET, in_buffer, can_resume)<0) { - *err_code = 400; - *reason = (const uint8_t *)"Wrong connection id"; - } - } else { - *err_code = 500; - } - } else { - *err_code = 500; - } - } else { - *err_code = 500; - } - ss->to_be_closed = 1; - } - } + } else { + if (server->send_socket_to_relay) { + turnserver_id sid = (id & 0xFF000000) >> 24; + ioa_socket_handle s = ss->client_socket; + if (s && !ioa_socket_tobeclosed(s)) { + ioa_socket_handle new_s = detach_ioa_socket(s); + if (new_s) { + if (server->send_socket_to_relay(sid, id, tid, new_s, message_integrity, RMT_CB_SOCKET, in_buffer, + can_resume) < 0) { + *err_code = 400; + *reason = (const uint8_t *)"Wrong connection id"; + } + } else { + *err_code = 500; + } + } else { + *err_code = 500; + } + } else { + *err_code = 500; + } + ss->to_be_closed = 1; + } + } - if (!(*resp_constructed) && ss->client_socket && !ioa_socket_tobeclosed(ss->client_socket)) { + if (!(*resp_constructed) && ss->client_socket && !ioa_socket_tobeclosed(ss->client_socket)) { - if (!(*err_code)) { - *err_code = 437; - } + if (!(*err_code)) { + *err_code = 437; + } - size_t len = ioa_network_buffer_get_size(nbh); - stun_init_error_response_str(method, ioa_network_buffer_data(nbh), &len, *err_code, *reason, tid); - ioa_network_buffer_set_size(nbh,len); + size_t len = ioa_network_buffer_get_size(nbh); + stun_init_error_response_str(method, ioa_network_buffer_data(nbh), &len, *err_code, *reason, tid); + ioa_network_buffer_set_size(nbh, len); - *resp_constructed = 1; - } + *resp_constructed = 1; + } - return 0; + return 0; } -int turnserver_accept_tcp_client_data_connection(turn_turnserver *server, tcp_connection_id tcid, stun_tid *tid, ioa_socket_handle s, int message_integrity, ioa_net_data *in_buffer, int can_resume) -{ - if(!server) - return -1; +int turnserver_accept_tcp_client_data_connection(turn_turnserver *server, tcp_connection_id tcid, stun_tid *tid, + ioa_socket_handle s, int message_integrity, ioa_net_data *in_buffer, + int can_resume) { + if (!server) + return -1; - FUNCSTART; + FUNCSTART; - tcp_connection *tc = NULL; - ts_ur_super_session *ss = NULL; + tcp_connection *tc = NULL; + ts_ur_super_session *ss = NULL; - int err_code = 0; - const uint8_t *reason = NULL; + int err_code = 0; + const uint8_t *reason = NULL; - ioa_socket_handle s_to_delete = s; + ioa_socket_handle s_to_delete = s; - if(tcid && tid && s) { + if (tcid && tid && s) { - tc = get_tcp_connection_by_id(server->tcp_relay_connections, tcid); - ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(server->e); - int resp_constructed = 0; - if(!tc || (tc->state == TC_STATE_READY) || (tc->client_s)) { - err_code = 400; - } else { - allocation *a = (allocation*)(tc->owner); - if(!a || !(a->owner)) { - err_code = 500; - } else { - ss = (ts_ur_super_session*)(a->owner); + tc = get_tcp_connection_by_id(server->tcp_relay_connections, tcid); + ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(server->e); + int resp_constructed = 0; + if (!tc || (tc->state == TC_STATE_READY) || (tc->client_s)) { + err_code = 400; + } else { + allocation *a = (allocation *)(tc->owner); + if (!a || !(a->owner)) { + err_code = 500; + } else { + ss = (ts_ur_super_session *)(a->owner); - if(ss->to_be_closed || ioa_socket_tobeclosed(ss->client_socket)) { - err_code = 404; - } else { - //Check security: - int postpone_reply = 0; - check_stun_auth(server, ss, tid, &resp_constructed, &err_code, &reason, in_buffer, nbh, - STUN_METHOD_CONNECTION_BIND, &message_integrity, &postpone_reply, can_resume); + if (ss->to_be_closed || ioa_socket_tobeclosed(ss->client_socket)) { + err_code = 404; + } else { + // Check security: + int postpone_reply = 0; + check_stun_auth(server, ss, tid, &resp_constructed, &err_code, &reason, in_buffer, nbh, + STUN_METHOD_CONNECTION_BIND, &message_integrity, &postpone_reply, can_resume); - if(postpone_reply) { + if (postpone_reply) { - ioa_network_buffer_delete(server->e, nbh); - return 0; + ioa_network_buffer_delete(server->e, nbh); + return 0; - } else if(!err_code) { - tc->state = TC_STATE_READY; - tc->client_s = s; - s_to_delete = NULL; - set_ioa_socket_session(s,ss); - set_ioa_socket_sub_session(s,tc); - set_ioa_socket_app_type(s,TCP_CLIENT_DATA_SOCKET); - if(register_callback_on_ioa_socket(server->e, s, IOA_EV_READ, tcp_client_input_handler_rfc6062data, tc, 1)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: cannot set TCP client data input callback\n", __FUNCTION__); - err_code = 500; - } else { - IOA_EVENT_DEL(tc->conn_bind_timeout); - } - } - } - } - } + } else if (!err_code) { + tc->state = TC_STATE_READY; + tc->client_s = s; + s_to_delete = NULL; + set_ioa_socket_session(s, ss); + set_ioa_socket_sub_session(s, tc); + set_ioa_socket_app_type(s, TCP_CLIENT_DATA_SOCKET); + if (register_callback_on_ioa_socket(server->e, s, IOA_EV_READ, tcp_client_input_handler_rfc6062data, tc, + 1) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: cannot set TCP client data input callback\n", __FUNCTION__); + err_code = 500; + } else { + IOA_EVENT_DEL(tc->conn_bind_timeout); + } + } + } + } + } - if(tc) - get_and_clean_tcp_connection_by_id(server->tcp_relay_connections, tcid); + if (tc) + get_and_clean_tcp_connection_by_id(server->tcp_relay_connections, tcid); - if(!resp_constructed) { - if(!err_code) { - size_t len = ioa_network_buffer_get_size(nbh); - stun_init_success_response_str(STUN_METHOD_CONNECTION_BIND, ioa_network_buffer_data(nbh), &len, tid); - ioa_network_buffer_set_size(nbh,len); - } else { - size_t len = ioa_network_buffer_get_size(nbh); - stun_init_error_response_str(STUN_METHOD_CONNECTION_BIND, ioa_network_buffer_data(nbh), &len, err_code, NULL, tid); - ioa_network_buffer_set_size(nbh,len); - } - } + if (!resp_constructed) { + if (!err_code) { + size_t len = ioa_network_buffer_get_size(nbh); + stun_init_success_response_str(STUN_METHOD_CONNECTION_BIND, ioa_network_buffer_data(nbh), &len, tid); + ioa_network_buffer_set_size(nbh, len); + } else { + size_t len = ioa_network_buffer_get_size(nbh); + stun_init_error_response_str(STUN_METHOD_CONNECTION_BIND, ioa_network_buffer_data(nbh), &len, err_code, NULL, + tid); + ioa_network_buffer_set_size(nbh, len); + } + } - if(!(*server->no_software_attribute)) - { - size_t fsz = strlen(get_version(server)); - const uint8_t *field = (const uint8_t *) get_version(server); - size_t len = ioa_network_buffer_get_size(nbh); - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_SOFTWARE, field, fsz); - ioa_network_buffer_set_size(nbh, len); - } + if (!(*server->no_software_attribute)) { + size_t fsz = strlen(get_version(server)); + const uint8_t *field = (const uint8_t *)get_version(server); + size_t len = ioa_network_buffer_get_size(nbh); + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_SOFTWARE, field, fsz); + ioa_network_buffer_set_size(nbh, len); + } - if(message_integrity && ss) { - size_t len = ioa_network_buffer_get_size(nbh); - stun_attr_add_integrity_str(server->ct,ioa_network_buffer_data(nbh),&len,ss->hmackey,ss->pwd,SHATYPE_DEFAULT); - ioa_network_buffer_set_size(nbh,len); - } + if (message_integrity && ss) { + size_t len = ioa_network_buffer_get_size(nbh); + stun_attr_add_integrity_str(server->ct, ioa_network_buffer_data(nbh), &len, ss->hmackey, ss->pwd, + SHATYPE_DEFAULT); + ioa_network_buffer_set_size(nbh, len); + } - if ((server->fingerprint) || (ss &&(ss->enforce_fingerprints))) { - size_t len = ioa_network_buffer_get_size(nbh); - stun_attr_add_fingerprint_str(ioa_network_buffer_data(nbh), &len); - ioa_network_buffer_set_size(nbh, len); - } + if ((server->fingerprint) || (ss && (ss->enforce_fingerprints))) { + size_t len = ioa_network_buffer_get_size(nbh); + stun_attr_add_fingerprint_str(ioa_network_buffer_data(nbh), &len); + ioa_network_buffer_set_size(nbh, len); + } - if(server->verbose) { - log_method(ss, "CONNECTION_BIND", err_code, reason); - } + if (server->verbose) { + log_method(ss, "CONNECTION_BIND", err_code, reason); + } - if(ss && !err_code) { - send_data_from_ioa_socket_nbh(s, NULL, nbh, TTL_IGNORE, TOS_IGNORE, NULL); - tcp_deliver_delayed_buffer(&(tc->ub_to_client),s,ss); - IOA_CLOSE_SOCKET(s_to_delete); - FUNCEND; - return 0; - } else { - /* Just to set the necessary structures for the packet sending: */ - if(register_callback_on_ioa_socket(server->e, s, IOA_EV_READ, NULL, NULL, 1)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: cannot set TCP tmp client data input callback\n", __FUNCTION__); - ioa_network_buffer_delete(server->e, nbh); - } else { - send_data_from_ioa_socket_nbh(s, NULL, nbh, TTL_IGNORE, TOS_IGNORE, NULL); - } - } - } + if (ss && !err_code) { + send_data_from_ioa_socket_nbh(s, NULL, nbh, TTL_IGNORE, TOS_IGNORE, NULL); + tcp_deliver_delayed_buffer(&(tc->ub_to_client), s, ss); + IOA_CLOSE_SOCKET(s_to_delete); + FUNCEND; + return 0; + } else { + /* Just to set the necessary structures for the packet sending: */ + if (register_callback_on_ioa_socket(server->e, s, IOA_EV_READ, NULL, NULL, 1) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: cannot set TCP tmp client data input callback\n", __FUNCTION__); + ioa_network_buffer_delete(server->e, nbh); + } else { + send_data_from_ioa_socket_nbh(s, NULL, nbh, TTL_IGNORE, TOS_IGNORE, NULL); + } + } + } - IOA_CLOSE_SOCKET(s_to_delete); + IOA_CLOSE_SOCKET(s_to_delete); - FUNCEND; - return -1; + FUNCEND; + return -1; } /* <<== RFC 6062 */ -static int handle_turn_channel_bind(turn_turnserver *server, - ts_ur_super_session *ss, stun_tid *tid, int *resp_constructed, - int *err_code, const uint8_t **reason, uint16_t *unknown_attrs, uint16_t *ua_num, - ioa_net_data *in_buffer, ioa_network_buffer_handle nbh) { +static int handle_turn_channel_bind(turn_turnserver *server, ts_ur_super_session *ss, stun_tid *tid, + int *resp_constructed, int *err_code, const uint8_t **reason, + uint16_t *unknown_attrs, uint16_t *ua_num, ioa_net_data *in_buffer, + ioa_network_buffer_handle nbh) { - FUNCSTART; - uint16_t chnum = 0; - ioa_addr peer_addr; - addr_set_any(&peer_addr); - allocation* a = get_allocation_ss(ss); - int addr_found = 0; + FUNCSTART; + uint16_t chnum = 0; + ioa_addr peer_addr; + addr_set_any(&peer_addr); + allocation *a = get_allocation_ss(ss); + int addr_found = 0; - if(ss->is_tcp_relay) { - *err_code = 403; - *reason = (const uint8_t *)"Channel bind cannot be used with TCP relay"; - } else if (is_allocation_valid(a)) { + if (ss->is_tcp_relay) { + *err_code = 403; + *reason = (const uint8_t *)"Channel bind cannot be used with TCP relay"; + } else if (is_allocation_valid(a)) { - stun_attr_ref sar = stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh)); - while (sar && (!(*err_code)) && (*ua_num < MAX_NUMBER_OF_UNKNOWN_ATTRS)) { - int attr_type = stun_attr_get_type(sar); - switch (attr_type) { - SKIP_ATTRIBUTES; - case STUN_ATTRIBUTE_CHANNEL_NUMBER: { - if (chnum) { - chnum = 0; - *err_code = 400; - *reason = (const uint8_t *)"Channel number cannot be duplicated in this request"; - break; - } - chnum = stun_attr_get_channel_number(sar); - if (!chnum) { - *err_code = 400; - *reason = (const uint8_t *)"Channel number cannot be zero in this request"; - break; - } - } - break; - case STUN_ATTRIBUTE_XOR_PEER_ADDRESS: - { - stun_attr_get_addr_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - sar, &peer_addr, - NULL); + stun_attr_ref sar = + stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh)); + while (sar && (!(*err_code)) && (*ua_num < MAX_NUMBER_OF_UNKNOWN_ATTRS)) { + int attr_type = stun_attr_get_type(sar); + switch (attr_type) { + SKIP_ATTRIBUTES; + case STUN_ATTRIBUTE_CHANNEL_NUMBER: { + if (chnum) { + chnum = 0; + *err_code = 400; + *reason = (const uint8_t *)"Channel number cannot be duplicated in this request"; + break; + } + chnum = stun_attr_get_channel_number(sar); + if (!chnum) { + *err_code = 400; + *reason = (const uint8_t *)"Channel number cannot be zero in this request"; + break; + } + } break; + case STUN_ATTRIBUTE_XOR_PEER_ADDRESS: { + stun_attr_get_addr_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), + sar, &peer_addr, NULL); - if(!get_relay_socket(a,peer_addr.ss.sa_family)) { - *err_code = 443; - *reason = (const uint8_t *)"Peer Address Family Mismatch (3)"; - } + if (!get_relay_socket(a, peer_addr.ss.sa_family)) { + *err_code = 443; + *reason = (const uint8_t *)"Peer Address Family Mismatch (3)"; + } - if(addr_get_port(&peer_addr) < 1) { - *err_code = 400; - *reason = (const uint8_t *)"Empty port number in channel bind request"; - } else { - addr_found = 1; - } + if (addr_get_port(&peer_addr) < 1) { + *err_code = 400; + *reason = (const uint8_t *)"Empty port number in channel bind request"; + } else { + addr_found = 1; + } - break; - } - default: - if(attr_type>=0x0000 && attr_type<=0x7FFF) - unknown_attrs[(*ua_num)++] = nswap16(attr_type); - }; - sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - sar); - } + break; + } + default: + if (attr_type >= 0x0000 && attr_type <= 0x7FFF) + unknown_attrs[(*ua_num)++] = nswap16(attr_type); + }; + sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), + sar); + } - if (*ua_num > 0) { + if (*ua_num > 0) { - *err_code = 420; + *err_code = 420; - } else if (*err_code) { + } else if (*err_code) { - ; + ; - } else if (!chnum || addr_any(&peer_addr) || !addr_found) { + } else if (!chnum || addr_any(&peer_addr) || !addr_found) { - *err_code = 400; - *reason = (const uint8_t *)"Bad channel bind request"; + *err_code = 400; + *reason = (const uint8_t *)"Bad channel bind request"; - } else if(!STUN_VALID_CHANNEL(chnum)) { + } else if (!STUN_VALID_CHANNEL(chnum)) { - *err_code = 400; - *reason = (const uint8_t *)"Bad channel number"; + *err_code = 400; + *reason = (const uint8_t *)"Bad channel number"; - } else { + } else { - ch_info* chn = allocation_get_ch_info(a, chnum); - turn_permission_info* tinfo = NULL; + ch_info *chn = allocation_get_ch_info(a, chnum); + turn_permission_info *tinfo = NULL; - if (chn) { - if (!addr_eq(&peer_addr, &(chn->peer_addr))) { - *err_code = 400; - *reason = (const uint8_t *)"You cannot use the same channel number with different peer"; - } else { - tinfo = (turn_permission_info*) (chn->owner); - if (!tinfo) { - *err_code = 500; - *reason = (const uint8_t *)"Wrong permission info"; - } else { - if (!addr_eq_no_port(&peer_addr, &(tinfo->addr))) { - *err_code = 500; - *reason = (const uint8_t *)"Wrong permission info and peer addr combination"; - } else if (chn->port != addr_get_port(&peer_addr)) { - *err_code = 500; - *reason = (const uint8_t *)"Wrong port number"; - } - } - } + if (chn) { + if (!addr_eq(&peer_addr, &(chn->peer_addr))) { + *err_code = 400; + *reason = (const uint8_t *)"You cannot use the same channel number with different peer"; + } else { + tinfo = (turn_permission_info *)(chn->owner); + if (!tinfo) { + *err_code = 500; + *reason = (const uint8_t *)"Wrong permission info"; + } else { + if (!addr_eq_no_port(&peer_addr, &(tinfo->addr))) { + *err_code = 500; + *reason = (const uint8_t *)"Wrong permission info and peer addr combination"; + } else if (chn->port != addr_get_port(&peer_addr)) { + *err_code = 500; + *reason = (const uint8_t *)"Wrong port number"; + } + } + } - } else { + } else { - chn = allocation_get_ch_info_by_peer_addr(a, &peer_addr); - if(chn) { - *err_code = 400; - *reason = (const uint8_t *)"You cannot use the same peer with different channel number"; - } else { - if(!good_peer_addr(server,ss->realm_options.name,&peer_addr)) { - *err_code = 403; - *reason = (const uint8_t *) "Forbidden IP"; - } else { - chn = allocation_get_new_ch_info(a, chnum, &peer_addr); - if (!chn) { - *err_code = 500; - *reason = (const uint8_t *) "Cannot find channel data"; - } else { - tinfo = (turn_permission_info*) (chn->owner); - if (!tinfo) { - *err_code = 500; - *reason - = (const uint8_t *) "Wrong turn permission info"; - } - } - } - } - } + chn = allocation_get_ch_info_by_peer_addr(a, &peer_addr); + if (chn) { + *err_code = 400; + *reason = (const uint8_t *)"You cannot use the same peer with different channel number"; + } else { + if (!good_peer_addr(server, ss->realm_options.name, &peer_addr)) { + *err_code = 403; + *reason = (const uint8_t *)"Forbidden IP"; + } else { + chn = allocation_get_new_ch_info(a, chnum, &peer_addr); + if (!chn) { + *err_code = 500; + *reason = (const uint8_t *)"Cannot find channel data"; + } else { + tinfo = (turn_permission_info *)(chn->owner); + if (!tinfo) { + *err_code = 500; + *reason = (const uint8_t *)"Wrong turn permission info"; + } + } + } + } + } - if (!(*err_code) && chn && tinfo) { + if (!(*err_code) && chn && tinfo) { - if (update_channel_lifetime(ss,chn) < 0) { - *err_code = 500; - *reason = (const uint8_t *)"Cannot update channel lifetime (internal error)"; - } else { - size_t len = ioa_network_buffer_get_size(nbh); - stun_set_channel_bind_response_str(ioa_network_buffer_data(nbh), &len, tid, 0, NULL); - ioa_network_buffer_set_size(nbh,len); - *resp_constructed = 1; + if (update_channel_lifetime(ss, chn) < 0) { + *err_code = 500; + *reason = (const uint8_t *)"Cannot update channel lifetime (internal error)"; + } else { + size_t len = ioa_network_buffer_get_size(nbh); + stun_set_channel_bind_response_str(ioa_network_buffer_data(nbh), &len, tid, 0, NULL); + ioa_network_buffer_set_size(nbh, len); + *resp_constructed = 1; - if(!(ss->is_mobile)) { - if(get_ioa_socket_type(ss->client_socket) == UDP_SOCKET || - get_ioa_socket_type(ss->client_socket) == TCP_SOCKET || - get_ioa_socket_type(ss->client_socket) == SCTP_SOCKET) { - if(get_ioa_socket_type(get_relay_socket(&(ss->alloc),peer_addr.ss.sa_family)) == UDP_SOCKET) { - chn->kernel_channel = CREATE_TURN_CHANNEL_KERNEL(chn->chnum, - get_ioa_socket_address_family(ss->client_socket), - peer_addr.ss.sa_family, - (get_ioa_socket_type(ss->client_socket)==UDP_SOCKET ? IPPROTO_UDP : IPPROTO_TCP), - &(get_remote_addr_from_ioa_socket(ss->client_socket)->ss), - &(get_local_addr_from_ioa_socket(ss->client_socket)->ss), - &(get_local_addr_from_ioa_socket(get_relay_socket(&(ss->alloc),peer_addr.ss.sa_family))), - &(get_remote_addr_from_ioa_socket(get_relay_socket(&(ss->alloc),peer_addr.ss.sa_family))) - ); - } - } - } - } - } - } - } + if (!(ss->is_mobile)) { + if (get_ioa_socket_type(ss->client_socket) == UDP_SOCKET || + get_ioa_socket_type(ss->client_socket) == TCP_SOCKET || + get_ioa_socket_type(ss->client_socket) == SCTP_SOCKET) { + if (get_ioa_socket_type(get_relay_socket(&(ss->alloc), peer_addr.ss.sa_family)) == UDP_SOCKET) { + chn->kernel_channel = CREATE_TURN_CHANNEL_KERNEL( + chn->chnum, get_ioa_socket_address_family(ss->client_socket), peer_addr.ss.sa_family, + (get_ioa_socket_type(ss->client_socket) == UDP_SOCKET ? IPPROTO_UDP : IPPROTO_TCP), + &(get_remote_addr_from_ioa_socket(ss->client_socket)->ss), + &(get_local_addr_from_ioa_socket(ss->client_socket)->ss), + &(get_local_addr_from_ioa_socket(get_relay_socket(&(ss->alloc), peer_addr.ss.sa_family))), + &(get_remote_addr_from_ioa_socket(get_relay_socket(&(ss->alloc), peer_addr.ss.sa_family)))); + } + } + } + } + } + } + } - FUNCEND; - return 0; + FUNCEND; + return 0; } -static int handle_turn_binding(turn_turnserver *server, - ts_ur_super_session *ss, stun_tid *tid, int *resp_constructed, - int *err_code, const uint8_t **reason, uint16_t *unknown_attrs, uint16_t *ua_num, - ioa_net_data *in_buffer, ioa_network_buffer_handle nbh, - int *origin_changed, ioa_addr *response_origin, - int *dest_changed, ioa_addr *response_destination, - uint32_t cookie, int old_stun) { +static int handle_turn_binding(turn_turnserver *server, ts_ur_super_session *ss, stun_tid *tid, int *resp_constructed, + int *err_code, const uint8_t **reason, uint16_t *unknown_attrs, uint16_t *ua_num, + ioa_net_data *in_buffer, ioa_network_buffer_handle nbh, int *origin_changed, + ioa_addr *response_origin, int *dest_changed, ioa_addr *response_destination, + uint32_t cookie, int old_stun) { - FUNCSTART; - int change_ip = 0; - int change_port = 0; - int padding = 0; - int response_port_present = 0; - uint16_t response_port = 0; - SOCKET_TYPE st = get_ioa_socket_type(ss->client_socket); - int use_reflected_from = 0; + FUNCSTART; + int change_ip = 0; + int change_port = 0; + int padding = 0; + int response_port_present = 0; + uint16_t response_port = 0; + SOCKET_TYPE st = get_ioa_socket_type(ss->client_socket); + int use_reflected_from = 0; - if(!(ss->client_socket)) - return -1; + if (!(ss->client_socket)) + return -1; - *origin_changed = 0; - *dest_changed = 0; + *origin_changed = 0; + *dest_changed = 0; - stun_attr_ref sar = stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh)); - while (sar && (!(*err_code)) && (*ua_num < MAX_NUMBER_OF_UNKNOWN_ATTRS)) { - int attr_type = stun_attr_get_type(sar); - switch (attr_type) { - case OLD_STUN_ATTRIBUTE_PASSWORD: - SKIP_ATTRIBUTES; - case STUN_ATTRIBUTE_CHANGE_REQUEST: -/* - * This fix allows the client program from the Stuntman source to make STUN binding requests - * to this server. - * - * It was provided by John Selbie, from STUNTMAN project: - * - * "Here's the gist of the change. Stuntman comes with a STUN client library - * and client program. The client program displays the mapped IP address and - * port if it gets back a successful binding response. - * It also interops with JSTUN, a Java implementation of STUN. - * However, the JSTUN server refuses to respond to any binding request that - * doesn't have a CHANGE-REQUEST attribute in it. - * ... workaround is for the client to make a request with an empty CHANGE-REQUEST - * attribute (neither the ip or port bit are set)." - * - */ - stun_attr_get_change_request_str(sar, &change_ip, &change_port); - if( (!is_rfc5780(server)) && (change_ip || change_port)) { - *err_code = 420; - *reason = (const uint8_t *)"Unknown attribute: TURN server was configured without RFC 5780 support"; - break; - } - if(change_ip || change_port) { - if(st != UDP_SOCKET) { - *err_code = 400; - *reason = (const uint8_t *)"Wrong request: applicable only to UDP protocol"; - } - } - break; - case STUN_ATTRIBUTE_PADDING: - if(response_port_present) { - *err_code = 400; - *reason = (const uint8_t *)"Wrong request format: you cannot use PADDING and RESPONSE_PORT together"; - } else if((st != UDP_SOCKET) && (st != DTLS_SOCKET)) { - *err_code = 400; - *reason = (const uint8_t *)"Wrong request: padding applicable only to UDP and DTLS protocols"; - } else { - padding = 1; - } - break; - case STUN_ATTRIBUTE_RESPONSE_PORT: - if(padding) { - *err_code = 400; - *reason = (const uint8_t *)"Wrong request format: you cannot use PADDING and RESPONSE_PORT together"; - } else if(st != UDP_SOCKET) { - *err_code = 400; - *reason = (const uint8_t *)"Wrong request: applicable only to UDP protocol"; - } else { - int rp = stun_attr_get_response_port_str(sar); - if(rp>=0) { - response_port_present = 1; - response_port = (uint16_t)rp; - } else { - *err_code = 400; - *reason = (const uint8_t *)"Wrong response port format"; - } - } - break; - case OLD_STUN_ATTRIBUTE_RESPONSE_ADDRESS: - if(old_stun) { - use_reflected_from = 1; - stun_attr_get_addr_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - sar, response_destination, response_destination); - } - break; - default: - if(attr_type>=0x0000 && attr_type<=0x7FFF) - unknown_attrs[(*ua_num)++] = nswap16(attr_type); - }; - sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - sar); - } + stun_attr_ref sar = + stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh)); + while (sar && (!(*err_code)) && (*ua_num < MAX_NUMBER_OF_UNKNOWN_ATTRS)) { + int attr_type = stun_attr_get_type(sar); + switch (attr_type) { + case OLD_STUN_ATTRIBUTE_PASSWORD: + SKIP_ATTRIBUTES; + case STUN_ATTRIBUTE_CHANGE_REQUEST: + /* + * This fix allows the client program from the Stuntman source to make STUN binding requests + * to this server. + * + * It was provided by John Selbie, from STUNTMAN project: + * + * "Here's the gist of the change. Stuntman comes with a STUN client library + * and client program. The client program displays the mapped IP address and + * port if it gets back a successful binding response. + * It also interops with JSTUN, a Java implementation of STUN. + * However, the JSTUN server refuses to respond to any binding request that + * doesn't have a CHANGE-REQUEST attribute in it. + * ... workaround is for the client to make a request with an empty CHANGE-REQUEST + * attribute (neither the ip or port bit are set)." + * + */ + stun_attr_get_change_request_str(sar, &change_ip, &change_port); + if ((!is_rfc5780(server)) && (change_ip || change_port)) { + *err_code = 420; + *reason = (const uint8_t *)"Unknown attribute: TURN server was configured without RFC 5780 support"; + break; + } + if (change_ip || change_port) { + if (st != UDP_SOCKET) { + *err_code = 400; + *reason = (const uint8_t *)"Wrong request: applicable only to UDP protocol"; + } + } + break; + case STUN_ATTRIBUTE_PADDING: + if (response_port_present) { + *err_code = 400; + *reason = (const uint8_t *)"Wrong request format: you cannot use PADDING and RESPONSE_PORT together"; + } else if ((st != UDP_SOCKET) && (st != DTLS_SOCKET)) { + *err_code = 400; + *reason = (const uint8_t *)"Wrong request: padding applicable only to UDP and DTLS protocols"; + } else { + padding = 1; + } + break; + case STUN_ATTRIBUTE_RESPONSE_PORT: + if (padding) { + *err_code = 400; + *reason = (const uint8_t *)"Wrong request format: you cannot use PADDING and RESPONSE_PORT together"; + } else if (st != UDP_SOCKET) { + *err_code = 400; + *reason = (const uint8_t *)"Wrong request: applicable only to UDP protocol"; + } else { + int rp = stun_attr_get_response_port_str(sar); + if (rp >= 0) { + response_port_present = 1; + response_port = (uint16_t)rp; + } else { + *err_code = 400; + *reason = (const uint8_t *)"Wrong response port format"; + } + } + break; + case OLD_STUN_ATTRIBUTE_RESPONSE_ADDRESS: + if (old_stun) { + use_reflected_from = 1; + stun_attr_get_addr_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), + sar, response_destination, response_destination); + } + break; + default: + if (attr_type >= 0x0000 && attr_type <= 0x7FFF) + unknown_attrs[(*ua_num)++] = nswap16(attr_type); + }; + sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), + sar); + } - if (*ua_num > 0) { + if (*ua_num > 0) { - *err_code = 420; + *err_code = 420; - } else if (*err_code) { + } else if (*err_code) { - ; + ; - } else if(ss->client_socket && get_remote_addr_from_ioa_socket(ss->client_socket)) { + } else if (ss->client_socket && get_remote_addr_from_ioa_socket(ss->client_socket)) { - size_t len = ioa_network_buffer_get_size(nbh); - if (stun_set_binding_response_str(ioa_network_buffer_data(nbh), &len, tid, - get_remote_addr_from_ioa_socket(ss->client_socket), 0, NULL, cookie, old_stun, *server->no_stun_backward_compatibility) >= 0) { + size_t len = ioa_network_buffer_get_size(nbh); + if (stun_set_binding_response_str(ioa_network_buffer_data(nbh), &len, tid, + get_remote_addr_from_ioa_socket(ss->client_socket), 0, NULL, cookie, old_stun, + *server->no_stun_backward_compatibility) >= 0) { - addr_cpy(response_origin, get_local_addr_from_ioa_socket(ss->client_socket)); + addr_cpy(response_origin, get_local_addr_from_ioa_socket(ss->client_socket)); - *resp_constructed = 1; + *resp_constructed = 1; - if(old_stun && use_reflected_from) { - stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, - OLD_STUN_ATTRIBUTE_REFLECTED_FROM, - get_remote_addr_from_ioa_socket(ss->client_socket)); - } + if (old_stun && use_reflected_from) { + stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, OLD_STUN_ATTRIBUTE_REFLECTED_FROM, + get_remote_addr_from_ioa_socket(ss->client_socket)); + } - if(!is_rfc5780(server)) { + if (!is_rfc5780(server)) { - if(!(*server->response_origin_only_with_rfc5780)) { - if(old_stun) { - stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, - OLD_STUN_ATTRIBUTE_SOURCE_ADDRESS, response_origin); - stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, - OLD_STUN_ATTRIBUTE_CHANGED_ADDRESS, response_origin); - } else { - stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, - STUN_ATTRIBUTE_RESPONSE_ORIGIN, response_origin); - } - } + if (!(*server->response_origin_only_with_rfc5780)) { + if (old_stun) { + stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, OLD_STUN_ATTRIBUTE_SOURCE_ADDRESS, + response_origin); + stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, OLD_STUN_ATTRIBUTE_CHANGED_ADDRESS, + response_origin); + } else { + stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_RESPONSE_ORIGIN, response_origin); + } + } - } else if(ss->client_socket) { + } else if (ss->client_socket) { - ioa_addr other_address; + ioa_addr other_address; - if(get_other_address(server,ss,&other_address) == 0) { + if (get_other_address(server, ss, &other_address) == 0) { - addr_cpy(response_destination, get_remote_addr_from_ioa_socket(ss->client_socket)); + addr_cpy(response_destination, get_remote_addr_from_ioa_socket(ss->client_socket)); - if(change_ip) { - *origin_changed = 1; - if(change_port) { - addr_cpy(response_origin,&other_address); - } else { - int old_port = addr_get_port(response_origin); - addr_cpy(response_origin,&other_address); - addr_set_port(response_origin,old_port); - } - } else if(change_port) { - *origin_changed = 1; - addr_set_port(response_origin,addr_get_port(&other_address)); - } + if (change_ip) { + *origin_changed = 1; + if (change_port) { + addr_cpy(response_origin, &other_address); + } else { + int old_port = addr_get_port(response_origin); + addr_cpy(response_origin, &other_address); + addr_set_port(response_origin, old_port); + } + } else if (change_port) { + *origin_changed = 1; + addr_set_port(response_origin, addr_get_port(&other_address)); + } - if(old_stun) { - stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, - OLD_STUN_ATTRIBUTE_SOURCE_ADDRESS, response_origin); - stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, - OLD_STUN_ATTRIBUTE_CHANGED_ADDRESS, &other_address); - } else { - stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, - STUN_ATTRIBUTE_RESPONSE_ORIGIN, response_origin); - stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, - STUN_ATTRIBUTE_OTHER_ADDRESS, &other_address); - } + if (old_stun) { + stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, OLD_STUN_ATTRIBUTE_SOURCE_ADDRESS, + response_origin); + stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, OLD_STUN_ATTRIBUTE_CHANGED_ADDRESS, + &other_address); + } else { + stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_RESPONSE_ORIGIN, response_origin); + stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_OTHER_ADDRESS, &other_address); + } - if(response_port_present) { - *dest_changed = 1; - addr_set_port(response_destination, (int)response_port); - } + if (response_port_present) { + *dest_changed = 1; + addr_set_port(response_destination, (int)response_port); + } - if(padding) { - int mtu = get_local_mtu_ioa_socket(ss->client_socket); - if(mtu<68) - mtu=1500; + if (padding) { + int mtu = get_local_mtu_ioa_socket(ss->client_socket); + if (mtu < 68) + mtu = 1500; - mtu = (mtu >> 2) << 2; - stun_attr_add_padding_str(ioa_network_buffer_data(nbh), &len, (uint16_t)mtu); - } - } - } - } - ioa_network_buffer_set_size(nbh, len); - } + mtu = (mtu >> 2) << 2; + stun_attr_add_padding_str(ioa_network_buffer_data(nbh), &len, (uint16_t)mtu); + } + } + } + } + ioa_network_buffer_set_size(nbh, len); + } - FUNCEND; - return 0; + FUNCEND; + return 0; } -static int handle_turn_send(turn_turnserver *server, ts_ur_super_session *ss, - int *err_code, const uint8_t **reason, uint16_t *unknown_attrs, uint16_t *ua_num, - ioa_net_data *in_buffer) { +static int handle_turn_send(turn_turnserver *server, ts_ur_super_session *ss, int *err_code, const uint8_t **reason, + uint16_t *unknown_attrs, uint16_t *ua_num, ioa_net_data *in_buffer) { - FUNCSTART; + FUNCSTART; - ioa_addr peer_addr; - const uint8_t* value = NULL; - int len = -1; - int addr_found = 0; - int set_df = 0; + ioa_addr peer_addr; + const uint8_t *value = NULL; + int len = -1; + int addr_found = 0; + int set_df = 0; - addr_set_any(&peer_addr); - allocation* a = get_allocation_ss(ss); + addr_set_any(&peer_addr); + allocation *a = get_allocation_ss(ss); - if(ss->is_tcp_relay) { - *err_code = 403; - *reason = (const uint8_t *)"Send cannot be used with TCP relay"; - } else if (is_allocation_valid(a) && (in_buffer->recv_ttl != 0)) { + if (ss->is_tcp_relay) { + *err_code = 403; + *reason = (const uint8_t *)"Send cannot be used with TCP relay"; + } else if (is_allocation_valid(a) && (in_buffer->recv_ttl != 0)) { - stun_attr_ref sar = stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh)); - while (sar && (!(*err_code)) && (*ua_num < MAX_NUMBER_OF_UNKNOWN_ATTRS)) { - int attr_type = stun_attr_get_type(sar); - switch (attr_type) { - SKIP_ATTRIBUTES; - case STUN_ATTRIBUTE_DONT_FRAGMENT: - if(!(server->dont_fragment)) - unknown_attrs[(*ua_num)++] = nswap16(attr_type); - else - set_df = 1; - break; - case STUN_ATTRIBUTE_XOR_PEER_ADDRESS: { - if (addr_found) { - *err_code = 400; - *reason = (const uint8_t *)"Address duplication"; - } else { - stun_attr_get_addr_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - sar, &peer_addr, - NULL); - } - } - break; - case STUN_ATTRIBUTE_DATA: { - if (len >= 0) { - *err_code = 400; - *reason = (const uint8_t *)"Data duplication"; - } else { - len = stun_attr_get_len(sar); - value = stun_attr_get_value(sar); - } - } - break; - default: - if(attr_type>=0x0000 && attr_type<=0x7FFF) - unknown_attrs[(*ua_num)++] = nswap16(attr_type); - }; - sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - sar); - } + stun_attr_ref sar = + stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh)); + while (sar && (!(*err_code)) && (*ua_num < MAX_NUMBER_OF_UNKNOWN_ATTRS)) { + int attr_type = stun_attr_get_type(sar); + switch (attr_type) { + SKIP_ATTRIBUTES; + case STUN_ATTRIBUTE_DONT_FRAGMENT: + if (!(server->dont_fragment)) + unknown_attrs[(*ua_num)++] = nswap16(attr_type); + else + set_df = 1; + break; + case STUN_ATTRIBUTE_XOR_PEER_ADDRESS: { + if (addr_found) { + *err_code = 400; + *reason = (const uint8_t *)"Address duplication"; + } else { + stun_attr_get_addr_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), + sar, &peer_addr, NULL); + } + } break; + case STUN_ATTRIBUTE_DATA: { + if (len >= 0) { + *err_code = 400; + *reason = (const uint8_t *)"Data duplication"; + } else { + len = stun_attr_get_len(sar); + value = stun_attr_get_value(sar); + } + } break; + default: + if (attr_type >= 0x0000 && attr_type <= 0x7FFF) + unknown_attrs[(*ua_num)++] = nswap16(attr_type); + }; + sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), + sar); + } - if (*err_code) { - ; - } else if (*ua_num > 0) { + if (*err_code) { + ; + } else if (*ua_num > 0) { - *err_code = 420; + *err_code = 420; - } else if (!addr_any(&peer_addr) && len >= 0) { + } else if (!addr_any(&peer_addr) && len >= 0) { - turn_permission_info* tinfo = NULL; + turn_permission_info *tinfo = NULL; - if(!(server->server_relay)) - tinfo = allocation_get_permission(a, &peer_addr); + if (!(server->server_relay)) + tinfo = allocation_get_permission(a, &peer_addr); - if (tinfo || (server->server_relay)) { + if (tinfo || (server->server_relay)) { - set_df_on_ioa_socket(get_relay_socket_ss(ss,peer_addr.ss.sa_family), set_df); + set_df_on_ioa_socket(get_relay_socket_ss(ss, peer_addr.ss.sa_family), set_df); - ioa_network_buffer_handle nbh = in_buffer->nbh; - if(value && len>0) { - uint16_t offset = (uint16_t)(value - ioa_network_buffer_data(nbh)); - ioa_network_buffer_add_offset_size(nbh,offset,0,len); - } else { - len = 0; - ioa_network_buffer_set_size(nbh,len); - } - ioa_network_buffer_header_init(nbh); - int skip = 0; - send_data_from_ioa_socket_nbh(get_relay_socket_ss(ss,peer_addr.ss.sa_family), &peer_addr, nbh, in_buffer->recv_ttl-1, in_buffer->recv_tos, &skip); - if (!skip) { - ++(ss->peer_sent_packets); - ss->peer_sent_bytes += len; - turn_report_session_usage(ss, 0); - } - in_buffer->nbh = NULL; - } + ioa_network_buffer_handle nbh = in_buffer->nbh; + if (value && len > 0) { + uint16_t offset = (uint16_t)(value - ioa_network_buffer_data(nbh)); + ioa_network_buffer_add_offset_size(nbh, offset, 0, len); + } else { + len = 0; + ioa_network_buffer_set_size(nbh, len); + } + ioa_network_buffer_header_init(nbh); + int skip = 0; + send_data_from_ioa_socket_nbh(get_relay_socket_ss(ss, peer_addr.ss.sa_family), &peer_addr, nbh, + in_buffer->recv_ttl - 1, in_buffer->recv_tos, &skip); + if (!skip) { + ++(ss->peer_sent_packets); + ss->peer_sent_bytes += len; + turn_report_session_usage(ss, 0); + } + in_buffer->nbh = NULL; + } - } else { - *err_code = 400; - *reason = (const uint8_t *)"No address found"; - } - } + } else { + *err_code = 400; + *reason = (const uint8_t *)"No address found"; + } + } - FUNCEND; - return 0; + FUNCEND; + return 0; } static int update_permission(ts_ur_super_session *ss, ioa_addr *peer_addr) { - if (!ss || !peer_addr) - return -1; + if (!ss || !peer_addr) + return -1; - allocation* a = get_allocation_ss(ss); + allocation *a = get_allocation_ss(ss); - turn_permission_info* tinfo = allocation_get_permission(a, peer_addr); + turn_permission_info *tinfo = allocation_get_permission(a, peer_addr); - if (!tinfo) { - tinfo = allocation_add_permission(a, peer_addr); - } + if (!tinfo) { + tinfo = allocation_add_permission(a, peer_addr); + } - if (!tinfo) - return -1; + if (!tinfo) + return -1; - if (update_turn_permission_lifetime(ss, tinfo, 0) < 0) - return -1; + if (update_turn_permission_lifetime(ss, tinfo, 0) < 0) + return -1; - ch_info *chn = get_turn_channel(tinfo, peer_addr); - if(chn) { - if (update_channel_lifetime(ss, chn) < 0) - return -1; - } + ch_info *chn = get_turn_channel(tinfo, peer_addr); + if (chn) { + if (update_channel_lifetime(ss, chn) < 0) + return -1; + } - return 0; + return 0; } -static int handle_turn_create_permission(turn_turnserver *server, - ts_ur_super_session *ss, stun_tid *tid, int *resp_constructed, - int *err_code, const uint8_t **reason, uint16_t *unknown_attrs, uint16_t *ua_num, - ioa_net_data *in_buffer, ioa_network_buffer_handle nbh) { +static int handle_turn_create_permission(turn_turnserver *server, ts_ur_super_session *ss, stun_tid *tid, + int *resp_constructed, int *err_code, const uint8_t **reason, + uint16_t *unknown_attrs, uint16_t *ua_num, ioa_net_data *in_buffer, + ioa_network_buffer_handle nbh) { - int ret = -1; + int ret = -1; - int addr_found = 0; + int addr_found = 0; - UNUSED_ARG(server); + UNUSED_ARG(server); - allocation* a = get_allocation_ss(ss); + allocation *a = get_allocation_ss(ss); - if (is_allocation_valid(a)) { + if (is_allocation_valid(a)) { - { - stun_attr_ref sar = stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh)); + { + stun_attr_ref sar = + stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh)); - while (sar && (!(*err_code)) && (*ua_num < MAX_NUMBER_OF_UNKNOWN_ATTRS)) { + while (sar && (!(*err_code)) && (*ua_num < MAX_NUMBER_OF_UNKNOWN_ATTRS)) { - int attr_type = stun_attr_get_type(sar); + int attr_type = stun_attr_get_type(sar); - switch (attr_type) { + switch (attr_type) { - SKIP_ATTRIBUTES; + SKIP_ATTRIBUTES; - case STUN_ATTRIBUTE_XOR_PEER_ADDRESS: { + case STUN_ATTRIBUTE_XOR_PEER_ADDRESS: { - ioa_addr peer_addr; - addr_set_any(&peer_addr); + ioa_addr peer_addr; + addr_set_any(&peer_addr); - stun_attr_get_addr_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - sar, &peer_addr, - NULL); + stun_attr_get_addr_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), + sar, &peer_addr, NULL); - if(!get_relay_socket(a,peer_addr.ss.sa_family)) { - *err_code = 443; - *reason = (const uint8_t *)"Peer Address Family Mismatch (4)"; - } else if(!good_peer_addr(server, ss->realm_options.name, &peer_addr)) { - *err_code = 403; - *reason = (const uint8_t *) "Forbidden IP"; - } else { - addr_found++; - } - } - break; - default: - if(attr_type>=0x0000 && attr_type<=0x7FFF) - unknown_attrs[(*ua_num)++] = nswap16(attr_type); - }; - sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - sar); - } - } + if (!get_relay_socket(a, peer_addr.ss.sa_family)) { + *err_code = 443; + *reason = (const uint8_t *)"Peer Address Family Mismatch (4)"; + } else if (!good_peer_addr(server, ss->realm_options.name, &peer_addr)) { + *err_code = 403; + *reason = (const uint8_t *)"Forbidden IP"; + } else { + addr_found++; + } + } break; + default: + if (attr_type >= 0x0000 && attr_type <= 0x7FFF) + unknown_attrs[(*ua_num)++] = nswap16(attr_type); + }; + sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh), sar); + } + } - if (*ua_num > 0) { + if (*ua_num > 0) { - *err_code = 420; + *err_code = 420; - } else if (*err_code) { + } else if (*err_code) { - ; + ; - } else if (!addr_found) { + } else if (!addr_found) { - *err_code = 400; - *reason = (const uint8_t *)"No address found"; + *err_code = 400; + *reason = (const uint8_t *)"No address found"; - } else { + } else { - stun_attr_ref sar = stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh)); + stun_attr_ref sar = + stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh)); - while (sar) { + while (sar) { - int attr_type = stun_attr_get_type(sar); + int attr_type = stun_attr_get_type(sar); - switch (attr_type) { + switch (attr_type) { - SKIP_ATTRIBUTES; + SKIP_ATTRIBUTES; - case STUN_ATTRIBUTE_XOR_PEER_ADDRESS: { + case STUN_ATTRIBUTE_XOR_PEER_ADDRESS: { - ioa_addr peer_addr; - addr_set_any(&peer_addr); + ioa_addr peer_addr; + addr_set_any(&peer_addr); - stun_attr_get_addr_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - sar, &peer_addr, - NULL); + stun_attr_get_addr_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), + sar, &peer_addr, NULL); - addr_set_port(&peer_addr, 0); - if (update_permission(ss, &peer_addr) < 0) { - *err_code = 500; - *reason = (const uint8_t *)"Cannot update some permissions (critical server software error)"; - } - } - break; - default: - ; - } + addr_set_port(&peer_addr, 0); + if (update_permission(ss, &peer_addr) < 0) { + *err_code = 500; + *reason = (const uint8_t *)"Cannot update some permissions (critical server software error)"; + } + } break; + default:; + } - sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - sar); - } + sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh), sar); + } - if(*err_code == 0) { - size_t len = ioa_network_buffer_get_size(nbh); - stun_init_success_response_str(STUN_METHOD_CREATE_PERMISSION, - ioa_network_buffer_data(nbh), &len, tid); - ioa_network_buffer_set_size(nbh,len); + if (*err_code == 0) { + size_t len = ioa_network_buffer_get_size(nbh); + stun_init_success_response_str(STUN_METHOD_CREATE_PERMISSION, ioa_network_buffer_data(nbh), &len, tid); + ioa_network_buffer_set_size(nbh, len); - ret = 0; - *resp_constructed = 1; - } - } - } + ret = 0; + *resp_constructed = 1; + } + } + } - return ret; + return ret; } // AUTH ==>> -static int need_stun_authentication(turn_turnserver *server, ts_ur_super_session *ss) -{ - UNUSED_ARG(ss); +static int need_stun_authentication(turn_turnserver *server, ts_ur_super_session *ss) { + UNUSED_ARG(ss); - if(server) { - switch(server->ct) { - case TURN_CREDENTIALS_LONG_TERM: - return 1; - default: - ; - }; - } + if (server) { + switch (server->ct) { + case TURN_CREDENTIALS_LONG_TERM: + return 1; + default:; + }; + } - return 0; + return 0; } -static int create_challenge_response(ts_ur_super_session *ss, stun_tid *tid, int *resp_constructed, - int *err_code, const uint8_t **reason, - ioa_network_buffer_handle nbh, - uint16_t method) -{ - size_t len = ioa_network_buffer_get_size(nbh); - stun_init_error_response_str(method, ioa_network_buffer_data(nbh), &len, *err_code, *reason, tid); - *resp_constructed = 1; - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_NONCE, - ss->nonce, (int)(NONCE_MAX_SIZE-1)); - char *realm = ss->realm_options.name; - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_REALM, - (uint8_t*)realm, (int)(strlen((char*)(realm)))); +static int create_challenge_response(ts_ur_super_session *ss, stun_tid *tid, int *resp_constructed, int *err_code, + const uint8_t **reason, ioa_network_buffer_handle nbh, uint16_t method) { + size_t len = ioa_network_buffer_get_size(nbh); + stun_init_error_response_str(method, ioa_network_buffer_data(nbh), &len, *err_code, *reason, tid); + *resp_constructed = 1; + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_NONCE, ss->nonce, (int)(NONCE_MAX_SIZE - 1)); + char *realm = ss->realm_options.name; + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_REALM, (uint8_t *)realm, + (int)(strlen((char *)(realm)))); - if(ss->server) { - turn_turnserver* server = (turn_turnserver*)ss->server; - if(server->oauth) { - const char *server_name = server->oauth_server_name; - if(!(server_name && server_name[0])) { - server_name = realm; - } - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, - STUN_ATTRIBUTE_THIRD_PARTY_AUTHORIZATION, - (const uint8_t*)(server_name), - strlen(server_name)); - } + if (ss->server) { + turn_turnserver *server = (turn_turnserver *)ss->server; + if (server->oauth) { + const char *server_name = server->oauth_server_name; + if (!(server_name && server_name[0])) { + server_name = realm; + } + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_THIRD_PARTY_AUTHORIZATION, + (const uint8_t *)(server_name), strlen(server_name)); } + } - ioa_network_buffer_set_size(nbh,len); - return 0; + ioa_network_buffer_set_size(nbh, len); + return 0; } #if !defined(min) -#define min(a,b) ((a)<=(b) ? (a) : (b)) +#define min(a, b) ((a) <= (b) ? (a) : (b)) #endif -static void resume_processing_after_username_check(int success, int oauth, int max_session_time, hmackey_t hmackey, password_t pwd, turn_turnserver *server, uint64_t ctxkey, ioa_net_data *in_buffer, uint8_t *realm) -{ +static void resume_processing_after_username_check(int success, int oauth, int max_session_time, hmackey_t hmackey, + password_t pwd, turn_turnserver *server, uint64_t ctxkey, + ioa_net_data *in_buffer, uint8_t *realm) { - if(server && in_buffer && in_buffer->nbh) { + if (server && in_buffer && in_buffer->nbh) { - ts_ur_super_session *ss = get_session_from_map(server,(turnsession_id)ctxkey); - if(ss && ss->client_socket) { - turn_turnserver *server = (turn_turnserver *)ss->server; + ts_ur_super_session *ss = get_session_from_map(server, (turnsession_id)ctxkey); + if (ss && ss->client_socket) { + turn_turnserver *server = (turn_turnserver *)ss->server; - if(success) { - memcpy(ss->hmackey,hmackey,sizeof(hmackey_t)); - ss->hmackey_set = 1; - ss->oauth = oauth; - ss->max_session_time_auth = (turn_time_t)max_session_time; - memcpy(ss->pwd,pwd,sizeof(password_t)); - if(realm && realm[0] && strcmp((char*)realm,ss->realm_options.name)) { - dec_quota(ss); - get_realm_options_by_name((char*)realm, &(ss->realm_options)); - inc_quota(ss,ss->username); - } - } + if (success) { + memcpy(ss->hmackey, hmackey, sizeof(hmackey_t)); + ss->hmackey_set = 1; + ss->oauth = oauth; + ss->max_session_time_auth = (turn_time_t)max_session_time; + memcpy(ss->pwd, pwd, sizeof(password_t)); + if (realm && realm[0] && strcmp((char *)realm, ss->realm_options.name)) { + dec_quota(ss); + get_realm_options_by_name((char *)realm, &(ss->realm_options)); + inc_quota(ss, ss->username); + } + } - read_client_connection(server,ss,in_buffer,0,0); + read_client_connection(server, ss, in_buffer, 0, 0); - close_ioa_socket_after_processing_if_necessary(ss->client_socket); + close_ioa_socket_after_processing_if_necessary(ss->client_socket); - ioa_network_buffer_delete(server->e, in_buffer->nbh); - in_buffer->nbh=NULL; - } - } + ioa_network_buffer_delete(server->e, in_buffer->nbh); + in_buffer->nbh = NULL; + } + } } -static int check_stun_auth(turn_turnserver *server, - ts_ur_super_session *ss, stun_tid *tid, int *resp_constructed, - int *err_code, const uint8_t **reason, - ioa_net_data *in_buffer, ioa_network_buffer_handle nbh, - uint16_t method, int *message_integrity, - int *postpone_reply, - int can_resume) -{ - uint8_t usname[STUN_MAX_USERNAME_SIZE+1]; - uint8_t nonce[STUN_MAX_NONCE_SIZE+1]; - uint8_t realm[STUN_MAX_REALM_SIZE+1]; - size_t alen = 0; +static int check_stun_auth(turn_turnserver *server, ts_ur_super_session *ss, stun_tid *tid, int *resp_constructed, + int *err_code, const uint8_t **reason, ioa_net_data *in_buffer, + ioa_network_buffer_handle nbh, uint16_t method, int *message_integrity, int *postpone_reply, + int can_resume) { + uint8_t usname[STUN_MAX_USERNAME_SIZE + 1]; + uint8_t nonce[STUN_MAX_NONCE_SIZE + 1]; + uint8_t realm[STUN_MAX_REALM_SIZE + 1]; + size_t alen = 0; - if(!need_stun_authentication(server, ss)) - return 0; + if (!need_stun_authentication(server, ss)) + return 0; - int new_nonce = 0; + int new_nonce = 0; - { - int generate_new_nonce = 0; - if(ss->nonce[0]==0) { - generate_new_nonce = 1; - new_nonce = 1; - } + { + int generate_new_nonce = 0; + if (ss->nonce[0] == 0) { + generate_new_nonce = 1; + new_nonce = 1; + } - if(*(server->stale_nonce)) { - if(turn_time_before(ss->nonce_expiration_time,server->ctime)) { - generate_new_nonce = 1; - } - } + if (*(server->stale_nonce)) { + if (turn_time_before(ss->nonce_expiration_time, server->ctime)) { + generate_new_nonce = 1; + } + } - if(generate_new_nonce) { + if (generate_new_nonce) { - int i = 0; + int i = 0; - if(TURN_RANDOM_SIZE == 8) { - for(i=0;i<(NONCE_LENGTH_32BITS>>1);i++) { - uint8_t *s = ss->nonce + 8*i; - uint64_t rand=(uint64_t)turn_random(); - snprintf((char*)s, NONCE_MAX_SIZE-8*i, "%08lx",(unsigned long)rand); - } - } else { - for(i=0;inonce + 4*i; - uint32_t rand=(uint32_t)turn_random(); - snprintf((char*)s, NONCE_MAX_SIZE-4*i, "%04x",(unsigned int)rand); - } - } - ss->nonce_expiration_time = server->ctime + *(server->stale_nonce); - } - } + if (TURN_RANDOM_SIZE == 8) { + for (i = 0; i < (NONCE_LENGTH_32BITS >> 1); i++) { + uint8_t *s = ss->nonce + 8 * i; + uint64_t rand = (uint64_t)turn_random(); + snprintf((char *)s, NONCE_MAX_SIZE - 8 * i, "%08lx", (unsigned long)rand); + } + } else { + for (i = 0; i < NONCE_LENGTH_32BITS; i++) { + uint8_t *s = ss->nonce + 4 * i; + uint32_t rand = (uint32_t)turn_random(); + snprintf((char *)s, NONCE_MAX_SIZE - 4 * i, "%04x", (unsigned int)rand); + } + } + ss->nonce_expiration_time = server->ctime + *(server->stale_nonce); + } + } - /* MESSAGE_INTEGRITY ATTR: */ + /* MESSAGE_INTEGRITY ATTR: */ - stun_attr_ref sar = stun_attr_get_first_by_type_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - STUN_ATTRIBUTE_MESSAGE_INTEGRITY); + stun_attr_ref sar = + stun_attr_get_first_by_type_str(ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh), STUN_ATTRIBUTE_MESSAGE_INTEGRITY); - if(!sar) { - *err_code = 401; - return create_challenge_response(ss,tid,resp_constructed,err_code,reason,nbh,method); - } + if (!sar) { + *err_code = 401; + return create_challenge_response(ss, tid, resp_constructed, err_code, reason, nbh, method); + } - { - int sarlen = stun_attr_get_len(sar); + { + int sarlen = stun_attr_get_len(sar); - switch(sarlen) { - case SHA1SIZEBYTES: - break; - case SHA256SIZEBYTES: - case SHA384SIZEBYTES: - case SHA512SIZEBYTES: - default: - *err_code = 401; - return create_challenge_response(ss,tid,resp_constructed,err_code,reason,nbh,method); - }; - } + switch (sarlen) { + case SHA1SIZEBYTES: + break; + case SHA256SIZEBYTES: + case SHA384SIZEBYTES: + case SHA512SIZEBYTES: + default: + *err_code = 401; + return create_challenge_response(ss, tid, resp_constructed, err_code, reason, nbh, method); + }; + } - { + { - /* REALM ATTR: */ + /* REALM ATTR: */ - sar = stun_attr_get_first_by_type_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - STUN_ATTRIBUTE_REALM); + sar = stun_attr_get_first_by_type_str(ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh), STUN_ATTRIBUTE_REALM); - if(!sar) { - *err_code = 400; - return -1; - } + if (!sar) { + *err_code = 400; + return -1; + } - alen = min((size_t)stun_attr_get_len(sar),sizeof(realm)-1); - memcpy(realm,stun_attr_get_value(sar),alen); - realm[alen]=0; + alen = min((size_t)stun_attr_get_len(sar), sizeof(realm) - 1); + memcpy(realm, stun_attr_get_value(sar), alen); + realm[alen] = 0; - if(!is_secure_string(realm,0)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: wrong realm: %s\n", __FUNCTION__, (char*)realm); - realm[0]=0; - *err_code = 400; - return -1; - } - - if(method == STUN_METHOD_CONNECTION_BIND) { + if (!is_secure_string(realm, 0)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: wrong realm: %s\n", __FUNCTION__, (char *)realm); + realm[0] = 0; + *err_code = 400; + return -1; + } - get_realm_options_by_name((char *)realm, &(ss->realm_options)); + if (method == STUN_METHOD_CONNECTION_BIND) { - } else if(strcmp((char*)realm, (char*)(ss->realm_options.name))) { - if(!(ss->oauth)){ - if(method == STUN_METHOD_ALLOCATE) { - *err_code = 437; - *reason = (const uint8_t*)"Allocation mismatch: wrong credentials: the realm value is incorrect"; - } else { - *err_code = 441; - *reason = (const uint8_t*)"Wrong credentials: the realm value is incorrect"; - } - return -1; - } else { - memcpy(realm,ss->realm_options.name,sizeof(ss->realm_options.name)); - } - } - } + get_realm_options_by_name((char *)realm, &(ss->realm_options)); - /* USERNAME ATTR: */ + } else if (strcmp((char *)realm, (char *)(ss->realm_options.name))) { + if (!(ss->oauth)) { + if (method == STUN_METHOD_ALLOCATE) { + *err_code = 437; + *reason = (const uint8_t *)"Allocation mismatch: wrong credentials: the realm value is incorrect"; + } else { + *err_code = 441; + *reason = (const uint8_t *)"Wrong credentials: the realm value is incorrect"; + } + return -1; + } else { + memcpy(realm, ss->realm_options.name, sizeof(ss->realm_options.name)); + } + } + } - sar = stun_attr_get_first_by_type_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - STUN_ATTRIBUTE_USERNAME); + /* USERNAME ATTR: */ - if(!sar) { - *err_code = 400; - return -1; - } + sar = stun_attr_get_first_by_type_str(ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh), STUN_ATTRIBUTE_USERNAME); - alen = min((size_t)stun_attr_get_len(sar),sizeof(usname)-1); - memcpy(usname,stun_attr_get_value(sar),alen); - usname[alen]=0; + if (!sar) { + *err_code = 400; + return -1; + } - if(!is_secure_string(usname,1)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: wrong username: %s\n", __FUNCTION__, (char*)usname); - usname[0]=0; - *err_code = 400; - return -1; - } else if(ss->username[0]) { - if(strcmp((char*)ss->username,(char*)usname)) { - if(ss->oauth) { - ss->hmackey_set = 0; - STRCPY(ss->username,usname); - } else { - if(method == STUN_METHOD_ALLOCATE) { - *err_code = 437; - *reason = (const uint8_t*)"Allocation mismatch: wrong credentials"; - } else { - *err_code = 441; - } - return -1; - } - } - } else { - STRCPY(ss->username,usname); - } + alen = min((size_t)stun_attr_get_len(sar), sizeof(usname) - 1); + memcpy(usname, stun_attr_get_value(sar), alen); + usname[alen] = 0; - { - /* NONCE ATTR: */ + if (!is_secure_string(usname, 1)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: wrong username: %s\n", __FUNCTION__, (char *)usname); + usname[0] = 0; + *err_code = 400; + return -1; + } else if (ss->username[0]) { + if (strcmp((char *)ss->username, (char *)usname)) { + if (ss->oauth) { + ss->hmackey_set = 0; + STRCPY(ss->username, usname); + } else { + if (method == STUN_METHOD_ALLOCATE) { + *err_code = 437; + *reason = (const uint8_t *)"Allocation mismatch: wrong credentials"; + } else { + *err_code = 441; + } + return -1; + } + } + } else { + STRCPY(ss->username, usname); + } - sar = stun_attr_get_first_by_type_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - STUN_ATTRIBUTE_NONCE); + { + /* NONCE ATTR: */ - if(!sar) { - *err_code = 400; - return -1; - } + sar = stun_attr_get_first_by_type_str(ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh), STUN_ATTRIBUTE_NONCE); - alen = min((size_t)stun_attr_get_len(sar),sizeof(nonce)-1); - memcpy(nonce,stun_attr_get_value(sar),alen); - nonce[alen]=0; + if (!sar) { + *err_code = 400; + return -1; + } - /* Stale Nonce check: */ + alen = min((size_t)stun_attr_get_len(sar), sizeof(nonce) - 1); + memcpy(nonce, stun_attr_get_value(sar), alen); + nonce[alen] = 0; - if(new_nonce) { - *err_code = 438; - *reason = (const uint8_t*)"Wrong nonce"; - return create_challenge_response(ss,tid,resp_constructed,err_code,reason,nbh,method); - } + /* Stale Nonce check: */ - if(strcmp((char*)ss->nonce,(char*)nonce)) { - *err_code = 438; - *reason = (const uint8_t*)"Stale nonce"; - return create_challenge_response(ss,tid,resp_constructed,err_code,reason,nbh,method); - } - } + if (new_nonce) { + *err_code = 438; + *reason = (const uint8_t *)"Wrong nonce"; + return create_challenge_response(ss, tid, resp_constructed, err_code, reason, nbh, method); + } - /* Password */ - if(!(ss->hmackey_set) && (ss->pwd[0] == 0)) { - if(can_resume) { - (server->userkeycb)(server->id, server->ct, server->oauth, &(ss->oauth), usname, realm, resume_processing_after_username_check, in_buffer, ss->id, postpone_reply); - if(*postpone_reply) { - return 0; - } - } + if (strcmp((char *)ss->nonce, (char *)nonce)) { + *err_code = 438; + *reason = (const uint8_t *)"Stale nonce"; + return create_challenge_response(ss, tid, resp_constructed, err_code, reason, nbh, method); + } + } - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: Cannot find credentials of user <%s>\n", - __FUNCTION__, (char*)usname); - *err_code = 401; - return create_challenge_response(ss,tid,resp_constructed,err_code,reason,nbh,method); - } + /* Password */ + if (!(ss->hmackey_set) && (ss->pwd[0] == 0)) { + if (can_resume) { + (server->userkeycb)(server->id, server->ct, server->oauth, &(ss->oauth), usname, realm, + resume_processing_after_username_check, in_buffer, ss->id, postpone_reply); + if (*postpone_reply) { + return 0; + } + } - /* Check integrity */ - if(stun_check_message_integrity_by_key_str(server->ct,ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - ss->hmackey, - ss->pwd, - SHATYPE_DEFAULT)<1) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot find credentials of user <%s>\n", __FUNCTION__, (char *)usname); + *err_code = 401; + return create_challenge_response(ss, tid, resp_constructed, err_code, reason, nbh, method); + } - if(can_resume) { - (server->userkeycb)(server->id, server->ct, server->oauth, &(ss->oauth), usname, realm, resume_processing_after_username_check, in_buffer, ss->id, postpone_reply); - if(*postpone_reply) { - return 0; - } - } + /* Check integrity */ + if (stun_check_message_integrity_by_key_str(server->ct, ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh), ss->hmackey, ss->pwd, + SHATYPE_DEFAULT) < 1) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: user %s credentials are incorrect\n", - __FUNCTION__, (char*)usname); - *err_code = 401; - return create_challenge_response(ss,tid,resp_constructed,err_code,reason,nbh,method); - } + if (can_resume) { + (server->userkeycb)(server->id, server->ct, server->oauth, &(ss->oauth), usname, realm, + resume_processing_after_username_check, in_buffer, ss->id, postpone_reply); + if (*postpone_reply) { + return 0; + } + } - *message_integrity = 1; + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: user %s credentials are incorrect\n", __FUNCTION__, (char *)usname); + *err_code = 401; + return create_challenge_response(ss, tid, resp_constructed, err_code, reason, nbh, method); + } - return 0; + *message_integrity = 1; + + return 0; } //<<== AUTH -static void set_alternate_server(turn_server_addrs_list_t *asl, const ioa_addr *local_addr, size_t *counter, uint16_t method, stun_tid *tid, int *resp_constructed, int *err_code, const uint8_t **reason, ioa_network_buffer_handle nbh) -{ - if(asl && asl->size && local_addr) { +static void set_alternate_server(turn_server_addrs_list_t *asl, const ioa_addr *local_addr, size_t *counter, + uint16_t method, stun_tid *tid, int *resp_constructed, int *err_code, + const uint8_t **reason, ioa_network_buffer_handle nbh) { + if (asl && asl->size && local_addr) { - size_t i; + size_t i; - /* to prevent indefinite cycle: */ + /* to prevent indefinite cycle: */ - for(i=0;isize;++i) { - ioa_addr *addr = &(asl->addrs[i]); - if(addr_eq(addr,local_addr)) - return; - } + for (i = 0; i < asl->size; ++i) { + ioa_addr *addr = &(asl->addrs[i]); + if (addr_eq(addr, local_addr)) + return; + } - for(i=0;isize;++i) { - if(*counter>=asl->size) - *counter = 0; - ioa_addr *addr = &(asl->addrs[*counter]); - *counter +=1; - if(addr->ss.sa_family == local_addr->ss.sa_family) { + for (i = 0; i < asl->size; ++i) { + if (*counter >= asl->size) + *counter = 0; + ioa_addr *addr = &(asl->addrs[*counter]); + *counter += 1; + if (addr->ss.sa_family == local_addr->ss.sa_family) { - *err_code = 300; + *err_code = 300; - size_t len = ioa_network_buffer_get_size(nbh); - stun_init_error_response_str(method, ioa_network_buffer_data(nbh), &len, *err_code, *reason, tid); - *resp_constructed = 1; - stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_ALTERNATE_SERVER, addr); - ioa_network_buffer_set_size(nbh,len); + size_t len = ioa_network_buffer_get_size(nbh); + stun_init_error_response_str(method, ioa_network_buffer_data(nbh), &len, *err_code, *reason, tid); + *resp_constructed = 1; + stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_ALTERNATE_SERVER, addr); + ioa_network_buffer_set_size(nbh, len); - return; - } - } - } + return; + } + } + } } -static int handle_turn_command(turn_turnserver *server, ts_ur_super_session *ss, ioa_net_data *in_buffer, ioa_network_buffer_handle nbh, int *resp_constructed, int can_resume) -{ - - stun_tid tid; - int err_code = 0; - const uint8_t *reason = NULL; - int no_response = 0; - int message_integrity = 0; - - if(!(ss->client_socket)) - return -1; - - uint16_t unknown_attrs[MAX_NUMBER_OF_UNKNOWN_ATTRS]; - uint16_t ua_num = 0; - uint16_t method = stun_get_method_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh)); - - *resp_constructed = 0; - - stun_tid_from_message_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - &tid); - - if (stun_is_request_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh))) { - - if((method == STUN_METHOD_BINDING) && (*(server->no_stun))) { - - no_response = 1; - if(server->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: STUN method 0x%x ignored\n", - __FUNCTION__, (unsigned int)method); - } - - } else if((method != STUN_METHOD_BINDING) && (*(server->stun_only))) { - - no_response = 1; - if(server->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: STUN method 0x%x ignored\n", - __FUNCTION__, (unsigned int)method); - } - - } else if((method != STUN_METHOD_BINDING) || (*(server->secure_stun))) { - - if(method == STUN_METHOD_ALLOCATE) { - - allocation *a = get_allocation_ss(ss); - if(is_allocation_valid(a)) { - if(!stun_tid_equals(&(a->tid), &tid)) { - err_code = 437; - reason = (const uint8_t *)"Mismatched allocation: wrong transaction ID"; - } - } - - if(!err_code) { - SOCKET_TYPE cst = get_ioa_socket_type(ss->client_socket); - turn_server_addrs_list_t *asl = server->alternate_servers_list; - - if(((cst == UDP_SOCKET)||(cst == DTLS_SOCKET)) && server->self_udp_balance && - server->aux_servers_list && server->aux_servers_list->size) { - asl = server->aux_servers_list; - } else if(((cst == TLS_SOCKET) || (cst == DTLS_SOCKET) ||(cst == TLS_SCTP_SOCKET)) && - server->tls_alternate_servers_list && server->tls_alternate_servers_list->size) { - asl = server->tls_alternate_servers_list; - } - - if(asl && asl->size) { - TURN_MUTEX_LOCK(&(asl->m)); - set_alternate_server(asl,get_local_addr_from_ioa_socket(ss->client_socket),&(server->as_counter),method,&tid,resp_constructed,&err_code,&reason,nbh); - TURN_MUTEX_UNLOCK(&(asl->m)); - } - } - } - - /* check that the realm is the same as in the original request */ - if(ss->origin_set) { - stun_attr_ref sar = stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh)); - - int origin_found = 0; - int norigins = 0; - - while(sar && !origin_found) { - if(stun_attr_get_type(sar) == STUN_ATTRIBUTE_ORIGIN) { - int sarlen = stun_attr_get_len(sar); - if(sarlen>0) { - ++norigins; - char *o = (char*)malloc(sarlen+1); - memcpy(o,stun_attr_get_value(sar),sarlen); - o[sarlen]=0; - char *corigin = (char*)malloc(STUN_MAX_ORIGIN_SIZE+1); - corigin[0]=0; - if(get_canonic_origin(o,corigin,STUN_MAX_ORIGIN_SIZE)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: Wrong origin format: %s\n", - __FUNCTION__, o); - } - if(!strncmp(ss->origin,corigin,STUN_MAX_ORIGIN_SIZE)) { - origin_found = 1; - } - free(corigin); - free(o); - } - } - sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), sar); - } - - if(server->check_origin && *(server->check_origin)) { - if(ss->origin[0]) { - if(!origin_found) { - err_code = 441; - reason = (const uint8_t *)"The origin attribute does not match the initial session origin value"; - if(server->verbose) { - char smethod[129]; - stun_method_str(method,smethod); - log_method(ss, smethod, err_code, reason); - } - } - } else if(norigins > 0){ - err_code = 441; - reason = (const uint8_t *)"The origin attribute is empty, does not match the initial session origin value"; - if(server->verbose) { - char smethod[129]; - stun_method_str(method,smethod); - log_method(ss, smethod, err_code, reason); - } - } - } - } - - /* get the initial origin value */ - if(!err_code && !(ss->origin_set) && (method == STUN_METHOD_ALLOCATE)) { - - stun_attr_ref sar = stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh)); - - int origin_found = 0; - - while(sar && !origin_found) { - if(stun_attr_get_type(sar) == STUN_ATTRIBUTE_ORIGIN) { - int sarlen = stun_attr_get_len(sar); - if(sarlen>0) { - char *o = (char*)malloc(sarlen+1); - memcpy(o,stun_attr_get_value(sar),sarlen); - o[sarlen]=0; - char *corigin = (char*)malloc(STUN_MAX_ORIGIN_SIZE+1); - corigin[0]=0; - if(get_canonic_origin(o,corigin,STUN_MAX_ORIGIN_SIZE)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, - "%s: Wrong origin format: %s\n", - __FUNCTION__, o); - } - strncpy(ss->origin,corigin,STUN_MAX_ORIGIN_SIZE); - free(corigin); - free(o); - origin_found = get_realm_options_by_origin(ss->origin,&(ss->realm_options)); - } - } - sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), sar); - } - - ss->origin_set = 1; - } - - if(!err_code && !(*resp_constructed) && !no_response) { - if(method == STUN_METHOD_CONNECTION_BIND) { - ; - } else if(!(*(server->mobility)) || (method != STUN_METHOD_REFRESH) || is_allocation_valid(get_allocation_ss(ss))) { - int postpone_reply = 0; - check_stun_auth(server, ss, &tid, resp_constructed, &err_code, &reason, in_buffer, nbh, method, &message_integrity, &postpone_reply, can_resume); - if(postpone_reply) - no_response = 1; - } - } - } - - if (!err_code && !(*resp_constructed) && !no_response) { - - switch (method){ - - case STUN_METHOD_ALLOCATE: - - { - handle_turn_allocate(server, ss, &tid, resp_constructed, &err_code, &reason, - unknown_attrs, &ua_num, in_buffer, nbh); - - if(server->verbose) { - log_method(ss, "ALLOCATE", err_code, reason); - } - - break; - } - - case STUN_METHOD_CONNECT: - - handle_turn_connect(server, ss, &tid, &err_code, &reason, - unknown_attrs, &ua_num, in_buffer); - - if(server->verbose) { - log_method(ss, "CONNECT", err_code, reason); - } - - if(!err_code) - no_response = 1; - - break; - - case STUN_METHOD_CONNECTION_BIND: - - handle_turn_connection_bind(server, ss, &tid, resp_constructed, &err_code, &reason, - unknown_attrs, &ua_num, in_buffer, nbh, message_integrity, can_resume); - - if(server->verbose && err_code) { - log_method(ss, "CONNECTION_BIND", err_code, reason); - } - - break; +static int handle_turn_command(turn_turnserver *server, ts_ur_super_session *ss, ioa_net_data *in_buffer, + ioa_network_buffer_handle nbh, int *resp_constructed, int can_resume) { + + stun_tid tid; + int err_code = 0; + const uint8_t *reason = NULL; + int no_response = 0; + int message_integrity = 0; + + if (!(ss->client_socket)) + return -1; + + uint16_t unknown_attrs[MAX_NUMBER_OF_UNKNOWN_ATTRS]; + uint16_t ua_num = 0; + uint16_t method = + stun_get_method_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh)); + + *resp_constructed = 0; + + stun_tid_from_message_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), &tid); + + if (stun_is_request_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh))) { + + if ((method == STUN_METHOD_BINDING) && (*(server->no_stun))) { + + no_response = 1; + if (server->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: STUN method 0x%x ignored\n", __FUNCTION__, (unsigned int)method); + } + + } else if ((method != STUN_METHOD_BINDING) && (*(server->stun_only))) { + + no_response = 1; + if (server->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: STUN method 0x%x ignored\n", __FUNCTION__, (unsigned int)method); + } + + } else if ((method != STUN_METHOD_BINDING) || (*(server->secure_stun))) { + + if (method == STUN_METHOD_ALLOCATE) { + + allocation *a = get_allocation_ss(ss); + if (is_allocation_valid(a)) { + if (!stun_tid_equals(&(a->tid), &tid)) { + err_code = 437; + reason = (const uint8_t *)"Mismatched allocation: wrong transaction ID"; + } + } + + if (!err_code) { + SOCKET_TYPE cst = get_ioa_socket_type(ss->client_socket); + turn_server_addrs_list_t *asl = server->alternate_servers_list; + + if (((cst == UDP_SOCKET) || (cst == DTLS_SOCKET)) && server->self_udp_balance && server->aux_servers_list && + server->aux_servers_list->size) { + asl = server->aux_servers_list; + } else if (((cst == TLS_SOCKET) || (cst == DTLS_SOCKET) || (cst == TLS_SCTP_SOCKET)) && + server->tls_alternate_servers_list && server->tls_alternate_servers_list->size) { + asl = server->tls_alternate_servers_list; + } + + if (asl && asl->size) { + TURN_MUTEX_LOCK(&(asl->m)); + set_alternate_server(asl, get_local_addr_from_ioa_socket(ss->client_socket), &(server->as_counter), method, + &tid, resp_constructed, &err_code, &reason, nbh); + TURN_MUTEX_UNLOCK(&(asl->m)); + } + } + } + + /* check that the realm is the same as in the original request */ + if (ss->origin_set) { + stun_attr_ref sar = stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh)); + + int origin_found = 0; + int norigins = 0; + + while (sar && !origin_found) { + if (stun_attr_get_type(sar) == STUN_ATTRIBUTE_ORIGIN) { + int sarlen = stun_attr_get_len(sar); + if (sarlen > 0) { + ++norigins; + char *o = (char *)malloc(sarlen + 1); + memcpy(o, stun_attr_get_value(sar), sarlen); + o[sarlen] = 0; + char *corigin = (char *)malloc(STUN_MAX_ORIGIN_SIZE + 1); + corigin[0] = 0; + if (get_canonic_origin(o, corigin, STUN_MAX_ORIGIN_SIZE) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Wrong origin format: %s\n", __FUNCTION__, o); + } + if (!strncmp(ss->origin, corigin, STUN_MAX_ORIGIN_SIZE)) { + origin_found = 1; + } + free(corigin); + free(o); + } + } + sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh), sar); + } + + if (server->check_origin && *(server->check_origin)) { + if (ss->origin[0]) { + if (!origin_found) { + err_code = 441; + reason = (const uint8_t *)"The origin attribute does not match the initial session origin value"; + if (server->verbose) { + char smethod[129]; + stun_method_str(method, smethod); + log_method(ss, smethod, err_code, reason); + } + } + } else if (norigins > 0) { + err_code = 441; + reason = (const uint8_t *)"The origin attribute is empty, does not match the initial session origin value"; + if (server->verbose) { + char smethod[129]; + stun_method_str(method, smethod); + log_method(ss, smethod, err_code, reason); + } + } + } + } + + /* get the initial origin value */ + if (!err_code && !(ss->origin_set) && (method == STUN_METHOD_ALLOCATE)) { + + stun_attr_ref sar = stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh)); + + int origin_found = 0; + + while (sar && !origin_found) { + if (stun_attr_get_type(sar) == STUN_ATTRIBUTE_ORIGIN) { + int sarlen = stun_attr_get_len(sar); + if (sarlen > 0) { + char *o = (char *)malloc(sarlen + 1); + memcpy(o, stun_attr_get_value(sar), sarlen); + o[sarlen] = 0; + char *corigin = (char *)malloc(STUN_MAX_ORIGIN_SIZE + 1); + corigin[0] = 0; + if (get_canonic_origin(o, corigin, STUN_MAX_ORIGIN_SIZE) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Wrong origin format: %s\n", __FUNCTION__, o); + } + strncpy(ss->origin, corigin, STUN_MAX_ORIGIN_SIZE); + free(corigin); + free(o); + origin_found = get_realm_options_by_origin(ss->origin, &(ss->realm_options)); + } + } + sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh), sar); + } + + ss->origin_set = 1; + } + + if (!err_code && !(*resp_constructed) && !no_response) { + if (method == STUN_METHOD_CONNECTION_BIND) { + ; + } else if (!(*(server->mobility)) || (method != STUN_METHOD_REFRESH) || + is_allocation_valid(get_allocation_ss(ss))) { + int postpone_reply = 0; + check_stun_auth(server, ss, &tid, resp_constructed, &err_code, &reason, in_buffer, nbh, method, + &message_integrity, &postpone_reply, can_resume); + if (postpone_reply) + no_response = 1; + } + } + } + + if (!err_code && !(*resp_constructed) && !no_response) { + + switch (method) { + + case STUN_METHOD_ALLOCATE: + + { + handle_turn_allocate(server, ss, &tid, resp_constructed, &err_code, &reason, unknown_attrs, &ua_num, in_buffer, + nbh); + + if (server->verbose) { + log_method(ss, "ALLOCATE", err_code, reason); + } + + break; + } + + case STUN_METHOD_CONNECT: + + handle_turn_connect(server, ss, &tid, &err_code, &reason, unknown_attrs, &ua_num, in_buffer); + + if (server->verbose) { + log_method(ss, "CONNECT", err_code, reason); + } + + if (!err_code) + no_response = 1; + + break; + + case STUN_METHOD_CONNECTION_BIND: + + handle_turn_connection_bind(server, ss, &tid, resp_constructed, &err_code, &reason, unknown_attrs, &ua_num, + in_buffer, nbh, message_integrity, can_resume); + + if (server->verbose && err_code) { + log_method(ss, "CONNECTION_BIND", err_code, reason); + } - case STUN_METHOD_REFRESH: + break; - handle_turn_refresh(server, ss, &tid, resp_constructed, &err_code, &reason, - unknown_attrs, &ua_num, in_buffer, nbh, message_integrity, - &no_response, can_resume); + case STUN_METHOD_REFRESH: - if(server->verbose) { - log_method(ss, "REFRESH", err_code, reason); - } - break; + handle_turn_refresh(server, ss, &tid, resp_constructed, &err_code, &reason, unknown_attrs, &ua_num, in_buffer, + nbh, message_integrity, &no_response, can_resume); - case STUN_METHOD_CHANNEL_BIND: + if (server->verbose) { + log_method(ss, "REFRESH", err_code, reason); + } + break; - handle_turn_channel_bind(server, ss, &tid, resp_constructed, &err_code, &reason, - unknown_attrs, &ua_num, in_buffer, nbh); + case STUN_METHOD_CHANNEL_BIND: - if(server->verbose) { - log_method(ss, "CHANNEL_BIND", err_code, reason); - } - break; + handle_turn_channel_bind(server, ss, &tid, resp_constructed, &err_code, &reason, unknown_attrs, &ua_num, + in_buffer, nbh); - case STUN_METHOD_CREATE_PERMISSION: + if (server->verbose) { + log_method(ss, "CHANNEL_BIND", err_code, reason); + } + break; - handle_turn_create_permission(server, ss, &tid, resp_constructed, &err_code, &reason, - unknown_attrs, &ua_num, in_buffer, nbh); + case STUN_METHOD_CREATE_PERMISSION: - if(server->verbose) { - log_method(ss, "CREATE_PERMISSION", err_code, reason); - } - break; + handle_turn_create_permission(server, ss, &tid, resp_constructed, &err_code, &reason, unknown_attrs, &ua_num, + in_buffer, nbh); - case STUN_METHOD_BINDING: + if (server->verbose) { + log_method(ss, "CREATE_PERMISSION", err_code, reason); + } + break; - { - int origin_changed=0; - ioa_addr response_origin; - int dest_changed=0; - ioa_addr response_destination; + case STUN_METHOD_BINDING: - handle_turn_binding(server, ss, &tid, resp_constructed, &err_code, &reason, - unknown_attrs, &ua_num, in_buffer, nbh, - &origin_changed, &response_origin, - &dest_changed, &response_destination, - 0, 0); + { + int origin_changed = 0; + ioa_addr response_origin; + int dest_changed = 0; + ioa_addr response_destination; - if(server->verbose && *(server->log_binding)) { - log_method(ss, "BINDING", err_code, reason); - } + handle_turn_binding(server, ss, &tid, resp_constructed, &err_code, &reason, unknown_attrs, &ua_num, in_buffer, + nbh, &origin_changed, &response_origin, &dest_changed, &response_destination, 0, 0); - if(*resp_constructed && !err_code && (origin_changed || dest_changed)) { + if (server->verbose && *(server->log_binding)) { + log_method(ss, "BINDING", err_code, reason); + } - if (server->verbose && *(server->log_binding)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "RFC 5780 request successfully processed\n"); - } + if (*resp_constructed && !err_code && (origin_changed || dest_changed)) { - if(!(*server->no_software_attribute)) - { - const uint8_t *field = (const uint8_t *) get_version(server); - size_t fsz = strlen(get_version(server)); - size_t len = ioa_network_buffer_get_size(nbh); - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_SOFTWARE, field, fsz); - ioa_network_buffer_set_size(nbh, len); - } + if (server->verbose && *(server->log_binding)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "RFC 5780 request successfully processed\n"); + } - send_turn_message_to(server, nbh, &response_origin, &response_destination); + if (!(*server->no_software_attribute)) { + const uint8_t *field = (const uint8_t *)get_version(server); + size_t fsz = strlen(get_version(server)); + size_t len = ioa_network_buffer_get_size(nbh); + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_SOFTWARE, field, fsz); + ioa_network_buffer_set_size(nbh, len); + } - no_response = 1; - } + send_turn_message_to(server, nbh, &response_origin, &response_destination); - break; - } - default: - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unsupported STUN request received, method 0x%x\n",(unsigned int)method); - }; - } + no_response = 1; + } - } else if (stun_is_indication_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh))) { + break; + } + default: + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unsupported STUN request received, method 0x%x\n", (unsigned int)method); + }; + } - no_response = 1; - int postpone = 0; + } else if (stun_is_indication_str(ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh))) { - if (!postpone && !err_code) { + no_response = 1; + int postpone = 0; - switch (method){ + if (!postpone && !err_code) { - case STUN_METHOD_BINDING: - //ICE ? - break; + switch (method) { - case STUN_METHOD_SEND: + case STUN_METHOD_BINDING: + // ICE ? + break; - handle_turn_send(server, ss, &err_code, &reason, unknown_attrs, &ua_num, in_buffer); + case STUN_METHOD_SEND: - if(eve(server->verbose)) { - log_method(ss, "SEND", err_code, reason); - } + handle_turn_send(server, ss, &err_code, &reason, unknown_attrs, &ua_num, in_buffer); - break; + if (eve(server->verbose)) { + log_method(ss, "SEND", err_code, reason); + } - case STUN_METHOD_DATA: + break; - err_code = 403; + case STUN_METHOD_DATA: - if(eve(server->verbose)) { - log_method(ss, "DATA", err_code, reason); - } + err_code = 403; - break; + if (eve(server->verbose)) { + log_method(ss, "DATA", err_code, reason); + } - default: - if (server->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Unsupported STUN indication received: method 0x%x\n",(unsigned int)method); - } - } - }; + break; - } else { + default: + if (server->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Unsupported STUN indication received: method 0x%x\n", + (unsigned int)method); + } + } + }; - no_response = 1; + } else { - if (server->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Wrong STUN message received\n"); - } - } + no_response = 1; - if(ss->to_be_closed || !(ss->client_socket) || ioa_socket_tobeclosed(ss->client_socket)) - return 0; + if (server->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Wrong STUN message received\n"); + } + } - if (ua_num > 0) { + if (ss->to_be_closed || !(ss->client_socket) || ioa_socket_tobeclosed(ss->client_socket)) + return 0; - err_code = 420; + if (ua_num > 0) { - size_t len = ioa_network_buffer_get_size(nbh); - stun_init_error_response_str(method, ioa_network_buffer_data(nbh), &len, err_code, NULL, &tid); + err_code = 420; - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES, (const uint8_t*) unknown_attrs, (ua_num - * 2)); + size_t len = ioa_network_buffer_get_size(nbh); + stun_init_error_response_str(method, ioa_network_buffer_data(nbh), &len, err_code, NULL, &tid); - ioa_network_buffer_set_size(nbh,len); + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES, + (const uint8_t *)unknown_attrs, (ua_num * 2)); - *resp_constructed = 1; - } + ioa_network_buffer_set_size(nbh, len); - if (!no_response) { + *resp_constructed = 1; + } - if (!(*resp_constructed)) { + if (!no_response) { - if (!err_code) - err_code = 400; + if (!(*resp_constructed)) { - size_t len = ioa_network_buffer_get_size(nbh); - stun_init_error_response_str(method, ioa_network_buffer_data(nbh), &len, err_code, reason, &tid); - ioa_network_buffer_set_size(nbh,len); - *resp_constructed = 1; - } + if (!err_code) + err_code = 400; - if(!(*server->no_software_attribute)) - { - const uint8_t *field = (const uint8_t *) get_version(server); - size_t fsz = strlen(get_version(server)); - size_t len = ioa_network_buffer_get_size(nbh); - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_SOFTWARE, field, fsz); - ioa_network_buffer_set_size(nbh, len); - } + size_t len = ioa_network_buffer_get_size(nbh); + stun_init_error_response_str(method, ioa_network_buffer_data(nbh), &len, err_code, reason, &tid); + ioa_network_buffer_set_size(nbh, len); + *resp_constructed = 1; + } - if(message_integrity) { - size_t len = ioa_network_buffer_get_size(nbh); - stun_attr_add_integrity_str(server->ct,ioa_network_buffer_data(nbh),&len,ss->hmackey,ss->pwd,SHATYPE_DEFAULT); - ioa_network_buffer_set_size(nbh,len); - } + if (!(*server->no_software_attribute)) { + const uint8_t *field = (const uint8_t *)get_version(server); + size_t fsz = strlen(get_version(server)); + size_t len = ioa_network_buffer_get_size(nbh); + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_SOFTWARE, field, fsz); + ioa_network_buffer_set_size(nbh, len); + } - if(err_code) { - if(server->verbose) { - log_method(ss, "message", err_code, reason); - } - } + if (message_integrity) { + size_t len = ioa_network_buffer_get_size(nbh); + stun_attr_add_integrity_str(server->ct, ioa_network_buffer_data(nbh), &len, ss->hmackey, ss->pwd, + SHATYPE_DEFAULT); + ioa_network_buffer_set_size(nbh, len); + } - } else { - *resp_constructed = 0; - } + if (err_code) { + if (server->verbose) { + log_method(ss, "message", err_code, reason); + } + } - return 0; + } else { + *resp_constructed = 0; + } + + return 0; } -static int handle_old_stun_command(turn_turnserver *server, ts_ur_super_session *ss, ioa_net_data *in_buffer, ioa_network_buffer_handle nbh, int *resp_constructed, uint32_t cookie) -{ +static int handle_old_stun_command(turn_turnserver *server, ts_ur_super_session *ss, ioa_net_data *in_buffer, + ioa_network_buffer_handle nbh, int *resp_constructed, uint32_t cookie) { - stun_tid tid; - int err_code = 0; - const uint8_t *reason = NULL; - int no_response = 0; + stun_tid tid; + int err_code = 0; + const uint8_t *reason = NULL; + int no_response = 0; - uint16_t unknown_attrs[MAX_NUMBER_OF_UNKNOWN_ATTRS]; - uint16_t ua_num = 0; - uint16_t method = stun_get_method_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh)); + uint16_t unknown_attrs[MAX_NUMBER_OF_UNKNOWN_ATTRS]; + uint16_t ua_num = 0; + uint16_t method = + stun_get_method_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh)); - *resp_constructed = 0; + *resp_constructed = 0; - stun_tid_from_message_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - &tid); + stun_tid_from_message_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), &tid); - if (stun_is_request_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh))) { + if (stun_is_request_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh))) { - if(method != STUN_METHOD_BINDING) { - no_response = 1; - if(server->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: OLD STUN method 0x%x ignored\n", - __FUNCTION__, (unsigned int)method); - } - } + if (method != STUN_METHOD_BINDING) { + no_response = 1; + if (server->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: OLD STUN method 0x%x ignored\n", __FUNCTION__, (unsigned int)method); + } + } - if (!err_code && !(*resp_constructed) && !no_response) { + if (!err_code && !(*resp_constructed) && !no_response) { - int origin_changed=0; - ioa_addr response_origin; - int dest_changed=0; - ioa_addr response_destination; + int origin_changed = 0; + ioa_addr response_origin; + int dest_changed = 0; + ioa_addr response_destination; - handle_turn_binding(server, ss, &tid, resp_constructed, &err_code, &reason, - unknown_attrs, &ua_num, in_buffer, nbh, - &origin_changed, &response_origin, - &dest_changed, &response_destination, - cookie,1); + handle_turn_binding(server, ss, &tid, resp_constructed, &err_code, &reason, unknown_attrs, &ua_num, in_buffer, + nbh, &origin_changed, &response_origin, &dest_changed, &response_destination, cookie, 1); - if(server->verbose && *(server->log_binding)) { - log_method(ss, "OLD BINDING", err_code, reason); - } + if (server->verbose && *(server->log_binding)) { + log_method(ss, "OLD BINDING", err_code, reason); + } - if(*resp_constructed && !err_code && (origin_changed || dest_changed)) { + if (*resp_constructed && !err_code && (origin_changed || dest_changed)) { - if (server->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "RFC3489 CHANGE request successfully processed\n"); - } + if (server->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "RFC3489 CHANGE request successfully processed\n"); + } - { - size_t oldsz = strlen(get_version(server)); - size_t newsz = (((oldsz)>>2) + 1)<<2; - uint8_t software[120]; - memset(software, 0, sizeof(software)); - if(newsz>sizeof(software)) - newsz = sizeof(software); - memcpy(software,get_version(server),oldsz); - size_t len = ioa_network_buffer_get_size(nbh); - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, OLD_STUN_ATTRIBUTE_SERVER, software, newsz); - ioa_network_buffer_set_size(nbh, len); - } + { + size_t oldsz = strlen(get_version(server)); + size_t newsz = (((oldsz) >> 2) + 1) << 2; + uint8_t software[120]; + memset(software, 0, sizeof(software)); + if (newsz > sizeof(software)) + newsz = sizeof(software); + memcpy(software, get_version(server), oldsz); + size_t len = ioa_network_buffer_get_size(nbh); + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, OLD_STUN_ATTRIBUTE_SERVER, software, newsz); + ioa_network_buffer_set_size(nbh, len); + } - send_turn_message_to(server, nbh, &response_origin, &response_destination); + send_turn_message_to(server, nbh, &response_origin, &response_destination); - no_response = 1; - } - } - } else { + no_response = 1; + } + } + } else { - no_response = 1; + no_response = 1; - if (server->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Wrong OLD STUN message received\n"); - } - } + if (server->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Wrong OLD STUN message received\n"); + } + } - if (ua_num > 0) { + if (ua_num > 0) { - err_code = 420; + err_code = 420; - size_t len = ioa_network_buffer_get_size(nbh); - old_stun_init_error_response_str(method, ioa_network_buffer_data(nbh), &len, err_code, NULL, &tid, cookie); + size_t len = ioa_network_buffer_get_size(nbh); + old_stun_init_error_response_str(method, ioa_network_buffer_data(nbh), &len, err_code, NULL, &tid, cookie); - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES, (const uint8_t*) unknown_attrs, (ua_num * 2)); + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES, + (const uint8_t *)unknown_attrs, (ua_num * 2)); - ioa_network_buffer_set_size(nbh,len); + ioa_network_buffer_set_size(nbh, len); - *resp_constructed = 1; - } + *resp_constructed = 1; + } - if (!no_response) { + if (!no_response) { - if (!(*resp_constructed)) { + if (!(*resp_constructed)) { - if (!err_code) - err_code = 400; + if (!err_code) + err_code = 400; - size_t len = ioa_network_buffer_get_size(nbh); - old_stun_init_error_response_str(method, ioa_network_buffer_data(nbh), &len, err_code, reason, &tid, cookie); - ioa_network_buffer_set_size(nbh,len); - *resp_constructed = 1; - } + size_t len = ioa_network_buffer_get_size(nbh); + old_stun_init_error_response_str(method, ioa_network_buffer_data(nbh), &len, err_code, reason, &tid, cookie); + ioa_network_buffer_set_size(nbh, len); + *resp_constructed = 1; + } - { - size_t oldsz = strlen(get_version(server)); - size_t newsz = (((oldsz)>>2) + 1)<<2; - uint8_t software[120]; - memset(software, 0, sizeof(software)); - if(newsz>sizeof(software)) - newsz = sizeof(software); - memcpy(software,get_version(server),oldsz); - size_t len = ioa_network_buffer_get_size(nbh); - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, OLD_STUN_ATTRIBUTE_SERVER, software, newsz); - ioa_network_buffer_set_size(nbh, len); - } + { + size_t oldsz = strlen(get_version(server)); + size_t newsz = (((oldsz) >> 2) + 1) << 2; + uint8_t software[120]; + memset(software, 0, sizeof(software)); + if (newsz > sizeof(software)) + newsz = sizeof(software); + memcpy(software, get_version(server), oldsz); + size_t len = ioa_network_buffer_get_size(nbh); + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, OLD_STUN_ATTRIBUTE_SERVER, software, newsz); + ioa_network_buffer_set_size(nbh, len); + } - if(err_code) { - if(server->verbose) { - log_method(ss, "OLD STUN message", err_code, reason); - } - } + if (err_code) { + if (server->verbose) { + log_method(ss, "OLD STUN message", err_code, reason); + } + } - } else { - *resp_constructed = 0; - } + } else { + *resp_constructed = 0; + } - return 0; + return 0; } ////////////////////////////////////////////////////////////////// -static int write_to_peerchannel(ts_ur_super_session* ss, uint16_t chnum, ioa_net_data *in_buffer) { +static int write_to_peerchannel(ts_ur_super_session *ss, uint16_t chnum, ioa_net_data *in_buffer) { - int rc = 0; + int rc = 0; - if (ss && (in_buffer->recv_ttl!=0)) { + if (ss && (in_buffer->recv_ttl != 0)) { - allocation* a = get_allocation_ss(ss); + allocation *a = get_allocation_ss(ss); - if (is_allocation_valid(a)) { + if (is_allocation_valid(a)) { - ch_info* chn = allocation_get_ch_info(a, chnum); + ch_info *chn = allocation_get_ch_info(a, chnum); - if (!chn) - return -1; + if (!chn) + return -1; - /* Channel packets are always sent with DF=0: */ - set_df_on_ioa_socket(get_relay_socket_ss(ss, chn->peer_addr.ss.sa_family), 0); + /* Channel packets are always sent with DF=0: */ + set_df_on_ioa_socket(get_relay_socket_ss(ss, chn->peer_addr.ss.sa_family), 0); - ioa_network_buffer_handle nbh = in_buffer->nbh; + ioa_network_buffer_handle nbh = in_buffer->nbh; - ioa_network_buffer_add_offset_size(in_buffer->nbh, STUN_CHANNEL_HEADER_LENGTH, 0, ioa_network_buffer_get_size(in_buffer->nbh)-STUN_CHANNEL_HEADER_LENGTH); + ioa_network_buffer_add_offset_size(in_buffer->nbh, STUN_CHANNEL_HEADER_LENGTH, 0, + ioa_network_buffer_get_size(in_buffer->nbh) - STUN_CHANNEL_HEADER_LENGTH); - ioa_network_buffer_header_init(nbh); + ioa_network_buffer_header_init(nbh); - int skip = 0; - rc = send_data_from_ioa_socket_nbh(get_relay_socket_ss(ss, chn->peer_addr.ss.sa_family), &(chn->peer_addr), nbh, in_buffer->recv_ttl-1, in_buffer->recv_tos, &skip); + int skip = 0; + rc = send_data_from_ioa_socket_nbh(get_relay_socket_ss(ss, chn->peer_addr.ss.sa_family), &(chn->peer_addr), nbh, + in_buffer->recv_ttl - 1, in_buffer->recv_tos, &skip); - if (!skip && rc > -1) { - ++(ss->peer_sent_packets); - ss->peer_sent_bytes += (uint32_t)ioa_network_buffer_get_size(in_buffer->nbh); - turn_report_session_usage(ss, 0); - } + if (!skip && rc > -1) { + ++(ss->peer_sent_packets); + ss->peer_sent_bytes += (uint32_t)ioa_network_buffer_get_size(in_buffer->nbh); + turn_report_session_usage(ss, 0); + } - in_buffer->nbh = NULL; - } - } + in_buffer->nbh = NULL; + } + } - return rc; + return rc; } -static void client_input_handler(ioa_socket_handle s, int event_type, - ioa_net_data *data, void *arg, int can_resume); -static void peer_input_handler(ioa_socket_handle s, int event_type, - ioa_net_data *data, void *arg, int can_resume); +static void client_input_handler(ioa_socket_handle s, int event_type, ioa_net_data *data, void *arg, int can_resume); +static void peer_input_handler(ioa_socket_handle s, int event_type, ioa_net_data *data, void *arg, int can_resume); /////////////// Client actions ///////////////// -int shutdown_client_connection(turn_turnserver *server, ts_ur_super_session *ss, int force, const char* reason) { +int shutdown_client_connection(turn_turnserver *server, ts_ur_super_session *ss, int force, const char *reason) { - FUNCSTART; + FUNCSTART; - if (!ss) - return -1; + if (!ss) + return -1; - SOCKET_TYPE socket_type = get_ioa_socket_type(ss->client_socket); + SOCKET_TYPE socket_type = get_ioa_socket_type(ss->client_socket); - turn_report_session_usage(ss, 1); - dec_quota(ss); - dec_bps(ss); + turn_report_session_usage(ss, 1); + dec_quota(ss); + dec_bps(ss); - allocation* alloc = get_allocation_ss(ss); - if (!is_allocation_valid(alloc)) { - force = 1; - } + allocation *alloc = get_allocation_ss(ss); + if (!is_allocation_valid(alloc)) { + force = 1; + } - if(!force && ss->is_mobile) { + if (!force && ss->is_mobile) { - if (ss->client_socket && server->verbose) { + if (ss->client_socket && server->verbose) { - char sraddr[129]="\0"; - char sladdr[129]="\0"; - addr_to_string(get_remote_addr_from_ioa_socket(ss->client_socket),(uint8_t*)sraddr); - addr_to_string(get_local_addr_from_ioa_socket(ss->client_socket),(uint8_t*)sladdr); + char sraddr[129] = "\0"; + char sladdr[129] = "\0"; + addr_to_string(get_remote_addr_from_ioa_socket(ss->client_socket), (uint8_t *)sraddr); + addr_to_string(get_local_addr_from_ioa_socket(ss->client_socket), (uint8_t *)sladdr); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "session %018llu: closed (1st stage), user <%s> realm <%s> origin <%s>, local %s, remote %s, reason: %s\n",(unsigned long long)(ss->id),(char*)ss->username,(char*)ss->realm_options.name,(char*)ss->origin, sladdr,sraddr,reason); - } + TURN_LOG_FUNC( + TURN_LOG_LEVEL_INFO, + "session %018llu: closed (1st stage), user <%s> realm <%s> origin <%s>, local %s, remote %s, reason: %s\n", + (unsigned long long)(ss->id), (char *)ss->username, (char *)ss->realm_options.name, (char *)ss->origin, + sladdr, sraddr, reason); + } - IOA_CLOSE_SOCKET(ss->client_socket); + IOA_CLOSE_SOCKET(ss->client_socket); - FUNCEND; + FUNCEND; - return 0; - } + return 0; + } - if (eve(server->verbose)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "closing session 0x%lx, client socket 0x%lx (socket session=0x%lx)\n", - (long) ss, - (long) ss->client_socket, - (long)get_ioa_socket_session(ss->client_socket)); - } + if (eve(server->verbose)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "closing session 0x%lx, client socket 0x%lx (socket session=0x%lx)\n", (long)ss, + (long)ss->client_socket, (long)get_ioa_socket_session(ss->client_socket)); + } - if (server->disconnect) - server->disconnect(ss); + if (server->disconnect) + server->disconnect(ss); - if (server->verbose) { + if (server->verbose) { - char sraddr[129]="\0"; - char sladdr[129]="\0"; - addr_to_string(get_remote_addr_from_ioa_socket(ss->client_socket),(uint8_t*)sraddr); - addr_to_string(get_local_addr_from_ioa_socket(ss->client_socket),(uint8_t*)sladdr); + char sraddr[129] = "\0"; + char sladdr[129] = "\0"; + addr_to_string(get_remote_addr_from_ioa_socket(ss->client_socket), (uint8_t *)sraddr); + addr_to_string(get_local_addr_from_ioa_socket(ss->client_socket), (uint8_t *)sladdr); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "session %018llu: closed (2nd stage), user <%s> realm <%s> origin <%s>, local %s, remote %s, reason: %s\n", - (unsigned long long)(ss->id), (char*)ss->username,(char*)ss->realm_options.name,(char*)ss->origin, sladdr,sraddr, reason); - } + TURN_LOG_FUNC( + TURN_LOG_LEVEL_INFO, + "session %018llu: closed (2nd stage), user <%s> realm <%s> origin <%s>, local %s, remote %s, reason: %s\n", + (unsigned long long)(ss->id), (char *)ss->username, (char *)ss->realm_options.name, (char *)ss->origin, sladdr, + sraddr, reason); + } - IOA_CLOSE_SOCKET(ss->client_socket); - { - int i; - for(i=0;ialloc.relay_sessions[i].s); - } - } + IOA_CLOSE_SOCKET(ss->client_socket); + { + int i; + for (i = 0; i < ALLOC_PROTOCOLS_NUMBER; ++i) { + IOA_CLOSE_SOCKET(ss->alloc.relay_sessions[i].s); + } + } - turn_server_remove_all_from_ur_map_ss(ss, socket_type); + turn_server_remove_all_from_ur_map_ss(ss, socket_type); - FUNCEND; + FUNCEND; - return 0; + return 0; } -static void client_to_be_allocated_timeout_handler(ioa_engine_handle e, - void *arg) { +static void client_to_be_allocated_timeout_handler(ioa_engine_handle e, void *arg) { - if (!arg) - return; + if (!arg) + return; - UNUSED_ARG(e); + UNUSED_ARG(e); - ts_ur_super_session* ss = (ts_ur_super_session*) arg; + ts_ur_super_session *ss = (ts_ur_super_session *)arg; - turn_turnserver* server = (turn_turnserver*) (ss->server); + turn_turnserver *server = (turn_turnserver *)(ss->server); - if (!server) - return; + if (!server) + return; - FUNCSTART; + FUNCSTART; - int to_close = 0; + int to_close = 0; - ioa_socket_handle s = ss->client_socket; + ioa_socket_handle s = ss->client_socket; - if(!s || ioa_socket_tobeclosed(s)) { - to_close = 1; - } else if(get_ioa_socket_app_type(s) == HTTPS_CLIENT_SOCKET) { - ; - } else { - ioa_socket_handle rs4 = ss->alloc.relay_sessions[ALLOC_IPV4_INDEX].s; - ioa_socket_handle rs6 = ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].s; - if((!rs4 || ioa_socket_tobeclosed(rs4)) && (!rs6 || ioa_socket_tobeclosed(rs6))) { - to_close = 1; - } else if(ss->client_socket == NULL) { - to_close = 1; - } else if(!(ss->alloc.relay_sessions[ALLOC_IPV4_INDEX].lifetime_ev) && - !(ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].lifetime_ev)) { - to_close = 1; - } else if(!(ss->to_be_allocated_timeout_ev)) { - to_close = 1; - } - } + if (!s || ioa_socket_tobeclosed(s)) { + to_close = 1; + } else if (get_ioa_socket_app_type(s) == HTTPS_CLIENT_SOCKET) { + ; + } else { + ioa_socket_handle rs4 = ss->alloc.relay_sessions[ALLOC_IPV4_INDEX].s; + ioa_socket_handle rs6 = ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].s; + if ((!rs4 || ioa_socket_tobeclosed(rs4)) && (!rs6 || ioa_socket_tobeclosed(rs6))) { + to_close = 1; + } else if (ss->client_socket == NULL) { + to_close = 1; + } else if (!(ss->alloc.relay_sessions[ALLOC_IPV4_INDEX].lifetime_ev) && + !(ss->alloc.relay_sessions[ALLOC_IPV6_INDEX].lifetime_ev)) { + to_close = 1; + } else if (!(ss->to_be_allocated_timeout_ev)) { + to_close = 1; + } + } - if(to_close) { - IOA_EVENT_DEL(ss->to_be_allocated_timeout_ev); - shutdown_client_connection(server, ss, 1, "allocation watchdog determined stale session state"); - } + if (to_close) { + IOA_EVENT_DEL(ss->to_be_allocated_timeout_ev); + shutdown_client_connection(server, ss, 1, "allocation watchdog determined stale session state"); + } - FUNCEND; + FUNCEND; } -static int write_client_connection(turn_turnserver *server, ts_ur_super_session* ss, ioa_network_buffer_handle nbh, int ttl, int tos) { +static int write_client_connection(turn_turnserver *server, ts_ur_super_session *ss, ioa_network_buffer_handle nbh, + int ttl, int tos) { - FUNCSTART; + FUNCSTART; - if (!(ss->client_socket)) { - ioa_network_buffer_delete(server->e, nbh); - FUNCEND; - return -1; - } else { + if (!(ss->client_socket)) { + ioa_network_buffer_delete(server->e, nbh); + FUNCEND; + return -1; + } else { - if (eve(server->verbose)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: prepare to write to s 0x%lx\n", __FUNCTION__, - (long) (ss->client_socket)); - } + if (eve(server->verbose)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: prepare to write to s 0x%lx\n", __FUNCTION__, (long)(ss->client_socket)); + } - int skip = 0; - int ret = send_data_from_ioa_socket_nbh(ss->client_socket, NULL, nbh, ttl, tos, &skip); + int skip = 0; + int ret = send_data_from_ioa_socket_nbh(ss->client_socket, NULL, nbh, ttl, tos, &skip); - if(!skip && ret>-1) { - ++(ss->sent_packets); - ss->sent_bytes += (uint32_t)ioa_network_buffer_get_size(nbh); - turn_report_session_usage(ss, 0); - } + if (!skip && ret > -1) { + ++(ss->sent_packets); + ss->sent_bytes += (uint32_t)ioa_network_buffer_get_size(nbh); + turn_report_session_usage(ss, 0); + } - FUNCEND; - return ret; - } + FUNCEND; + return ret; + } } static void client_ss_allocation_timeout_handler(ioa_engine_handle e, void *arg) { - UNUSED_ARG(e); + UNUSED_ARG(e); - if (!arg) - return; + if (!arg) + return; - relay_endpoint_session *rsession = (relay_endpoint_session*)arg; + relay_endpoint_session *rsession = (relay_endpoint_session *)arg; - if(!(rsession->s)) - return; + if (!(rsession->s)) + return; - ts_ur_super_session* ss = get_ioa_socket_session(rsession->s); + ts_ur_super_session *ss = get_ioa_socket_session(rsession->s); - if (!ss) - return; + if (!ss) + return; - allocation* a = get_allocation_ss(ss); + allocation *a = get_allocation_ss(ss); - turn_turnserver* server = (turn_turnserver*) (ss->server); + turn_turnserver *server = (turn_turnserver *)(ss->server); - if (!server) { - clear_allocation(a, get_ioa_socket_type(ss->client_socket)); - return; - } + if (!server) { + clear_allocation(a, get_ioa_socket_type(ss->client_socket)); + return; + } - FUNCSTART; + FUNCSTART; - int family = get_ioa_socket_address_family(rsession->s); + int family = get_ioa_socket_address_family(rsession->s); - set_allocation_family_invalid(a,family); + set_allocation_family_invalid(a, family); - if(!get_relay_socket(a, AF_INET) && !get_relay_socket(a, AF_INET6)) { - shutdown_client_connection(server, ss, 0, "allocation timeout"); - } + if (!get_relay_socket(a, AF_INET) && !get_relay_socket(a, AF_INET6)) { + shutdown_client_connection(server, ss, 0, "allocation timeout"); + } - FUNCEND; + FUNCEND; } -static int create_relay_connection(turn_turnserver* server, - ts_ur_super_session *ss, uint32_t lifetime, - int address_family, uint8_t transport, - int even_port, uint64_t in_reservation_token, uint64_t *out_reservation_token, - int *err_code, const uint8_t **reason, - accept_cb acb) { +static int create_relay_connection(turn_turnserver *server, ts_ur_super_session *ss, uint32_t lifetime, + int address_family, uint8_t transport, int even_port, uint64_t in_reservation_token, + uint64_t *out_reservation_token, int *err_code, const uint8_t **reason, + accept_cb acb) { - if (server && ss && ss->client_socket && !ioa_socket_tobeclosed(ss->client_socket)) { + if (server && ss && ss->client_socket && !ioa_socket_tobeclosed(ss->client_socket)) { - allocation* a = get_allocation_ss(ss); - relay_endpoint_session* newelem = NULL; - ioa_socket_handle rtcp_s = NULL; + allocation *a = get_allocation_ss(ss); + relay_endpoint_session *newelem = NULL; + ioa_socket_handle rtcp_s = NULL; - if (in_reservation_token) { + if (in_reservation_token) { - ioa_socket_handle s = NULL; + ioa_socket_handle s = NULL; - if ((get_ioa_socket_from_reservation(server->e, in_reservation_token,&s) < 0)|| - !s || - ioa_socket_tobeclosed(s)) { + if ((get_ioa_socket_from_reservation(server->e, in_reservation_token, &s) < 0) || !s || + ioa_socket_tobeclosed(s)) { - IOA_CLOSE_SOCKET(s); - *err_code = 404; - *reason = (const uint8_t *)"Cannot find reserved socket"; - return -1; - } + IOA_CLOSE_SOCKET(s); + *err_code = 404; + *reason = (const uint8_t *)"Cannot find reserved socket"; + return -1; + } - int family = get_ioa_socket_address_family(s); + int family = get_ioa_socket_address_family(s); - newelem = get_relay_session_ss(ss,family); + newelem = get_relay_session_ss(ss, family); - if(newelem->s != s) { + if (newelem->s != s) { - IOA_CLOSE_SOCKET(newelem->s); + IOA_CLOSE_SOCKET(newelem->s); - memset(newelem, 0, sizeof(relay_endpoint_session)); - newelem->s = s; - } + memset(newelem, 0, sizeof(relay_endpoint_session)); + newelem->s = s; + } - addr_debug_print(server->verbose, get_local_addr_from_ioa_socket(newelem->s), "Local relay addr (RTCP)"); + addr_debug_print(server->verbose, get_local_addr_from_ioa_socket(newelem->s), "Local relay addr (RTCP)"); - } else { - int family = get_family(address_family,server->e,ss->client_socket); + } else { + int family = get_family(address_family, server->e, ss->client_socket); - newelem = get_relay_session_ss(ss,family); + newelem = get_relay_session_ss(ss, family); + IOA_CLOSE_SOCKET(newelem->s); - IOA_CLOSE_SOCKET(newelem->s); + memset(newelem, 0, sizeof(relay_endpoint_session)); + newelem->s = NULL; - memset(newelem, 0, sizeof(relay_endpoint_session)); - newelem->s = NULL; + int res = create_relay_ioa_sockets(server->e, ss->client_socket, address_family, transport, even_port, + &(newelem->s), &rtcp_s, out_reservation_token, err_code, reason, acb, ss); + if (res < 0) { + if (!(*err_code)) + *err_code = 508; + if (!(*reason)) + *reason = (const uint8_t *)"Cannot create socket"; + IOA_CLOSE_SOCKET(newelem->s); + IOA_CLOSE_SOCKET(rtcp_s); + return -1; + } + } - int res = create_relay_ioa_sockets(server->e, - ss->client_socket, - address_family, transport, - even_port, &(newelem->s), &rtcp_s, out_reservation_token, - err_code, reason, acb, ss); - if (res < 0) { - if(!(*err_code)) - *err_code = 508; - if(!(*reason)) - *reason = (const uint8_t *)"Cannot create socket"; - IOA_CLOSE_SOCKET(newelem->s); - IOA_CLOSE_SOCKET(rtcp_s); - return -1; - } - } + if (newelem->s == NULL) { + IOA_CLOSE_SOCKET(rtcp_s); + *err_code = 508; + *reason = (const uint8_t *)"Cannot create relay socket"; + return -1; + } - if (newelem->s == NULL) { - IOA_CLOSE_SOCKET(rtcp_s); - *err_code = 508; - *reason = (const uint8_t *)"Cannot create relay socket"; - return -1; - } + if (rtcp_s) { + if (out_reservation_token && *out_reservation_token) { + /* OK */ + } else { + IOA_CLOSE_SOCKET(newelem->s); + IOA_CLOSE_SOCKET(rtcp_s); + *err_code = 500; + *reason = (const uint8_t *)"Wrong reservation tokens (internal error)"; + return -1; + } + } - if (rtcp_s) { - if (out_reservation_token && *out_reservation_token) { - /* OK */ - } else { - IOA_CLOSE_SOCKET(newelem->s); - IOA_CLOSE_SOCKET(rtcp_s); - *err_code = 500; - *reason = (const uint8_t *)"Wrong reservation tokens (internal error)"; - return -1; - } - } + /* RFC6156: do not use DF when IPv6 is involved: */ + if ((get_ioa_socket_address_family(newelem->s) == AF_INET6) || + (get_ioa_socket_address_family(ss->client_socket) == AF_INET6)) + set_do_not_use_df(newelem->s); - /* RFC6156: do not use DF when IPv6 is involved: */ - if((get_ioa_socket_address_family(newelem->s) == AF_INET6) || - (get_ioa_socket_address_family(ss->client_socket) == AF_INET6)) - set_do_not_use_df(newelem->s); + if (get_ioa_socket_type(newelem->s) != TCP_SOCKET) { + if (register_callback_on_ioa_socket(server->e, newelem->s, IOA_EV_READ, peer_input_handler, ss, 0) < 0) { + return -1; + } + } - if(get_ioa_socket_type(newelem->s) != TCP_SOCKET) { - if(register_callback_on_ioa_socket(server->e, newelem->s, IOA_EV_READ,peer_input_handler, ss, 0)<0) { - return -1; - } - } + if (lifetime < 1) + lifetime = STUN_DEFAULT_ALLOCATE_LIFETIME; + else if (lifetime > (uint32_t) * (server->max_allocate_lifetime)) + lifetime = (uint32_t) * (server->max_allocate_lifetime); - if (lifetime<1) - lifetime = STUN_DEFAULT_ALLOCATE_LIFETIME; - else if(lifetime>(uint32_t)*(server->max_allocate_lifetime)) - lifetime = (uint32_t)*(server->max_allocate_lifetime); + ioa_timer_handle ev = set_ioa_timer(server->e, lifetime, 0, client_ss_allocation_timeout_handler, newelem, 0, + "client_ss_allocation_timeout_handler"); + set_allocation_lifetime_ev(a, server->ctime + lifetime, ev, get_ioa_socket_address_family(newelem->s)); - ioa_timer_handle ev = set_ioa_timer(server->e, lifetime, 0, - client_ss_allocation_timeout_handler, newelem, 0, - "client_ss_allocation_timeout_handler"); - set_allocation_lifetime_ev(a, server->ctime + lifetime, ev, get_ioa_socket_address_family(newelem->s)); + set_ioa_socket_session(newelem->s, ss); + } - set_ioa_socket_session(newelem->s, ss); - } - - return 0; + return 0; } -static int refresh_relay_connection(turn_turnserver* server, - ts_ur_super_session *ss, uint32_t lifetime, int even_port, - uint64_t in_reservation_token, uint64_t *out_reservation_token, - int *err_code, int family) { +static int refresh_relay_connection(turn_turnserver *server, ts_ur_super_session *ss, uint32_t lifetime, int even_port, + uint64_t in_reservation_token, uint64_t *out_reservation_token, int *err_code, + int family) { - UNUSED_ARG(even_port); - UNUSED_ARG(in_reservation_token); - UNUSED_ARG(out_reservation_token); - UNUSED_ARG(err_code); + UNUSED_ARG(even_port); + UNUSED_ARG(in_reservation_token); + UNUSED_ARG(out_reservation_token); + UNUSED_ARG(err_code); - allocation* a = get_allocation_ss(ss); + allocation *a = get_allocation_ss(ss); - if (server && ss && is_allocation_valid(a)) { + if (server && ss && is_allocation_valid(a)) { - if (lifetime < 1) { - lifetime = 1; - } + if (lifetime < 1) { + lifetime = 1; + } - ioa_timer_handle ev = set_ioa_timer(server->e, lifetime, 0, - client_ss_allocation_timeout_handler, get_relay_session(a,family), 0, - "refresh_client_ss_allocation_timeout_handler"); + ioa_timer_handle ev = + set_ioa_timer(server->e, lifetime, 0, client_ss_allocation_timeout_handler, get_relay_session(a, family), 0, + "refresh_client_ss_allocation_timeout_handler"); - set_allocation_lifetime_ev(a, server->ctime + lifetime, ev, family); + set_allocation_lifetime_ev(a, server->ctime + lifetime, ev, family); - return 0; + return 0; - } else { - return -1; - } + } else { + return -1; + } } -static int read_client_connection(turn_turnserver *server, - ts_ur_super_session *ss, ioa_net_data *in_buffer, - int can_resume, int count_usage) { +static int read_client_connection(turn_turnserver *server, ts_ur_super_session *ss, ioa_net_data *in_buffer, + int can_resume, int count_usage) { - FUNCSTART; + FUNCSTART; - if (!server || !ss || !in_buffer || !(ss->client_socket) || ss->to_be_closed || ioa_socket_tobeclosed(ss->client_socket)) { - FUNCEND; - return -1; - } + if (!server || !ss || !in_buffer || !(ss->client_socket) || ss->to_be_closed || + ioa_socket_tobeclosed(ss->client_socket)) { + FUNCEND; + return -1; + } - int ret = (int)ioa_network_buffer_get_size(in_buffer->nbh); - if (ret < 0) { - FUNCEND; - return -1; - } + int ret = (int)ioa_network_buffer_get_size(in_buffer->nbh); + if (ret < 0) { + FUNCEND; + return -1; + } - if(count_usage) { - ++(ss->received_packets); - ss->received_bytes += (uint32_t)ioa_network_buffer_get_size(in_buffer->nbh); - turn_report_session_usage(ss, 0); - } + if (count_usage) { + ++(ss->received_packets); + ss->received_bytes += (uint32_t)ioa_network_buffer_get_size(in_buffer->nbh); + turn_report_session_usage(ss, 0); + } - if (eve(server->verbose)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: data.buffer=0x%lx, data.len=%ld\n", __FUNCTION__, - (long)ioa_network_buffer_data(in_buffer->nbh), - (long)ioa_network_buffer_get_size(in_buffer->nbh)); - } + if (eve(server->verbose)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: data.buffer=0x%lx, data.len=%ld\n", __FUNCTION__, + (long)ioa_network_buffer_data(in_buffer->nbh), (long)ioa_network_buffer_get_size(in_buffer->nbh)); + } - uint16_t chnum = 0; - uint32_t old_stun_cookie = 0; + uint16_t chnum = 0; + uint32_t old_stun_cookie = 0; - size_t blen = ioa_network_buffer_get_size(in_buffer->nbh); - size_t orig_blen = blen; - SOCKET_TYPE st = get_ioa_socket_type(ss->client_socket); - SOCKET_APP_TYPE sat = get_ioa_socket_app_type(ss->client_socket); - int is_padding_mandatory = is_stream_socket(st); + size_t blen = ioa_network_buffer_get_size(in_buffer->nbh); + size_t orig_blen = blen; + SOCKET_TYPE st = get_ioa_socket_type(ss->client_socket); + SOCKET_APP_TYPE sat = get_ioa_socket_app_type(ss->client_socket); + int is_padding_mandatory = is_stream_socket(st); - if(sat == HTTP_CLIENT_SOCKET) { + if (sat == HTTP_CLIENT_SOCKET) { - if(server->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: HTTP connection input: %s\n", __FUNCTION__, (char*)ioa_network_buffer_data(in_buffer->nbh)); - } + if (server->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: HTTP connection input: %s\n", __FUNCTION__, + (char *)ioa_network_buffer_data(in_buffer->nbh)); + } - handle_http_echo(ss->client_socket); + handle_http_echo(ss->client_socket); - } else if(sat == HTTPS_CLIENT_SOCKET) { + } else if (sat == HTTPS_CLIENT_SOCKET) { - //??? + //??? - } else if (stun_is_channel_message_str(ioa_network_buffer_data(in_buffer->nbh), - &blen, - &chnum, - is_padding_mandatory)) { + } else if (stun_is_channel_message_str(ioa_network_buffer_data(in_buffer->nbh), &blen, &chnum, + is_padding_mandatory)) { - if(ss->is_tcp_relay) { - //Forbidden - FUNCEND; - return -1; - } + if (ss->is_tcp_relay) { + // Forbidden + FUNCEND; + return -1; + } - int rc = 0; + int rc = 0; - if(blen<=orig_blen) { - ioa_network_buffer_set_size(in_buffer->nbh,blen); - rc = write_to_peerchannel(ss, chnum, in_buffer); - } + if (blen <= orig_blen) { + ioa_network_buffer_set_size(in_buffer->nbh, blen); + rc = write_to_peerchannel(ss, chnum, in_buffer); + } - if (eve(server->verbose)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: wrote to peer %d bytes\n", - __FUNCTION__, (int) rc); - } + if (eve(server->verbose)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: wrote to peer %d bytes\n", __FUNCTION__, (int)rc); + } - FUNCEND; - return 0; + FUNCEND; + return 0; - } else if (stun_is_command_message_full_check_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), 0, &(ss->enforce_fingerprints))) { + } else if (stun_is_command_message_full_check_str(ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh), 0, + &(ss->enforce_fingerprints))) { - ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(server->e); - int resp_constructed = 0; + ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(server->e); + int resp_constructed = 0; - uint16_t method = stun_get_method_str(ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh)); + uint16_t method = + stun_get_method_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh)); - handle_turn_command(server, ss, in_buffer, nbh, &resp_constructed, can_resume); + handle_turn_command(server, ss, in_buffer, nbh, &resp_constructed, can_resume); - if((method != STUN_METHOD_BINDING) && (method != STUN_METHOD_SEND)) - report_turn_session_info(server,ss,0); + if ((method != STUN_METHOD_BINDING) && (method != STUN_METHOD_SEND)) + report_turn_session_info(server, ss, 0); - if(ss->to_be_closed || ioa_socket_tobeclosed(ss->client_socket)) { - FUNCEND; - ioa_network_buffer_delete(server->e, nbh); - return 0; - } + if (ss->to_be_closed || ioa_socket_tobeclosed(ss->client_socket)) { + FUNCEND; + ioa_network_buffer_delete(server->e, nbh); + return 0; + } - if (resp_constructed) { + if (resp_constructed) { - if ((server->fingerprint) || ss->enforce_fingerprints) { - size_t len = ioa_network_buffer_get_size(nbh); - if (stun_attr_add_fingerprint_str(ioa_network_buffer_data(nbh), &len) < 0) { - FUNCEND ; - ioa_network_buffer_delete(server->e, nbh); - return -1; - } - ioa_network_buffer_set_size(nbh, len); - } + if ((server->fingerprint) || ss->enforce_fingerprints) { + size_t len = ioa_network_buffer_get_size(nbh); + if (stun_attr_add_fingerprint_str(ioa_network_buffer_data(nbh), &len) < 0) { + FUNCEND; + ioa_network_buffer_delete(server->e, nbh); + return -1; + } + ioa_network_buffer_set_size(nbh, len); + } - int ret = write_client_connection(server, ss, nbh, TTL_IGNORE, TOS_IGNORE); + int ret = write_client_connection(server, ss, nbh, TTL_IGNORE, TOS_IGNORE); - FUNCEND ; - return ret; - } else { - ioa_network_buffer_delete(server->e, nbh); - return 0; - } + FUNCEND; + return ret; + } else { + ioa_network_buffer_delete(server->e, nbh); + return 0; + } - } else if ( - old_stun_is_command_message_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), &old_stun_cookie) && - !(*(server->no_stun)) && - !(*(server->no_stun_backward_compatibility)) - ) { + } else if (old_stun_is_command_message_str(ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh), &old_stun_cookie) && + !(*(server->no_stun)) && !(*(server->no_stun_backward_compatibility))) { - ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(server->e); - int resp_constructed = 0; + ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(server->e); + int resp_constructed = 0; - handle_old_stun_command(server, ss, in_buffer, nbh, &resp_constructed, old_stun_cookie); + handle_old_stun_command(server, ss, in_buffer, nbh, &resp_constructed, old_stun_cookie); - if (resp_constructed) { + if (resp_constructed) { - int ret = write_client_connection(server, ss, nbh, TTL_IGNORE, TOS_IGNORE); + int ret = write_client_connection(server, ss, nbh, TTL_IGNORE, TOS_IGNORE); - FUNCEND ; - return ret; - } else { - ioa_network_buffer_delete(server->e, nbh); - return 0; - } - } else { - SOCKET_TYPE st = get_ioa_socket_type(ss->client_socket); - if(is_stream_socket(st)) { - if(is_http((char*)ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh))) { + FUNCEND; + return ret; + } else { + ioa_network_buffer_delete(server->e, nbh); + return 0; + } + } else { + SOCKET_TYPE st = get_ioa_socket_type(ss->client_socket); + if (is_stream_socket(st)) { + if (is_http((char *)ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh))) { - const char *proto = "HTTP"; - if ((st == TCP_SOCKET) && - ( - try_acme_redirect( - (char*)ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - server->acme_redirect, - ss->client_socket - ) == 0 - ) - ) { - ss->to_be_closed = 1; - return 0; - } else if (*server->web_admin_listen_on_workers) { - if(st==TLS_SOCKET) { - proto = "HTTPS"; - set_ioa_socket_app_type(ss->client_socket,HTTPS_CLIENT_SOCKET); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %zu\n", __FUNCTION__, proto, get_ioa_socket_cipher(ss->client_socket), get_ioa_socket_ssl_method(ss->client_socket), ioa_network_buffer_get_size(in_buffer->nbh)); - if(server->send_https_socket) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s socket to be detached: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)ss->client_socket, get_ioa_socket_type(ss->client_socket), get_ioa_socket_app_type(ss->client_socket)); - ioa_socket_handle new_s = detach_ioa_socket(ss->client_socket); - if(new_s) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s new detached socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)new_s, get_ioa_socket_type(new_s), get_ioa_socket_app_type(new_s)); - server->send_https_socket(new_s); - } - ss->to_be_closed = 1; - } - } else { - set_ioa_socket_app_type(ss->client_socket,HTTP_CLIENT_SOCKET); - if(server->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s request: %zu\n", __FUNCTION__, proto, ioa_network_buffer_get_size(in_buffer->nbh)); - } - handle_http_echo(ss->client_socket); - } - return 0; - } else { - ss->to_be_closed = 1; - return 0; - } - } - } - } - - //Unrecognized message received, ignore it + const char *proto = "HTTP"; + if ((st == TCP_SOCKET) && (try_acme_redirect((char *)ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh), server->acme_redirect, + ss->client_socket) == 0)) { + ss->to_be_closed = 1; + return 0; + } else if (*server->web_admin_listen_on_workers) { + if (st == TLS_SOCKET) { + proto = "HTTPS"; + set_ioa_socket_app_type(ss->client_socket, HTTPS_CLIENT_SOCKET); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %zu\n", __FUNCTION__, proto, + get_ioa_socket_cipher(ss->client_socket), get_ioa_socket_ssl_method(ss->client_socket), + ioa_network_buffer_get_size(in_buffer->nbh)); + if (server->send_https_socket) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s socket to be detached: 0x%lx, st=%d, sat=%d\n", __FUNCTION__, + (long)ss->client_socket, get_ioa_socket_type(ss->client_socket), + get_ioa_socket_app_type(ss->client_socket)); + ioa_socket_handle new_s = detach_ioa_socket(ss->client_socket); + if (new_s) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s new detached socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__, + (long)new_s, get_ioa_socket_type(new_s), get_ioa_socket_app_type(new_s)); + server->send_https_socket(new_s); + } + ss->to_be_closed = 1; + } + } else { + set_ioa_socket_app_type(ss->client_socket, HTTP_CLIENT_SOCKET); + if (server->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s request: %zu\n", __FUNCTION__, proto, + ioa_network_buffer_get_size(in_buffer->nbh)); + } + handle_http_echo(ss->client_socket); + } + return 0; + } else { + ss->to_be_closed = 1; + return 0; + } + } + } + } - FUNCEND; - return -1; + // Unrecognized message received, ignore it + + FUNCEND; + return -1; } -static int attach_socket_to_session(turn_turnserver* server, ioa_socket_handle s, ts_ur_super_session* ss) { +static int attach_socket_to_session(turn_turnserver *server, ioa_socket_handle s, ts_ur_super_session *ss) { - int ret = -1; - FUNCSTART; + int ret = -1; + FUNCSTART; - if(s && server && ss && !ioa_socket_tobeclosed(s)) { + if (s && server && ss && !ioa_socket_tobeclosed(s)) { - if(ss->client_socket != s) { + if (ss->client_socket != s) { - IOA_CLOSE_SOCKET(ss->client_socket); + IOA_CLOSE_SOCKET(ss->client_socket); - ss->client_socket = s; + ss->client_socket = s; - if(register_callback_on_ioa_socket(server->e, s, IOA_EV_READ, - client_input_handler, ss, 0)<0) { - return -1; - } + if (register_callback_on_ioa_socket(server->e, s, IOA_EV_READ, client_input_handler, ss, 0) < 0) { + return -1; + } - set_ioa_socket_session(s, ss); - } + set_ioa_socket_session(s, ss); + } - ret = 0; - } + ret = 0; + } - FUNCEND; - return ret; + FUNCEND; + return ret; } -int open_client_connection_session(turn_turnserver* server, - struct socket_message *sm) { - int ret = 0; - FUNCSTART; - if (!server) - return -1; +int open_client_connection_session(turn_turnserver *server, struct socket_message *sm) { + int ret = 0; + FUNCSTART; + if (!server) + return -1; - if (!(sm->s)) - return -1; + if (!(sm->s)) + return -1; - ts_ur_super_session* ss = create_new_ss(server); + ts_ur_super_session *ss = create_new_ss(server); - ss->client_socket = sm->s; + ss->client_socket = sm->s; - if(register_callback_on_ioa_socket(server->e, ss->client_socket, IOA_EV_READ, - client_input_handler, ss, 0)<0) { - ret = -1; - } + if (register_callback_on_ioa_socket(server->e, ss->client_socket, IOA_EV_READ, client_input_handler, ss, 0) < 0) { + ret = -1; + } - set_ioa_socket_session(ss->client_socket, ss); + set_ioa_socket_session(ss->client_socket, ss); - int at = TURN_MAX_ALLOCATE_TIMEOUT; - if(*(server->stun_only)) - at = TURN_MAX_ALLOCATE_TIMEOUT_STUN_ONLY; + int at = TURN_MAX_ALLOCATE_TIMEOUT; + if (*(server->stun_only)) + at = TURN_MAX_ALLOCATE_TIMEOUT_STUN_ONLY; - IOA_EVENT_DEL(ss->to_be_allocated_timeout_ev); - ss->to_be_allocated_timeout_ev = set_ioa_timer(server->e, - at, 0, - client_to_be_allocated_timeout_handler, ss, 1, - "client_to_be_allocated_timeout_handler"); + IOA_EVENT_DEL(ss->to_be_allocated_timeout_ev); + ss->to_be_allocated_timeout_ev = set_ioa_timer(server->e, at, 0, client_to_be_allocated_timeout_handler, ss, 1, + "client_to_be_allocated_timeout_handler"); - if(sm->nd.nbh) { - client_input_handler(ss->client_socket,IOA_EV_READ,&(sm->nd),ss,sm->can_resume); - ioa_network_buffer_delete(server->e, sm->nd.nbh); - sm->nd.nbh = NULL; - } + if (sm->nd.nbh) { + client_input_handler(ss->client_socket, IOA_EV_READ, &(sm->nd), ss, sm->can_resume); + ioa_network_buffer_delete(server->e, sm->nd.nbh); + sm->nd.nbh = NULL; + } - FUNCEND; + FUNCEND; - return ret; + return ret; } /////////////// io handlers /////////////////// -static void peer_input_handler(ioa_socket_handle s, int event_type, - ioa_net_data *in_buffer, void *arg, int can_resume) { +static void peer_input_handler(ioa_socket_handle s, int event_type, ioa_net_data *in_buffer, void *arg, + int can_resume) { - if (!(event_type & IOA_EV_READ) || !arg) return; + if (!(event_type & IOA_EV_READ) || !arg) + return; - if(in_buffer->recv_ttl==0) return; + if (in_buffer->recv_ttl == 0) + return; - UNUSED_ARG(can_resume); + UNUSED_ARG(can_resume); - if(!s || ioa_socket_tobeclosed(s)) return; + if (!s || ioa_socket_tobeclosed(s)) + return; - ts_ur_super_session* ss = (ts_ur_super_session*) arg; + ts_ur_super_session *ss = (ts_ur_super_session *)arg; - if(!ss) return; + if (!ss) + return; - if(ss->to_be_closed) return; + if (ss->to_be_closed) + return; - if(!(ss->client_socket) || ioa_socket_tobeclosed(ss->client_socket)) return; + if (!(ss->client_socket) || ioa_socket_tobeclosed(ss->client_socket)) + return; - turn_turnserver *server = (turn_turnserver*) (ss->server); + turn_turnserver *server = (turn_turnserver *)(ss->server); - if (!server) return; + if (!server) + return; - relay_endpoint_session* elem = get_relay_session_ss(ss, get_ioa_socket_address_family(s)); - if (elem->s == NULL) { - return; - } + relay_endpoint_session *elem = get_relay_session_ss(ss, get_ioa_socket_address_family(s)); + if (elem->s == NULL) { + return; + } - int offset = STUN_CHANNEL_HEADER_LENGTH; + int offset = STUN_CHANNEL_HEADER_LENGTH; - int ilen = min((int)ioa_network_buffer_get_size(in_buffer->nbh), - (int)(ioa_network_buffer_get_capacity_udp() - offset)); + int ilen = + min((int)ioa_network_buffer_get_size(in_buffer->nbh), (int)(ioa_network_buffer_get_capacity_udp() - offset)); - if (ilen >= 0) { - ++(ss->peer_received_packets); - ss->peer_received_bytes += ilen; - turn_report_session_usage(ss, 0); + if (ilen >= 0) { + ++(ss->peer_received_packets); + ss->peer_received_bytes += ilen; + turn_report_session_usage(ss, 0); - allocation* a = get_allocation_ss(ss); - if (is_allocation_valid(a)) { + allocation *a = get_allocation_ss(ss); + if (is_allocation_valid(a)) { - uint16_t chnum = 0; + uint16_t chnum = 0; - ioa_network_buffer_handle nbh = NULL; + ioa_network_buffer_handle nbh = NULL; - turn_permission_info* tinfo = allocation_get_permission(a, - &(in_buffer->src_addr)); - if (tinfo) { - chnum = get_turn_channel_number(tinfo, &(in_buffer->src_addr)); - } else if(!(server->server_relay)) { - return; - } + turn_permission_info *tinfo = allocation_get_permission(a, &(in_buffer->src_addr)); + if (tinfo) { + chnum = get_turn_channel_number(tinfo, &(in_buffer->src_addr)); + } else if (!(server->server_relay)) { + return; + } - if (chnum) { + if (chnum) { - size_t len = (size_t)(ilen); + size_t len = (size_t)(ilen); - nbh = in_buffer->nbh; + nbh = in_buffer->nbh; - ioa_network_buffer_add_offset_size(nbh, - 0, - STUN_CHANNEL_HEADER_LENGTH, - ioa_network_buffer_get_size(nbh)+STUN_CHANNEL_HEADER_LENGTH); + ioa_network_buffer_add_offset_size(nbh, 0, STUN_CHANNEL_HEADER_LENGTH, + ioa_network_buffer_get_size(nbh) + STUN_CHANNEL_HEADER_LENGTH); - ioa_network_buffer_header_init(nbh); + ioa_network_buffer_header_init(nbh); - SOCKET_TYPE st = get_ioa_socket_type(ss->client_socket); - int do_padding = is_stream_socket(st); + SOCKET_TYPE st = get_ioa_socket_type(ss->client_socket); + int do_padding = is_stream_socket(st); - stun_init_channel_message_str(chnum, ioa_network_buffer_data(nbh), &len, len, do_padding); - ioa_network_buffer_set_size(nbh,len); - in_buffer->nbh = NULL; - if (eve(server->verbose)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "%s: send channel 0x%x\n", __FUNCTION__, - (int) (chnum)); - } - } else { + stun_init_channel_message_str(chnum, ioa_network_buffer_data(nbh), &len, len, do_padding); + ioa_network_buffer_set_size(nbh, len); + in_buffer->nbh = NULL; + if (eve(server->verbose)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: send channel 0x%x\n", __FUNCTION__, (int)(chnum)); + } + } else { - size_t len = 0; + size_t len = 0; - nbh = ioa_network_buffer_allocate(server->e); - stun_init_indication_str(STUN_METHOD_DATA, ioa_network_buffer_data(nbh), &len); - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_DATA, - ioa_network_buffer_data(in_buffer->nbh), (size_t)ilen); - stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, - STUN_ATTRIBUTE_XOR_PEER_ADDRESS, - &(in_buffer->src_addr)); - ioa_network_buffer_set_size(nbh,len); + nbh = ioa_network_buffer_allocate(server->e); + stun_init_indication_str(STUN_METHOD_DATA, ioa_network_buffer_data(nbh), &len); + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_DATA, + ioa_network_buffer_data(in_buffer->nbh), (size_t)ilen); + stun_attr_add_addr_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, + &(in_buffer->src_addr)); + ioa_network_buffer_set_size(nbh, len); - if(!(*server->no_software_attribute)) - { - const uint8_t *field = (const uint8_t *) get_version(server); - size_t fsz = strlen(get_version(server)); - size_t len = ioa_network_buffer_get_size(nbh); - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_SOFTWARE, field, fsz); - ioa_network_buffer_set_size(nbh, len); - } + if (!(*server->no_software_attribute)) { + const uint8_t *field = (const uint8_t *)get_version(server); + size_t fsz = strlen(get_version(server)); + size_t len = ioa_network_buffer_get_size(nbh); + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_SOFTWARE, field, fsz); + ioa_network_buffer_set_size(nbh, len); + } - if ((server->fingerprint) || ss->enforce_fingerprints) { - size_t len = ioa_network_buffer_get_size(nbh); - stun_attr_add_fingerprint_str(ioa_network_buffer_data(nbh), &len); - ioa_network_buffer_set_size(nbh, len); - } - } - if (eve(server->verbose)) { - uint16_t* t = (uint16_t*) ioa_network_buffer_data(nbh); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Send data: 0x%x\n", - (int) (nswap16(t[0]))); - } + if ((server->fingerprint) || ss->enforce_fingerprints) { + size_t len = ioa_network_buffer_get_size(nbh); + stun_attr_add_fingerprint_str(ioa_network_buffer_data(nbh), &len); + ioa_network_buffer_set_size(nbh, len); + } + } + if (eve(server->verbose)) { + uint16_t *t = (uint16_t *)ioa_network_buffer_data(nbh); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Send data: 0x%x\n", (int)(nswap16(t[0]))); + } - write_client_connection(server, ss, nbh, in_buffer->recv_ttl-1, in_buffer->recv_tos); - } - } + write_client_connection(server, ss, nbh, in_buffer->recv_ttl - 1, in_buffer->recv_tos); + } + } } -static void client_input_handler(ioa_socket_handle s, int event_type, - ioa_net_data *data, void *arg, int can_resume) { +static void client_input_handler(ioa_socket_handle s, int event_type, ioa_net_data *data, void *arg, int can_resume) { - if (!arg) - return; + if (!arg) + return; - UNUSED_ARG(s); - UNUSED_ARG(event_type); + UNUSED_ARG(s); + UNUSED_ARG(event_type); - ts_ur_super_session* ss = (ts_ur_super_session*)arg; + ts_ur_super_session *ss = (ts_ur_super_session *)arg; - turn_turnserver *server = (turn_turnserver*)ss->server; + turn_turnserver *server = (turn_turnserver *)ss->server; - if (!server) { - return; - } + if (!server) { + return; + } - if (ss->client_socket != s) { - return; - } + if (ss->client_socket != s) { + return; + } - read_client_connection(server, ss, data, can_resume, 1); + read_client_connection(server, ss, data, can_resume, 1); - if (ss->to_be_closed) { - if(server->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, - "session %018llu: client socket to be closed in client handler: ss=0x%lx\n", (unsigned long long)(ss->id), (long)ss); - } - set_ioa_socket_tobeclosed(s); - } + if (ss->to_be_closed) { + if (server->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "session %018llu: client socket to be closed in client handler: ss=0x%lx\n", + (unsigned long long)(ss->id), (long)ss); + } + set_ioa_socket_tobeclosed(s); + } } /////////////////////////////////////////////////////////// -void init_turn_server(turn_turnserver* server, - turnserver_id id, int verbose, ioa_engine_handle e, turn_credential_type ct, - int stun_port, int fingerprint, dont_fragment_option_t dont_fragment, - get_user_key_cb userkeycb, - check_new_allocation_quota_cb chquotacb, - release_allocation_quota_cb raqcb, - ioa_addr *external_ip, - vintp check_origin, - vintp no_tcp_relay, - vintp no_udp_relay, - vintp stale_nonce, - vintp max_allocate_lifetime, - vintp channel_lifetime, - vintp permission_lifetime, - vintp stun_only, - vintp no_stun, - vintp no_software_attribute, - vintp web_admin_listen_on_workers, - turn_server_addrs_list_t *alternate_servers_list, - turn_server_addrs_list_t *tls_alternate_servers_list, - turn_server_addrs_list_t *aux_servers_list, - int self_udp_balance, - vintp no_multicast_peers, vintp allow_loopback_peers, - ip_range_list_t* ip_whitelist, ip_range_list_t* ip_blacklist, - send_socket_to_relay_cb send_socket_to_relay, - vintp secure_stun, vintp mobility, int server_relay, - send_turn_session_info_cb send_turn_session_info, - send_https_socket_cb send_https_socket, - allocate_bps_cb allocate_bps_func, - int oauth, - const char* oauth_server_name, - const char* acme_redirect, - ALLOCATION_DEFAULT_ADDRESS_FAMILY allocation_default_address_family, - vintp log_binding, - vintp no_stun_backward_compatibility, - vintp response_origin_only_with_rfc5780) { +void init_turn_server(turn_turnserver *server, turnserver_id id, int verbose, ioa_engine_handle e, + turn_credential_type ct, int stun_port, int fingerprint, dont_fragment_option_t dont_fragment, + get_user_key_cb userkeycb, check_new_allocation_quota_cb chquotacb, + release_allocation_quota_cb raqcb, ioa_addr *external_ip, vintp check_origin, vintp no_tcp_relay, + vintp no_udp_relay, vintp stale_nonce, vintp max_allocate_lifetime, vintp channel_lifetime, + vintp permission_lifetime, vintp stun_only, vintp no_stun, vintp no_software_attribute, + vintp web_admin_listen_on_workers, turn_server_addrs_list_t *alternate_servers_list, + turn_server_addrs_list_t *tls_alternate_servers_list, turn_server_addrs_list_t *aux_servers_list, + int self_udp_balance, vintp no_multicast_peers, vintp allow_loopback_peers, + ip_range_list_t *ip_whitelist, ip_range_list_t *ip_blacklist, + send_socket_to_relay_cb send_socket_to_relay, vintp secure_stun, vintp mobility, int server_relay, + send_turn_session_info_cb send_turn_session_info, send_https_socket_cb send_https_socket, + allocate_bps_cb allocate_bps_func, int oauth, const char *oauth_server_name, + const char *acme_redirect, ALLOCATION_DEFAULT_ADDRESS_FAMILY allocation_default_address_family, + vintp log_binding, vintp no_stun_backward_compatibility, + vintp response_origin_only_with_rfc5780) { - if (!server) - return; + if (!server) + return; - memset(server, 0, sizeof(turn_turnserver)); + memset(server, 0, sizeof(turn_turnserver)); - server->e = e; - server->id = id; - server->ctime = turn_time(); - server->session_id_counter = 0; - server->sessions_map = ur_map_create(); - server->tcp_relay_connections = ur_map_create(); - server->ct = ct; - server->userkeycb = userkeycb; - server->chquotacb = chquotacb; - server->raqcb = raqcb; - server->no_multicast_peers = no_multicast_peers; - server->allow_loopback_peers = allow_loopback_peers; - server->secure_stun = secure_stun; - server->mobility = mobility; - server->server_relay = server_relay; - server->send_turn_session_info = send_turn_session_info; - server->send_https_socket = send_https_socket; - server->oauth = oauth; - if(oauth) - server->oauth_server_name = oauth_server_name; - if(mobility) - server->mobile_connections_map = ur_map_create(); - server->acme_redirect = acme_redirect; + server->e = e; + server->id = id; + server->ctime = turn_time(); + server->session_id_counter = 0; + server->sessions_map = ur_map_create(); + server->tcp_relay_connections = ur_map_create(); + server->ct = ct; + server->userkeycb = userkeycb; + server->chquotacb = chquotacb; + server->raqcb = raqcb; + server->no_multicast_peers = no_multicast_peers; + server->allow_loopback_peers = allow_loopback_peers; + server->secure_stun = secure_stun; + server->mobility = mobility; + server->server_relay = server_relay; + server->send_turn_session_info = send_turn_session_info; + server->send_https_socket = send_https_socket; + server->oauth = oauth; + if (oauth) + server->oauth_server_name = oauth_server_name; + if (mobility) + server->mobile_connections_map = ur_map_create(); + server->acme_redirect = acme_redirect; - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"turn server id=%d created\n",(int)id); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "turn server id=%d created\n", (int)id); - server->check_origin = check_origin; - server->no_tcp_relay = no_tcp_relay; - server->no_udp_relay = no_udp_relay; + server->check_origin = check_origin; + server->no_tcp_relay = no_tcp_relay; + server->no_udp_relay = no_udp_relay; - server->alternate_servers_list = alternate_servers_list; - server->tls_alternate_servers_list = tls_alternate_servers_list; - server->aux_servers_list = aux_servers_list; - server->self_udp_balance = self_udp_balance; + server->alternate_servers_list = alternate_servers_list; + server->tls_alternate_servers_list = tls_alternate_servers_list; + server->aux_servers_list = aux_servers_list; + server->self_udp_balance = self_udp_balance; - server->stale_nonce = stale_nonce; - server->max_allocate_lifetime = max_allocate_lifetime; - server->channel_lifetime = channel_lifetime; - server->permission_lifetime = permission_lifetime; - server->stun_only = stun_only; - server->no_stun = no_stun; - server->no_software_attribute = no_software_attribute; - server-> web_admin_listen_on_workers = web_admin_listen_on_workers; + server->stale_nonce = stale_nonce; + server->max_allocate_lifetime = max_allocate_lifetime; + server->channel_lifetime = channel_lifetime; + server->permission_lifetime = permission_lifetime; + server->stun_only = stun_only; + server->no_stun = no_stun; + server->no_software_attribute = no_software_attribute; + server->web_admin_listen_on_workers = web_admin_listen_on_workers; - server->dont_fragment = dont_fragment; - server->fingerprint = fingerprint; - if(external_ip) { - addr_cpy(&(server->external_ip), external_ip); - server->external_ip_set = 1; - } - if (stun_port < 1) - stun_port = DEFAULT_STUN_PORT; + server->dont_fragment = dont_fragment; + server->fingerprint = fingerprint; + if (external_ip) { + addr_cpy(&(server->external_ip), external_ip); + server->external_ip_set = 1; + } + if (stun_port < 1) + stun_port = DEFAULT_STUN_PORT; - server->verbose = verbose; + server->verbose = verbose; - server->ip_whitelist = ip_whitelist; - server->ip_blacklist = ip_blacklist; + server->ip_whitelist = ip_whitelist; + server->ip_blacklist = ip_blacklist; - server->send_socket_to_relay = send_socket_to_relay; + server->send_socket_to_relay = send_socket_to_relay; - server->allocate_bps_func = allocate_bps_func; + server->allocate_bps_func = allocate_bps_func; - server->allocation_default_address_family = allocation_default_address_family; + server->allocation_default_address_family = allocation_default_address_family; - set_ioa_timer(server->e, 1, 0, timer_timeout_handler, server, 1, "timer_timeout_handler"); + set_ioa_timer(server->e, 1, 0, timer_timeout_handler, server, 1, "timer_timeout_handler"); - server->log_binding = log_binding; + server->log_binding = log_binding; - server->no_stun_backward_compatibility = no_stun_backward_compatibility; + server->no_stun_backward_compatibility = no_stun_backward_compatibility; - server->response_origin_only_with_rfc5780 = response_origin_only_with_rfc5780; + server->response_origin_only_with_rfc5780 = response_origin_only_with_rfc5780; } ioa_engine_handle turn_server_get_engine(turn_turnserver *s) { - if(s) - return s->e; - return NULL; + if (s) + return s->e; + return NULL; } -void set_disconnect_cb(turn_turnserver* server, int(*disconnect)( - ts_ur_super_session*)) { - server->disconnect = disconnect; +void set_disconnect_cb(turn_turnserver *server, int (*disconnect)(ts_ur_super_session *)) { + server->disconnect = disconnect; } ////////////////////////////////////////////////////////////////// diff --git a/src/server/ns_turn_server.h b/src/server/ns_turn_server.h index 4e86842..332dfac 100644 --- a/src/server/ns_turn_server.h +++ b/src/server/ns_turn_server.h @@ -31,8 +31,8 @@ #ifndef __TURN_SERVER__ #define __TURN_SERVER__ -#include "ns_turn_utils.h" #include "ns_turn_session.h" +#include "ns_turn_utils.h" #ifdef __cplusplus extern "C" { @@ -45,9 +45,9 @@ extern "C" { //////////// ALTERNATE-SERVER ///////////// struct _turn_server_addrs_list { - ioa_addr *addrs; - volatile size_t size; - TURN_MUTEX_DECLARE(m) + ioa_addr *addrs; + volatile size_t size; + TURN_MUTEX_DECLARE(m) }; typedef struct _turn_server_addrs_list turn_server_addrs_list_t; @@ -57,7 +57,8 @@ void init_turn_server_addrs_list(turn_server_addrs_list_t *l); ////////// RFC 5780 /////////////////////// typedef int (*get_alt_addr_cb)(ioa_addr *addr, ioa_addr *alt_addr); -typedef int (*send_message_cb)(ioa_engine_handle e, ioa_network_buffer_handle nbh, ioa_addr *origin, ioa_addr *destination); +typedef int (*send_message_cb)(ioa_engine_handle e, ioa_network_buffer_handle nbh, ioa_addr *origin, + ioa_addr *destination); ////////////////////////////////////////// @@ -66,43 +67,43 @@ extern int TURN_MAX_ALLOCATE_TIMEOUT_STUN_ONLY; typedef uint8_t turnserver_id; -enum _MESSAGE_TO_RELAY_TYPE { - RMT_UNKNOWN = 0, - RMT_SOCKET, - RMT_CB_SOCKET, - RMT_MOBILE_SOCKET, - RMT_CANCEL_SESSION -}; +enum _MESSAGE_TO_RELAY_TYPE { RMT_UNKNOWN = 0, RMT_SOCKET, RMT_CB_SOCKET, RMT_MOBILE_SOCKET, RMT_CANCEL_SESSION }; typedef enum _MESSAGE_TO_RELAY_TYPE MESSAGE_TO_RELAY_TYPE; ///////// ALLOCATION DEFAULT ADDRESS FAMILY TYPES ///////////////////// enum _ALLOCATION_DEFAULT_ADDRESS_FAMILY { - ALLOCATION_DEFAULT_ADDRESS_FAMILY_IPV4 = 0, - ALLOCATION_DEFAULT_ADDRESS_FAMILY_IPV6, - ALLOCATION_DEFAULT_ADDRESS_FAMILY_KEEP, + ALLOCATION_DEFAULT_ADDRESS_FAMILY_IPV4 = 0, + ALLOCATION_DEFAULT_ADDRESS_FAMILY_IPV6, + ALLOCATION_DEFAULT_ADDRESS_FAMILY_KEEP, }; typedef enum _ALLOCATION_DEFAULT_ADDRESS_FAMILY ALLOCATION_DEFAULT_ADDRESS_FAMILY; struct socket_message { - ioa_socket_handle s; - ioa_net_data nd; - int can_resume; + ioa_socket_handle s; + ioa_net_data nd; + int can_resume; }; typedef enum { - DONT_FRAGMENT_UNSUPPORTED=0, - DONT_FRAGMENT_SUPPORTED, - DONT_FRAGMENT_SUPPORT_EMULATED + DONT_FRAGMENT_UNSUPPORTED = 0, + DONT_FRAGMENT_SUPPORTED, + DONT_FRAGMENT_SUPPORT_EMULATED } dont_fragment_option_t; struct _turn_turnserver; typedef struct _turn_turnserver turn_turnserver; -typedef void (*get_username_resume_cb)(int success, int oauth, int max_session_time, hmackey_t hmackey, password_t pwd, turn_turnserver *server, uint64_t ctxkey, ioa_net_data *in_buffer, uint8_t* realm); -typedef uint8_t *(*get_user_key_cb)(turnserver_id id, turn_credential_type ct, int in_oauth, int *out_oauth, uint8_t *uname, uint8_t *realm, get_username_resume_cb resume, ioa_net_data *in_buffer, uint64_t ctxkey, int *postpone_reply); +typedef void (*get_username_resume_cb)(int success, int oauth, int max_session_time, hmackey_t hmackey, password_t pwd, + turn_turnserver *server, uint64_t ctxkey, ioa_net_data *in_buffer, + uint8_t *realm); +typedef uint8_t *(*get_user_key_cb)(turnserver_id id, turn_credential_type ct, int in_oauth, int *out_oauth, + uint8_t *uname, uint8_t *realm, get_username_resume_cb resume, + ioa_net_data *in_buffer, uint64_t ctxkey, int *postpone_reply); typedef int (*check_new_allocation_quota_cb)(uint8_t *username, int oauth, uint8_t *realm); typedef void (*release_allocation_quota_cb)(uint8_t *username, int oauth, uint8_t *realm); -typedef int (*send_socket_to_relay_cb)(turnserver_id id, uint64_t cid, stun_tid *tid, ioa_socket_handle s, int message_integrity, MESSAGE_TO_RELAY_TYPE rmt, ioa_net_data *nd, int can_resume); +typedef int (*send_socket_to_relay_cb)(turnserver_id id, uint64_t cid, stun_tid *tid, ioa_socket_handle s, + int message_integrity, MESSAGE_TO_RELAY_TYPE rmt, ioa_net_data *nd, + int can_resume); typedef int (*send_turn_session_info_cb)(struct turn_session_info *tsi); typedef void (*send_https_socket_cb)(ioa_socket_handle s); @@ -110,140 +111,111 @@ typedef band_limit_t (*allocate_bps_cb)(band_limit_t bps, int positive); struct _turn_turnserver { - turnserver_id id; + turnserver_id id; - turnsession_id session_id_counter; - ur_map *sessions_map; + turnsession_id session_id_counter; + ur_map *sessions_map; - turn_time_t ctime; + turn_time_t ctime; - ioa_engine_handle e; - int verbose; - int fingerprint; - int rfc5780; - vintp check_origin; - vintp stale_nonce; - vintp max_allocate_lifetime; - vintp channel_lifetime; - vintp permission_lifetime; - vintp stun_only; - vintp no_stun; - vintp no_software_attribute; - vintp web_admin_listen_on_workers; - vintp secure_stun; - turn_credential_type ct; - get_alt_addr_cb alt_addr_cb; - send_message_cb sm_cb; - dont_fragment_option_t dont_fragment; - int (*disconnect)(ts_ur_super_session*); - get_user_key_cb userkeycb; - check_new_allocation_quota_cb chquotacb; - release_allocation_quota_cb raqcb; - int external_ip_set; - ioa_addr external_ip; - vintp allow_loopback_peers; - vintp no_multicast_peers; - send_turn_session_info_cb send_turn_session_info; - send_https_socket_cb send_https_socket; + ioa_engine_handle e; + int verbose; + int fingerprint; + int rfc5780; + vintp check_origin; + vintp stale_nonce; + vintp max_allocate_lifetime; + vintp channel_lifetime; + vintp permission_lifetime; + vintp stun_only; + vintp no_stun; + vintp no_software_attribute; + vintp web_admin_listen_on_workers; + vintp secure_stun; + turn_credential_type ct; + get_alt_addr_cb alt_addr_cb; + send_message_cb sm_cb; + dont_fragment_option_t dont_fragment; + int (*disconnect)(ts_ur_super_session *); + get_user_key_cb userkeycb; + check_new_allocation_quota_cb chquotacb; + release_allocation_quota_cb raqcb; + int external_ip_set; + ioa_addr external_ip; + vintp allow_loopback_peers; + vintp no_multicast_peers; + send_turn_session_info_cb send_turn_session_info; + send_https_socket_cb send_https_socket; - /* RFC 6062 ==>> */ - vintp no_udp_relay; - vintp no_tcp_relay; - ur_map *tcp_relay_connections; - send_socket_to_relay_cb send_socket_to_relay; - /* <<== RFC 6062 */ + /* RFC 6062 ==>> */ + vintp no_udp_relay; + vintp no_tcp_relay; + ur_map *tcp_relay_connections; + send_socket_to_relay_cb send_socket_to_relay; + /* <<== RFC 6062 */ - /* Alternate servers ==>> */ - turn_server_addrs_list_t *alternate_servers_list; - size_t as_counter; - turn_server_addrs_list_t *tls_alternate_servers_list; - size_t tls_as_counter; - turn_server_addrs_list_t *aux_servers_list; - int self_udp_balance; + /* Alternate servers ==>> */ + turn_server_addrs_list_t *alternate_servers_list; + size_t as_counter; + turn_server_addrs_list_t *tls_alternate_servers_list; + size_t tls_as_counter; + turn_server_addrs_list_t *aux_servers_list; + int self_udp_balance; - /* White/black listing of address ranges */ - ip_range_list_t* ip_whitelist; - ip_range_list_t* ip_blacklist; + /* White/black listing of address ranges */ + ip_range_list_t *ip_whitelist; + ip_range_list_t *ip_blacklist; - /* Mobility */ - vintp mobility; - ur_map *mobile_connections_map; + /* Mobility */ + vintp mobility; + ur_map *mobile_connections_map; - /* Server relay */ - int server_relay; + /* Server relay */ + int server_relay; - /* Bandwidth draft: */ - allocate_bps_cb allocate_bps_func; + /* Bandwidth draft: */ + allocate_bps_cb allocate_bps_func; - /* oAuth: */ - int oauth; - const char* oauth_server_name; + /* oAuth: */ + int oauth; + const char *oauth_server_name; - /* ACME redirect URL */ - const char* acme_redirect; + /* ACME redirect URL */ + const char *acme_redirect; - /* Allocation Default Address Family */ - ALLOCATION_DEFAULT_ADDRESS_FAMILY allocation_default_address_family; + /* Allocation Default Address Family */ + ALLOCATION_DEFAULT_ADDRESS_FAMILY allocation_default_address_family; - /* Log Binding Requrest */ - vintp log_binding; + /* Log Binding Requrest */ + vintp log_binding; - /* Disable handling old STUN Binding Requests and disable MAPPED-ADDRESS attribute in response */ - vintp no_stun_backward_compatibility; + /* Disable handling old STUN Binding Requests and disable MAPPED-ADDRESS attribute in response */ + vintp no_stun_backward_compatibility; - /* Only send RESPONSE-ORIGIN attribute in response if RFC5780 is enabled */ - vintp response_origin_only_with_rfc5780; + /* Only send RESPONSE-ORIGIN attribute in response if RFC5780 is enabled */ + vintp response_origin_only_with_rfc5780; }; -const char * get_version(turn_turnserver *server); +const char *get_version(turn_turnserver *server); /////////////////////////////////////////// -void init_turn_server(turn_turnserver* server, - turnserver_id id, int verbose, - ioa_engine_handle e, - turn_credential_type ct, - int stun_port, - int fingerprint, - dont_fragment_option_t dont_fragment, - get_user_key_cb userkeycb, - check_new_allocation_quota_cb chquotacb, - release_allocation_quota_cb raqcb, - ioa_addr *external_addr, - vintp check_origin, - vintp no_tcp_relay, - vintp no_udp_relay, - vintp stale_nonce, - vintp max_allocate_lifetime, - vintp channel_lifetime, - vintp permission_lifetime, - vintp stun_only, - vintp no_stun, - vintp no_software_attribute, - vintp web_admin_listen_on_workers, - turn_server_addrs_list_t *alternate_servers_list, - turn_server_addrs_list_t *tls_alternate_servers_list, - turn_server_addrs_list_t *aux_servers_list, - int self_udp_balance, - vintp no_multicast_peers, - vintp allow_loopback_peers, - ip_range_list_t* ip_whitelist, - ip_range_list_t* ip_blacklist, - send_socket_to_relay_cb send_socket_to_relay, - vintp secure_stun, - vintp mobility, - int server_relay, - send_turn_session_info_cb send_turn_session_info, - send_https_socket_cb send_https_socket, - allocate_bps_cb allocate_bps_func, - int oauth, - const char* oauth_server_name, - const char* acme_redirect, - ALLOCATION_DEFAULT_ADDRESS_FAMILY allocation_default_address_family, - vintp log_binding, - vintp no_stun_backward_compatibility, - vintp response_origin_only_with_rfc5780 - ); +void init_turn_server(turn_turnserver *server, turnserver_id id, int verbose, ioa_engine_handle e, + turn_credential_type ct, int stun_port, int fingerprint, dont_fragment_option_t dont_fragment, + get_user_key_cb userkeycb, check_new_allocation_quota_cb chquotacb, + release_allocation_quota_cb raqcb, ioa_addr *external_addr, vintp check_origin, + vintp no_tcp_relay, vintp no_udp_relay, vintp stale_nonce, vintp max_allocate_lifetime, + vintp channel_lifetime, vintp permission_lifetime, vintp stun_only, vintp no_stun, + vintp no_software_attribute, vintp web_admin_listen_on_workers, + turn_server_addrs_list_t *alternate_servers_list, + turn_server_addrs_list_t *tls_alternate_servers_list, turn_server_addrs_list_t *aux_servers_list, + int self_udp_balance, vintp no_multicast_peers, vintp allow_loopback_peers, + ip_range_list_t *ip_whitelist, ip_range_list_t *ip_blacklist, + send_socket_to_relay_cb send_socket_to_relay, vintp secure_stun, vintp mobility, int server_relay, + send_turn_session_info_cb send_turn_session_info, send_https_socket_cb send_https_socket, + allocate_bps_cb allocate_bps_func, int oauth, const char *oauth_server_name, + const char *acme_redirect, ALLOCATION_DEFAULT_ADDRESS_FAMILY allocation_default_address_family, + vintp log_binding, vintp no_stun_backward_compatibility, vintp response_origin_only_with_rfc5780); ioa_engine_handle turn_server_get_engine(turn_turnserver *s); @@ -253,11 +225,13 @@ void set_rfc5780(turn_turnserver *server, get_alt_addr_cb cb, send_message_cb sm /////////////////////////////////////////// -int open_client_connection_session(turn_turnserver* server, struct socket_message *sm); -int shutdown_client_connection(turn_turnserver *server, ts_ur_super_session *ss, int force, const char* reason); -void set_disconnect_cb(turn_turnserver* server, int (*disconnect)(ts_ur_super_session*)); +int open_client_connection_session(turn_turnserver *server, struct socket_message *sm); +int shutdown_client_connection(turn_turnserver *server, ts_ur_super_session *ss, int force, const char *reason); +void set_disconnect_cb(turn_turnserver *server, int (*disconnect)(ts_ur_super_session *)); -int turnserver_accept_tcp_client_data_connection(turn_turnserver *server, tcp_connection_id tcid, stun_tid *tid, ioa_socket_handle s, int message_integrity, ioa_net_data *nd, int can_resume); +int turnserver_accept_tcp_client_data_connection(turn_turnserver *server, tcp_connection_id tcid, stun_tid *tid, + ioa_socket_handle s, int message_integrity, ioa_net_data *nd, + int can_resume); int report_turn_session_info(turn_turnserver *server, ts_ur_super_session *ss, int force_invalid); diff --git a/src/server/ns_turn_session.h b/src/server/ns_turn_session.h index 9d11444..a1cdab8 100644 --- a/src/server/ns_turn_session.h +++ b/src/server/ns_turn_session.h @@ -31,10 +31,10 @@ #ifndef __TURN_SESSION__ #define __TURN_SESSION__ -#include "ns_turn_utils.h" -#include "ns_turn_maps.h" -#include "ns_turn_ioalib.h" #include "ns_turn_allocation.h" +#include "ns_turn_ioalib.h" +#include "ns_turn_maps.h" +#include "ns_turn_utils.h" #ifdef __cplusplus extern "C" { @@ -44,29 +44,29 @@ extern "C" { typedef struct _perf_options_t { - volatile band_limit_t max_bps; - vint total_quota; - vint user_quota; + volatile band_limit_t max_bps; + vint total_quota; + vint user_quota; } perf_options_t; struct _realm_options_t { - char name[STUN_MAX_REALM_SIZE + 1]; + char name[STUN_MAX_REALM_SIZE + 1]; - perf_options_t perf_options; + perf_options_t perf_options; }; //////////////// session info ////////////////////// typedef uint64_t turnsession_id; -#define NONCE_MAX_SIZE (NONCE_LENGTH_32BITS*4+1) +#define NONCE_MAX_SIZE (NONCE_LENGTH_32BITS * 4 + 1) typedef uint64_t mobile_id_t; struct _ts_ur_super_session { - void* server; + void *server; turnsession_id id; turn_time_t start_time; ioa_socket_handle client_socket; @@ -78,7 +78,7 @@ struct _ts_ur_super_session { /* Auth */ uint8_t nonce[NONCE_MAX_SIZE]; turn_time_t nonce_expiration_time; - uint8_t username[STUN_MAX_USERNAME_SIZE+1]; + uint8_t username[STUN_MAX_USERNAME_SIZE + 1]; hmackey_t hmackey; int hmackey_set; password_t pwd; @@ -127,63 +127,63 @@ struct _ts_ur_super_session { #define TURN_MAIN_PEERS_ARRAY_SIZE (5) typedef struct _addr_data { - ioa_addr addr; - char saddr[TURN_ADDR_STR_SIZE]; + ioa_addr addr; + char saddr[TURN_ADDR_STR_SIZE]; } addr_data; struct turn_session_info { - turnsession_id id; - int valid; - turn_time_t start_time; - turn_time_t expiration_time; - SOCKET_TYPE client_protocol; - SOCKET_TYPE peer_protocol; - char tls_method[17]; - char tls_cipher[65]; - addr_data local_addr_data; - addr_data remote_addr_data; - addr_data relay_addr_data_ipv4; - addr_data relay_addr_data_ipv6; - uint8_t username[STUN_MAX_USERNAME_SIZE+1]; - int enforce_fingerprints; -/* Stats */ - uint64_t received_packets; - uint64_t sent_packets; - uint64_t received_bytes; - uint64_t sent_bytes; - uint32_t received_rate; - uint32_t sent_rate; - uint32_t total_rate; - uint64_t peer_received_packets; - uint64_t peer_sent_packets; - uint64_t peer_received_bytes; - uint64_t peer_sent_bytes; - uint32_t peer_received_rate; - uint32_t peer_sent_rate; - uint32_t peer_total_rate; -/* Mobile */ - int is_mobile; -/* Peers */ - addr_data main_peers_data[TURN_MAIN_PEERS_ARRAY_SIZE]; - size_t main_peers_size; - addr_data *extra_peers_data; - size_t extra_peers_size; -/* Realm */ - char realm[STUN_MAX_REALM_SIZE + 1]; - char origin[STUN_MAX_ORIGIN_SIZE + 1]; -/* Bandwidth */ - band_limit_t bps; + turnsession_id id; + int valid; + turn_time_t start_time; + turn_time_t expiration_time; + SOCKET_TYPE client_protocol; + SOCKET_TYPE peer_protocol; + char tls_method[17]; + char tls_cipher[65]; + addr_data local_addr_data; + addr_data remote_addr_data; + addr_data relay_addr_data_ipv4; + addr_data relay_addr_data_ipv6; + uint8_t username[STUN_MAX_USERNAME_SIZE + 1]; + int enforce_fingerprints; + /* Stats */ + uint64_t received_packets; + uint64_t sent_packets; + uint64_t received_bytes; + uint64_t sent_bytes; + uint32_t received_rate; + uint32_t sent_rate; + uint32_t total_rate; + uint64_t peer_received_packets; + uint64_t peer_sent_packets; + uint64_t peer_received_bytes; + uint64_t peer_sent_bytes; + uint32_t peer_received_rate; + uint32_t peer_sent_rate; + uint32_t peer_total_rate; + /* Mobile */ + int is_mobile; + /* Peers */ + addr_data main_peers_data[TURN_MAIN_PEERS_ARRAY_SIZE]; + size_t main_peers_size; + addr_data *extra_peers_data; + size_t extra_peers_size; + /* Realm */ + char realm[STUN_MAX_REALM_SIZE + 1]; + char origin[STUN_MAX_ORIGIN_SIZE + 1]; + /* Bandwidth */ + band_limit_t bps; }; -void turn_session_info_init(struct turn_session_info* tsi); -void turn_session_info_clean(struct turn_session_info* tsi); -void turn_session_info_add_peer(struct turn_session_info* tsi, ioa_addr *peer); +void turn_session_info_init(struct turn_session_info *tsi); +void turn_session_info_clean(struct turn_session_info *tsi); +void turn_session_info_add_peer(struct turn_session_info *tsi, ioa_addr *peer); -int turn_session_info_copy_from(struct turn_session_info* tsi, ts_ur_super_session *ss); +int turn_session_info_copy_from(struct turn_session_info *tsi, ts_ur_super_session *ss); ////////////// ss ///////////////////// -allocation* get_allocation_ss(ts_ur_super_session *ss); +allocation *get_allocation_ss(ts_ur_super_session *ss); ///////////////////////////////////////////////////////