Commit 044db7ee authored by Youness Alaoui's avatar Youness Alaoui

Moving functions and organizing files

parent f5af7205
......@@ -6,7 +6,7 @@
#
# Licensed under MPL 1.1/LGPL 2.1. See file COPYING.
SUBDIRS = . utils tests
SUBDIRS = . tools tests
include $(top_srcdir)/common.mk
......@@ -21,6 +21,7 @@ dist_noinst_SCRIPTS = build-unknown.sh
libstun_la_SOURCES = \
stun-msg.h stunsend.c stunrecv.c \
stun3489bis.c \
utils.c \
unknown.c \
crc32.c hmac.c \
......
......@@ -35,39 +35,6 @@
* file under either the MPL or the LGPL.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stddef.h>
#include <stdint.h>
#include <assert.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <netinet/in.h> /* htons() */
#include "stun-msg.h"
static inline uint32_t crc32 (const struct iovec *iov, size_t size);
uint32_t stun_fingerprint (const uint8_t *msg, size_t len)
{
struct iovec iov[3];
uint16_t fakelen = htons (len - 20u);
assert (len >= 28u);
iov[0].iov_base = (void *)msg;
iov[0].iov_len = 2;
iov[1].iov_base = &fakelen;
iov[1].iov_len = 2;
iov[2].iov_base = (void *)(msg + 4);
/* first 4 bytes done, last 8 bytes not summed */
iov[2].iov_len = len - 12u;
return crc32 (iov, sizeof (iov) / sizeof (iov[0])) ^ 0x5354554e;
}
/*-
* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
* code or tables extracted from it, as desired without restriction.
......@@ -115,6 +82,14 @@ uint32_t stun_fingerprint (const uint8_t *msg, size_t len)
* CRC32 code derived from work by Gary S. Brown.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "crc32.h"
static const uint32_t crc32_tab[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
......@@ -162,7 +137,6 @@ static const uint32_t crc32_tab[] = {
};
static inline
uint32_t crc32 (const struct iovec *iov, size_t n)
{
size_t i;
......
/*
* This file is part of the Nice GLib ICE library.
*
* (C) 2006, 2007 Collabora Ltd.
* Contact: Dafydd Harries
* (C) 2006, 2007 Nokia Corporation. All rights reserved.
* Contact: Rémi Denis-Courmont
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Nice GLib ICE library.
*
* The Initial Developers of the Original Code are Collabora Ltd and Nokia
* Corporation. All Rights Reserved.
*
* Contributors:
* Rémi Denis-Courmont, Nokia
*
* Alternatively, the contents of this file may be used under the terms of the
* the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
* case the provisions of LGPL are applicable instead of those above. If you
* wish to allow use of your version of this file only under the terms of the
* LGPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replace
* them with the notice and other provisions required by the LGPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the LGPL.
*/
#ifndef _CRC32_H
#define _CRC32_H
#include <stdint.h>
#include <stdlib.h>
#include <sys/uio.h>
uint32_t crc32 (const struct iovec *iov, size_t n);
#endif /* _CRC32_H */
......@@ -44,34 +44,12 @@
*/
# ifndef NDEBUG
# include <stdio.h>
# include <stdarg.h>
static inline void DBG (const char *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
vfprintf (stderr, fmt, ap);
va_end (ap);
}
static inline void DBG_bytes (const void *data, size_t len)
{
size_t i;
DBG ("0x");
for (i = 0; i < len; i++)
DBG ("%02x", ((const unsigned char *)data)[i]);
}
# else
# define DBG( ... ) (void)0
# define DBG_bytes( data, len ) (void)0
# endif
# include <stdint.h>
# include <sys/types.h>
# include <stdbool.h>
# define STUN_MAXMSG 65552 /* bytes */
# define STUN_MAXCHR 127u
# define STUN_MAXSTR ((STUN_MAXCHR * 6u) + 1)
......@@ -177,11 +155,6 @@ typedef enum
} stun_attr_type_t;
static inline bool stun_optional (uint16_t t)
{
return (t >> 15) == 1;
}
typedef uint8_t stun_transid_t[12];
/**
......@@ -211,84 +184,25 @@ typedef enum
} stun_error_t;
/**
* @return complement to the next multiple of 4.
*/
static inline size_t stun_padding (size_t l)
{
return (4 - (l & 3)) & 3;
}
/**
* Rounds up an integer to the next multiple of 4.
*/
static inline size_t stun_align (size_t l)
{
return (l + 3) & ~3;
}
/**
* Reads a word from a non-aligned buffer.
* @return host byte order word value.
*/
static inline uint16_t stun_getw (const uint8_t *ptr)
{
return ((ptr)[0] << 8) | ptr[1];
}
static inline uint16_t stun_length (const uint8_t *ptr)
{
return stun_getw (ptr + 2);
}
/**
* @return STUN message class in host byte order (value from 0 to 3)
*/
static inline stun_class_t stun_get_class (const uint8_t *msg)
{
uint16_t t = stun_getw (msg);
return (stun_class_t)(((t & 0x0100) >> 7) | ((t & 0x0010) >> 4));
}
/**
* @return STUN message method (value from 0 to 0xfff)
*/
static inline stun_method_t stun_get_method (const uint8_t *msg)
{
uint16_t t = stun_getw (msg);
return (stun_method_t)(((t & 0x3e00) >> 2) | ((t & 0x00e0) >> 1) |
(t & 0x000f));
}
bool stun_has_cookie (const uint8_t *msg);
#include "utils.h"
#include "stun3489bis.h"
# ifndef NDEBUG
# include <stdio.h>
# include <stdarg.h>
# define DBG stun_debug
# define DBG_bytes stun_debug_bytes
# else
# define DBG( ... ) (void)0
# define DBG_bytes( data, len ) (void)0
# endif
/**
* @return STUN message transaction ID
*/
static inline const uint8_t *stun_id (const uint8_t *msg)
{
//assert (stun_valid (req));
return msg + 8;
}
# ifdef __cplusplus
extern "C" {
# endif
/**
* Computes the FINGERPRINT checksum of a STUN message.
* @param msg pointer to the STUN message
* @param len size of the message from header (inclusive) and up to
* FINGERPRINT attribute (inclusive)
*
* @return fingerprint value in <b>host</b> byte order.
*/
uint32_t stun_fingerprint (const uint8_t *msg, size_t len);
/**
* Computes the MESSAGE-INTEGRITY hash of a STUN message.
......@@ -378,20 +292,6 @@ const void *
stun_find (const uint8_t *restrict msg, stun_attr_type_t type,
uint16_t *restrict palen);
/**
* Checks if an attribute is present within a STUN message.
*
* @param msg valid STUN message
* @param type STUN attribute type (host byte order)
*
* @return whether there is a MESSAGE-INTEGRITY attribute
*/
static inline bool stun_present (const uint8_t *msg, stun_attr_type_t type)
{
uint16_t dummy;
return stun_find (msg, type, &dummy) != NULL;
}
/**
* Looks for a flag attribute within a valid STUN message.
......@@ -699,32 +599,4 @@ int stun_append_xor_addr (uint8_t *restrict msg, size_t msize,
# endif
/**
* @param msg valid STUN message
* @return true if there is at least one unknown mandatory attribute.
*/
static inline bool stun_has_unknown (const void *msg)
{
uint16_t dummy;
return stun_find_unknown (msg, &dummy, 1);
}
# ifndef NDEBUG
/**
* This function is for debugging only, which is why it is only defined under
* !NDEBUG. It should really only be used in run-time assertions, as it cannot
* detect all possible errors. stun_validate() should be used instead in real
* code.
*
* @param msg pointer to a potential STUN message
* @return whether the pointer refers to a valid STUN message
*/
static inline bool stun_valid (const uint8_t *msg)
{
size_t length = 20u + stun_length (msg);
return stun_validate (msg, length) == (ssize_t)length;
}
# endif
#endif
/*
* This file is part of the Nice GLib ICE library.
*
* (C) 2007 Nokia Corporation. All rights reserved.
* Contact: Rémi Denis-Courmont
* COPYRIGHT (C) 1986 Gary S. Brown
* See documentation of the function crc32() below.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Nice GLib ICE library.
*
* The Initial Developers of the Original Code are Collabora Ltd and Nokia
* Corporation. All Rights Reserved.
*
* Contributors:
* Rémi Denis-Courmont, Nokia
*
* Alternatively, the contents of this file may be used under the terms of the
* the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
* case the provisions of LGPL are applicable instead of those above. If you
* wish to allow use of your version of this file only under the terms of the
* LGPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replace
* them with the notice and other provisions required by the LGPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the LGPL.
*/
#include <sys/socket.h>
#include <netinet/in.h> /* htons() */
#include <assert.h>
#include "crc32.h"
#include "stun-msg.h"
uint32_t stun_fingerprint (const uint8_t *msg, size_t len)
{
struct iovec iov[3];
uint16_t fakelen = htons (len - 20u);
assert (len >= 28u);
iov[0].iov_base = (void *)msg;
iov[0].iov_len = 2;
iov[1].iov_base = &fakelen;
iov[1].iov_len = 2;
iov[2].iov_base = (void *)(msg + 4);
/* first 4 bytes done, last 8 bytes not summed */
iov[2].iov_len = len - 12u;
return crc32 (iov, sizeof (iov) / sizeof (iov[0])) ^ 0x5354554e;
}
/*
* This file is part of the Nice GLib ICE library.
*
* (C) 2006, 2007 Collabora Ltd.
* Contact: Dafydd Harries
* (C) 2006, 2007 Nokia Corporation. All rights reserved.
* Contact: Rémi Denis-Courmont
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Nice GLib ICE library.
*
* The Initial Developers of the Original Code are Collabora Ltd and Nokia
* Corporation. All Rights Reserved.
*
* Contributors:
* Rémi Denis-Courmont, Nokia
*
* Alternatively, the contents of this file may be used under the terms of the
* the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
* case the provisions of LGPL are applicable instead of those above. If you
* wish to allow use of your version of this file only under the terms of the
* LGPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replace
* them with the notice and other provisions required by the LGPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the LGPL.
*/
#ifndef _STUN_3489BIS_H
#define _STUN_3489BIS_H
# include <stdint.h>
# include <sys/types.h>
# include <stdbool.h>
/**
* Computes the FINGERPRINT checksum of a STUN message.
* @param msg pointer to the STUN message
* @param len size of the message from header (inclusive) and up to
* FINGERPRINT attribute (inclusive)
*
* @return fingerprint value in <b>host</b> byte order.
*/
uint32_t stun_fingerprint (const uint8_t *msg, size_t len);
bool stun_has_cookie (const uint8_t *msg);
#endif /* _STUN_3489BIS_H */
......@@ -179,8 +179,6 @@ static inline ssize_t stun_recv (int fd, uint8_t *buf, size_t maxlen)
return stun_recvfrom (fd, buf, maxlen, NULL, NULL);
}
int sockaddrcmp (const struct sockaddr *a, const struct sockaddr *b);
# ifdef __cplusplus
}
# endif
......
......@@ -41,8 +41,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include "stun-msg.h"
#include "trans.h"
#include "utils.h"
/** Compares two socket addresses */
int sockaddrcmp (const struct sockaddr *a, const struct sockaddr *b)
......@@ -82,3 +81,131 @@ int sockaddrcmp (const struct sockaddr *a, const struct sockaddr *b)
}
bool stun_optional (uint16_t t)
{
return (t >> 15) == 1;
}
/**
* @return complement to the next multiple of 4.
*/
size_t stun_padding (size_t l)
{
return (4 - (l & 3)) & 3;
}
/**
* Rounds up an integer to the next multiple of 4.
*/
size_t stun_align (size_t l)
{
return (l + 3) & ~3;
}
/**
* Reads a word from a non-aligned buffer.
* @return host byte order word value.
*/
uint16_t stun_getw (const uint8_t *ptr)
{
return ((ptr)[0] << 8) | ptr[1];
}
uint16_t stun_length (const uint8_t *ptr)
{
return stun_getw (ptr + 2);
}
/**
* @return STUN message class in host byte order (value from 0 to 3)
*/
stun_class_t stun_get_class (const uint8_t *msg)
{
uint16_t t = stun_getw (msg);
return (stun_class_t)(((t & 0x0100) >> 7) | ((t & 0x0010) >> 4));
}
/**
* @return STUN message method (value from 0 to 0xfff)
*/
stun_method_t stun_get_method (const uint8_t *msg)
{
uint16_t t = stun_getw (msg);
return (stun_method_t)(((t & 0x3e00) >> 2) | ((t & 0x00e0) >> 1) |
(t & 0x000f));
}
/**
* @return STUN message transaction ID
*/
const uint8_t *stun_id (const uint8_t *msg)
{
//assert (stun_valid (req));
return msg + 8;
}
/**
* Checks if an attribute is present within a STUN message.
*
* @param msg valid STUN message
* @param type STUN attribute type (host byte order)
*
* @return whether there is a MESSAGE-INTEGRITY attribute
*/
bool stun_present (const uint8_t *msg, stun_attr_type_t type)
{
uint16_t dummy;
return stun_find (msg, type, &dummy) != NULL;
}
/**
* @param msg valid STUN message
* @return true if there is at least one unknown mandatory attribute.
*/
bool stun_has_unknown (const void *msg)
{
uint16_t dummy;
return stun_find_unknown (msg, &dummy, 1);
}
# ifndef NDEBUG
/**
* This function is for debugging only, which is why it is only defined under
* !NDEBUG. It should really only be used in run-time assertions, as it cannot
* detect all possible errors. stun_validate() should be used instead in real
* code.
*
* @param msg pointer to a potential STUN message
* @return whether the pointer refers to a valid STUN message
*/
bool stun_valid (const uint8_t *msg)
{
size_t length = 20u + stun_length (msg);
return stun_validate (msg, length) == (ssize_t)length;
}
# endif
void stun_debug (const char *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
vfprintf (stderr, fmt, ap);
va_end (ap);
}
void stun_debug_bytes (const void *data, size_t len)
{
size_t i;
DBG ("0x");
for (i = 0; i < len; i++)
DBG ("%02x", ((const unsigned char *)data)[i]);
}
......@@ -33,97 +33,53 @@
* file under either the MPL or the LGPL.
*/
#ifndef STUN_CONNCHECK_H
# define STUN_CONNCHECK_H 1
#ifndef STUN_UTILS_H
# define STUN_UTILS_H 1
# include "stun/bind.h"
/**
* @file utils.h
* @brief STUN client generic utility functions
*/
#include "stun-msg.h"
# ifdef __cplusplus
extern "C" {
# endif
/**
* @file conncheck.h
* @brief STUN/ICE connectivity checks
*/
/**
* Starts a connectivity check using STUN Binding discovery.
*
* @param context pointer to an opaque pointer that will be passed to
* stun_bind_resume() afterward
* @param fd socket to use for discovery, or -1 to create one
* @param srv STUN server socket address
* @param srvlen STUN server socket address length
* @param username nul-terminated username for authentication
* (need not be kept valid after return)
* @param password nul-terminated shared secret (ICE password)
* (need not be kept valid after return)
* @param cand_use whether to include a USE-CANDIDATE flag
* @param priority host-byte order PRIORITY value
* @param controlling whether we are in controlling (true) or
* controlled (false) state
* @param tie control tie breaker value (host-byte order)
*
* @return 0 on success, a standard error value otherwise.
*/
int stun_conncheck_start (stun_bind_t **restrict context, int fd,
const struct sockaddr *restrict srv, socklen_t srvlen,
const char *username, const char *password,
bool cand_use, bool controlling, uint32_t priority,
uint64_t tie, uint32_t compat);
int sockaddrcmp (const struct sockaddr *a, const struct sockaddr *b);
/**
* Tries to parse a STUN connectivity check (Binding request) and format a
* response accordingly.
*
* @param buf [OUT] output buffer to write a Binding response to. May refer
* to the same buffer space as the request message.
* @param plen [IN/OUT] output buffer size on entry, response length on exit
* @param msg pointer to the first byte of the binding request
* @param src socket address the message was received from
* @param srclen byte length of the socket address
* @param password HMAC secret password
* @param control [IN/OUT] whether we are controlling ICE or not
* @param tie tie breaker value for ICE role determination
*
* @return same as stun_bind_reply() with one additionnal error code:
* EACCES: ICE role conflict occured, please recheck the flag at @a control
*
* @note @a buf and @a msg <b>must not</b> collide.
*/
int
stun_conncheck_reply (uint8_t *buf, size_t *restrict plen, const uint8_t *msg,
const struct sockaddr *restrict src, socklen_t srclen,
const char *pass, bool *restrict control, uint64_t tie);
bool stun_optional (uint16_t t);
/**
* Extracts the username from a STUN message.
* @param msg pointer to the first byte of the binding request
* @param buf where to store the username as a nul-terminated string
* @param buflen byte length of @a buf buffer
*
* @return @a buf on success, NULL on error
*/
char *stun_conncheck_username (const uint8_t *restrict msg,
char *restrict buf, size_t buflen);
size_t stun_padding (size_t l);
/**
* Extracts the priority from a STUN message.
* @param msg valid STUN message.
* @return host byte order priority, or 0 if not specified.
*/
uint32_t stun_conncheck_priority (const uint8_t *msg);
size_t stun_align (size_t l);
/**
* Extracts the "use candidate" flag from a STUN message.
* @param msg valid STUN message.
* @return true if the flag is set, false if not.
*/
bool stun_conncheck_use_candidate (const uint8_t *msg);
uint16_t stun_getw (const uint8_t *ptr);
uint16_t stun_length (const uint8_t *ptr);
stun_class_t stun_get_class (const uint8_t *msg);
stun_method_t stun_get_method (const uint8_t *msg);
const uint8_t *stun_id (const uint8_t *msg);
bool stun_present (const uint8_t *msg, stun_attr_type_t type);
bool stun_has_unknown (const void *msg);
# ifndef NDEBUG
bool stun_valid (const uint8_t *msg);
# endif
void stun_debug (const char *fmt, ...);
void stun_debug_bytes (const void *data, size_t len);
# ifdef __cplusplus
}
# endif
#endif
#endif /* !STUN_UTILS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment