update splash
This commit is contained in:
commit
6648fd2393
282 changed files with 45451 additions and 0 deletions
109
Makefile
Normal file
109
Makefile
Normal file
|
@ -0,0 +1,109 @@
|
|||
#
|
||||
# Makefile
|
||||
#
|
||||
# Copyright (C) 2010 Creytiv.com
|
||||
#
|
||||
|
||||
# Master version number
|
||||
VER_MAJOR := 0
|
||||
VER_MINOR := 1
|
||||
VER_PATCH := 0
|
||||
|
||||
PROJECT := re
|
||||
VERSION := 0.1.0
|
||||
|
||||
MK := mk/re.mk
|
||||
|
||||
include $(MK)
|
||||
|
||||
# List of modules
|
||||
MODULES += sip sipreg sipsess
|
||||
MODULES += uri httpauth
|
||||
MODULES += stun turn ice
|
||||
MODULES += natbd
|
||||
MODULES += rtp sdp g711 jbuf telev
|
||||
MODULES += dns
|
||||
MODULES += md5 crc32 sha hmac base64
|
||||
MODULES += udp sa net tcp tls
|
||||
MODULES += list mbuf hash
|
||||
MODULES += fmt tmr main mem dbg sys lock mqueue
|
||||
MODULES += mod conf
|
||||
|
||||
INSTALL := install
|
||||
ifeq ($(DESTDIR),)
|
||||
PREFIX := /usr/local
|
||||
else
|
||||
PREFIX := /usr
|
||||
endif
|
||||
ifeq ($(LIBDIR),)
|
||||
LIBDIR := $(PREFIX)/lib
|
||||
endif
|
||||
INCDIR := $(PREFIX)/include/re
|
||||
MKDIR := $(PREFIX)/share/re
|
||||
CFLAGS += -Iinclude
|
||||
|
||||
MODMKS := $(patsubst %,src/%/mod.mk,$(MODULES))
|
||||
SHARED := libre$(LIB_SUFFIX)
|
||||
STATIC := libre.a
|
||||
|
||||
include $(MODMKS)
|
||||
|
||||
|
||||
OBJS ?= $(patsubst %.c,$(BUILD)/%.o,$(SRCS))
|
||||
|
||||
|
||||
all: $(SHARED) $(STATIC)
|
||||
|
||||
|
||||
-include $(OBJS:.o=.d)
|
||||
|
||||
|
||||
$(SHARED): $(OBJS)
|
||||
@echo " LD $@"
|
||||
@$(LD) $(LFLAGS) $(SH_LFLAGS) $^ $(LIBS) -o $@
|
||||
|
||||
|
||||
$(STATIC): $(OBJS)
|
||||
@echo " AR $@"
|
||||
@$(AR) $(AFLAGS) $@ $^
|
||||
ifneq ($(RANLIB),)
|
||||
@$(RANLIB) $@
|
||||
endif
|
||||
|
||||
$(BUILD)/%.o: src/%.c $(BUILD) Makefile $(MK) $(MODMKS)
|
||||
@echo " CC $@"
|
||||
@$(CC) $(CFLAGS) -c $< -o $@ $(DFLAGS)
|
||||
|
||||
|
||||
$(BUILD): Makefile $(MK) $(MODMKS)
|
||||
@mkdir -p $(patsubst %,$(BUILD)/%,$(sort $(dir $(SRCS))))
|
||||
@touch $@
|
||||
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -rf $(SHARED) $(STATIC) test.d test.o test $(BUILD)/
|
||||
|
||||
|
||||
install: $(SHARED) $(STATIC)
|
||||
@mkdir -p $(DESTDIR)$(LIBDIR) $(DESTDIR)$(INCDIR) $(DESTDIR)$(MKDIR)
|
||||
$(INSTALL) -m 0644 $(shell find include -name "*.h") \
|
||||
$(DESTDIR)$(INCDIR)
|
||||
$(INSTALL) -m 0755 $(SHARED) $(DESTDIR)$(LIBDIR)
|
||||
$(INSTALL) -m 0755 $(STATIC) $(DESTDIR)$(LIBDIR)
|
||||
$(INSTALL) -m 0644 $(MK) $(DESTDIR)$(MKDIR)
|
||||
|
||||
-include test.d
|
||||
|
||||
test.o: test.c Makefile $(MK)
|
||||
@echo " CC $@"
|
||||
@$(CC) $(CFLAGS) -c $< -o $@ $(DFLAGS)
|
||||
|
||||
test$(BIN_SUFFIX): test.o $(SHARED) $(STATIC)
|
||||
@echo " LD $@"
|
||||
@$(LD) $(LFLAGS) $< -L. -lre $(LIBS) -o $@
|
||||
|
||||
sym: $(SHARED)
|
||||
@nm $(SHARED) | grep " U " | perl -pe 's/\s*U\s+(.*)/$${1}/' \
|
||||
> docs/symbols.txt
|
||||
@echo "$(SHARED) is using `cat docs/symbols.txt | wc -l ` symbols"
|
5
debian/changelog
vendored
Normal file
5
debian/changelog
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
libre (0.1.0) unstable; urgency=low
|
||||
|
||||
* version 0.1.0
|
||||
|
||||
-- Alfred E. Heggestad <aeh@db.org> Fri, 5 Nov 2010 05:11:10 +0100
|
1
debian/compat
vendored
Normal file
1
debian/compat
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
7
|
34
debian/control
vendored
Normal file
34
debian/control
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
Source: libre
|
||||
Section: comm
|
||||
Priority: optional
|
||||
Maintainer: Alfred E. Heggestad <aeh@db.org>
|
||||
Build-Depends: debhelper (>= 4.0.0)
|
||||
Standards-Version: 3.6.2
|
||||
|
||||
Package: libre
|
||||
Architecture: any
|
||||
Section: libs
|
||||
Depends: ${shlibs:Depends}
|
||||
Description: Generic library for real-time communications with async IO support
|
||||
.
|
||||
Design goals:
|
||||
.
|
||||
- Portable POSIX source code (ANSI C89 and ISO C99 standard)
|
||||
- Robust, fast, low memory footprint
|
||||
- RFC compliance
|
||||
- IPv4 and IPv6 support
|
||||
|
||||
Package: libre-dev
|
||||
Architecture: any
|
||||
Section: libdevel
|
||||
Depends: libre (= ${Source-Version}), ${shlibs:Depends}
|
||||
Description: Generic library for real-time communications with async IO support (development files)
|
||||
.
|
||||
Design goals:
|
||||
.
|
||||
- Portable POSIX source code (ANSI C89 and ISO C99 standard)
|
||||
- Robust, fast, low memory footprint
|
||||
- RFC compliance
|
||||
- IPv4 and IPv6 support
|
||||
.
|
||||
This package is only the library development files.
|
9
debian/copyright
vendored
Normal file
9
debian/copyright
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
This package was debianized by Alfred E. Heggestad <aeh@db.org>
|
||||
|
||||
It was downloaded from http://www.creytiv.com/
|
||||
|
||||
Copyright Holder: Creytiv.com
|
||||
|
||||
License:
|
||||
|
||||
BSD License
|
2
debian/docs
vendored
Normal file
2
debian/docs
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
docs/README
|
||||
docs/TODO
|
3
debian/libre-dev.dirs
vendored
Normal file
3
debian/libre-dev.dirs
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
usr/include
|
||||
usr/lib
|
||||
usr/share
|
3
debian/libre-dev.files
vendored
Normal file
3
debian/libre-dev.files
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
usr/include
|
||||
usr/lib/libre.a
|
||||
usr/share/re
|
1
debian/libre.dirs
vendored
Normal file
1
debian/libre.dirs
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
usr/lib
|
1
debian/libre.files
vendored
Normal file
1
debian/libre.files
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/usr/lib/libre.so
|
88
debian/rules
vendored
Executable file
88
debian/rules
vendored
Executable file
|
@ -0,0 +1,88 @@
|
|||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
# Sample debian/rules that uses debhelper.
|
||||
# This file was originally written by Joey Hess and Craig Small.
|
||||
# As a special exception, when this file is copied by dh-make into a
|
||||
# dh-make output file, you may use that output file without restriction.
|
||||
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
|
||||
configure: configure-stamp
|
||||
configure-stamp:
|
||||
dh_testdir
|
||||
# Add here commands to configure the package.
|
||||
|
||||
touch configure-stamp
|
||||
|
||||
|
||||
build: build-stamp
|
||||
build-stamp: configure-stamp
|
||||
dh_testdir
|
||||
|
||||
# Add here commands to compile the package.
|
||||
$(MAKE) RELEASE=1
|
||||
|
||||
touch $@
|
||||
|
||||
clean:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
rm -f build-stamp configure-stamp
|
||||
|
||||
# Add here commands to clean up after the build process.
|
||||
-$(MAKE) clean
|
||||
|
||||
dh_clean
|
||||
|
||||
install: build
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_clean -k
|
||||
dh_installdirs
|
||||
|
||||
# Add here commands to install the package into debian/tmp
|
||||
mkdir $(CURDIR)/debian/tmp
|
||||
$(MAKE) install DESTDIR=$(CURDIR)/debian/tmp
|
||||
|
||||
dh_movefiles
|
||||
|
||||
# Build architecture-independent files here.
|
||||
binary-indep: build install
|
||||
# We have nothing to do by default.
|
||||
|
||||
# Build architecture-dependent files here.
|
||||
binary-arch: build install
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_installchangelogs
|
||||
dh_installdocs
|
||||
dh_installexamples
|
||||
# dh_install
|
||||
# dh_installmenu
|
||||
# dh_installdebconf
|
||||
# dh_installlogrotate
|
||||
# dh_installemacsen
|
||||
# dh_installpam
|
||||
# dh_installmime
|
||||
# dh_installinit
|
||||
# dh_installcron
|
||||
# dh_installinfo
|
||||
dh_installman
|
||||
dh_link
|
||||
dh_strip
|
||||
dh_compress
|
||||
dh_fixperms
|
||||
# dh_perl
|
||||
# dh_python
|
||||
# dh_makeshlibs
|
||||
dh_installdeb
|
||||
dh_shlibdeps
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
|
||||
binary: binary-indep binary-arch
|
||||
.PHONY: build clean binary-indep binary-arch binary install configure
|
31
docs/COPYING
Normal file
31
docs/COPYING
Normal file
|
@ -0,0 +1,31 @@
|
|||
Copyright (c) 2010, Alfred E. Heggestad
|
||||
Copyright (c) 2010, Creytiv.com
|
||||
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 Creytiv.com 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 AUTHOR ``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 AUTHOR 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.
|
146
docs/README
Normal file
146
docs/README
Normal file
|
@ -0,0 +1,146 @@
|
|||
README
|
||||
------
|
||||
|
||||
libre - "Generic library for real-time communications with async IO support"
|
||||
Copyright (C) 2010 Creytiv.com
|
||||
|
||||
Distributed under BSD license
|
||||
|
||||
|
||||
Design goals:
|
||||
|
||||
* Portable POSIX source code (ANSI C89 and ISO C99 standard)
|
||||
* Robust, fast, low memory footprint
|
||||
* RFC compliance
|
||||
* IPv4 and IPv6 support
|
||||
|
||||
|
||||
Modules:
|
||||
|
||||
name: status: description:
|
||||
|
||||
* base64 testing Base-64 encoding/decoding functions
|
||||
* conf testing Configuration file parser
|
||||
* crc32 testing 32-bit CRC defined in ITU V.42
|
||||
* dbg testing Debug printing
|
||||
* dns testing DNS resolving (NAPTR, SRV, A)
|
||||
* fmt testing Formatted printing and regular expression
|
||||
* g711 stable G.711 codec
|
||||
* hash testing Hashmap table
|
||||
* hmac testing HMAC: Keyed-Hashing for Message Authentication
|
||||
* httpauth unstable HTTP-based Authentication (RFC 2617)
|
||||
* ice development Interactive Connectivity Establishment (ICE)
|
||||
* jbuf testing Jitter buffer
|
||||
* list stable Sortable doubly-linked list handling
|
||||
* lock testing Resource locking functions
|
||||
* main testing Main poll loop
|
||||
* mbuf stable Linear memory buffers
|
||||
* md5 stable The MD5 Message-Digest Algorithm (RFC 1321)
|
||||
* mem stable Memory referencing
|
||||
* mod testing Run-time module loading
|
||||
* mqueue unstable Thread-safe message queue
|
||||
* natbd unstable NAT Behavior Discovery using STUN
|
||||
* net unstable Networking routines
|
||||
* rtp testing Real-time Transport Protocol
|
||||
* sa stable Socket Address functions
|
||||
* sdp unstable Session Description Protocol
|
||||
* sha testing Secure Hash Standard, NIST, FIPS PUB 180-1
|
||||
* sip unstable Core SIP library
|
||||
* sipreg testing SIP register client
|
||||
* sipsess unstable SIP Sessions
|
||||
* stun unstable Session Traversal Utilities for NAT (STUN)
|
||||
* sys testing System information
|
||||
* tcp testing TCP transport
|
||||
* telev testing Telephony Events (RFC 4733)
|
||||
* tls unstable Transport Layer Security
|
||||
* tmr stable Timer handling
|
||||
* turn unstable Obtaining Relay Addresses from STUN (TURN)
|
||||
* udp testing UDP transport
|
||||
* uri testing Generic URI library
|
||||
|
||||
legend:
|
||||
"stable" - Code complete; Stable code and stable API
|
||||
"testing" - Code complete, but API might change
|
||||
"unstable" - Code complete but not completely tested
|
||||
"development" - Code is under development
|
||||
|
||||
|
||||
Features:
|
||||
|
||||
* RFC 1321 - The MD5 Message-Digest Algorithm
|
||||
* RFC 1886 - DNS Extensions to support IP version 6
|
||||
* RFC 2032 - RTP Payload Format for H.261 Video Streams
|
||||
* RFC 2617 - HTTP Authentication: Basic and Digest Access Authentication
|
||||
* RFC 2782 - A DNS RR for Specifying the Location of Services (DNS SRV)
|
||||
* RFC 2915 - The Naming Authority Pointer (NAPTR) DNS Resource Record
|
||||
* RFC 3261 - SIP: Session Initiation Protocol
|
||||
* RFC 3263 - Locating SIP Servers
|
||||
* RFC 3264 - An Offer/Answer Model with SDP
|
||||
* RFC 3327 - SIP Extension Header Field for Registering Non-Adjacent Contacts
|
||||
* RFC 3428 - SIP Extension for Instant Messaging
|
||||
* RFC 3489 - STUN - Simple Traversal of UDP Through NATs
|
||||
* RFC 3550 - RTP: A Transport Protocol for Real-Time Applications
|
||||
* RFC 3551 - RTP Profile for Audio and Video Conferences with Minimal Control
|
||||
* RFC 3555 - MIME Type Registration of RTP Payload Formats
|
||||
* RFC 3556 - SDP Bandwidth Modifiers for RTCP Bandwidth
|
||||
* RFC 3581 - An Extension to SIP for Symmetric Response Routing
|
||||
* RFC 3605 - RTCP attribute in SDP
|
||||
* RFC 3969 - The IANA URI Parameter Registry for SIP
|
||||
* RFC 3994 - Indication of Message Composition for Instant Messaging
|
||||
* RFC 4346 - The TLS Protocol Version 1.1
|
||||
* RFC 4566 - SDP: Session Description Protocol
|
||||
* RFC 4585 - Extended RTP Profile for RTCP-Based Feedback
|
||||
* RFC 4733 - RTP Payload for DTMF Digits, Telephony Tones, and Teleph. Signals
|
||||
* RFC 4961 - Symmetric RTP / RTP Control Protocol (RTCP)
|
||||
* RFC 5118 - SIP Torture Test Messages for IPv6
|
||||
* RFC 5245 - Interactive Connectivity Establishment (ICE)
|
||||
* RFC 5389 - Session Traversal Utilities for NAT (STUN)
|
||||
* RFC 5766 - Traversal Using Relays around NAT (TURN)
|
||||
* RFC 5768 - Indicating Support for ICE in SIP
|
||||
* RFC 5769 - Test vectors for STUN
|
||||
* RFC 5780 - NAT Behaviour Discovery Using STUN
|
||||
* RFC 6026 - Correct Transaction Handling for 2xx Resp. to SIP INVITE Requests
|
||||
* Symmetric RTP
|
||||
* draft-ietf-behave-turn-ipv6-08 - TURN Extension for IPv4/IPv6 Transition
|
||||
* ITU-T G.711 Appendix I and Appendix II
|
||||
|
||||
|
||||
Supported platforms:
|
||||
|
||||
* Linux
|
||||
* FreeBSD
|
||||
* OpenBSD
|
||||
* NetBSD
|
||||
* Symbian OS
|
||||
* Solaris
|
||||
* Windows
|
||||
* Apple Mac OS X
|
||||
|
||||
|
||||
Supported compilers:
|
||||
|
||||
* gcc (v2.9x to v4.x)
|
||||
* gcce
|
||||
* ms vc2003 compiler
|
||||
* codewarrior
|
||||
|
||||
|
||||
Feedback:
|
||||
|
||||
- Please send feedback to <libre@creytiv.com>
|
||||
|
||||
|
||||
Coding guidelines:
|
||||
|
||||
* Use enum for constants where appropriate
|
||||
* Use const as much as possible (where appropriate)
|
||||
* Use C99 data types (intN_t, uintN_t, bool)
|
||||
* Hide data-types in .c files where possible (use struct foo)
|
||||
* Avoid malloc/free, use mem_alloc/mem_deref instead
|
||||
* CVS/svn/git tags are NOT allowed in the code!
|
||||
* Avoid bit-fields in structs which are not portable
|
||||
* Use dummy handlers for timing-critical callbacks
|
||||
* return err, return alloced objects as pointer-pointers
|
||||
* in allocating functions, first arg is always double pointer
|
||||
* Use POSIX error-codes; EINVAL for invalid args, EBADMSG for
|
||||
parse errors and EPROTO for protocol errors
|
11
docs/TODO
Normal file
11
docs/TODO
Normal file
|
@ -0,0 +1,11 @@
|
|||
TODO
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Version v0.1.1
|
||||
|
||||
SIP Outbound support - client+server
|
||||
tmr: scaling using binary heap or hash
|
||||
Add support for SIP SUBSCRIBE/NOTIFY
|
||||
Add support for Call-Transfer in SIP Session
|
||||
|
||||
-------------------------------------------------------------------------------
|
7
docs/main.dox
Normal file
7
docs/main.dox
Normal file
|
@ -0,0 +1,7 @@
|
|||
/**
|
||||
* \mainpage libre Development Documentation
|
||||
*
|
||||
* Development documentation for libre
|
||||
*
|
||||
* \section modules modules
|
||||
*/
|
137
docs/symbols.txt
Normal file
137
docs/symbols.txt
Normal file
|
@ -0,0 +1,137 @@
|
|||
BIO_new@@OPENSSL_0.9.8
|
||||
BIO_new_socket@@OPENSSL_0.9.8
|
||||
BIO_s_mem@@OPENSSL_0.9.8
|
||||
BIO_write@@OPENSSL_0.9.8
|
||||
ERR_free_strings@@OPENSSL_0.9.8
|
||||
ERR_get_error@@OPENSSL_0.9.8
|
||||
EVP_sha1@@OPENSSL_0.9.8
|
||||
HMAC@@OPENSSL_0.9.8
|
||||
MD5@@OPENSSL_0.9.8
|
||||
RAND_bytes@@OPENSSL_0.9.8
|
||||
SSL_CTX_free@@OPENSSL_0.9.8
|
||||
SSL_CTX_load_verify_locations@@OPENSSL_0.9.8
|
||||
SSL_CTX_new@@OPENSSL_0.9.8
|
||||
SSL_CTX_set_default_passwd_cb@@OPENSSL_0.9.8
|
||||
SSL_CTX_set_default_passwd_cb_userdata@@OPENSSL_0.9.8
|
||||
SSL_CTX_use_PrivateKey_file@@OPENSSL_0.9.8
|
||||
SSL_CTX_use_certificate_chain_file@@OPENSSL_0.9.8
|
||||
SSL_accept@@OPENSSL_0.9.8
|
||||
SSL_connect@@OPENSSL_0.9.8
|
||||
SSL_free@@OPENSSL_0.9.8
|
||||
SSL_get_error@@OPENSSL_0.9.8
|
||||
SSL_get_peer_certificate@@OPENSSL_0.9.8
|
||||
SSL_get_verify_result@@OPENSSL_0.9.8
|
||||
SSL_library_init@@OPENSSL_0.9.8
|
||||
SSL_load_error_strings@@OPENSSL_0.9.8
|
||||
SSL_new@@OPENSSL_0.9.8
|
||||
SSL_read@@OPENSSL_0.9.8
|
||||
SSL_set_bio@@OPENSSL_0.9.8
|
||||
SSL_shutdown@@OPENSSL_0.9.8
|
||||
SSL_state@@OPENSSL_0.9.8
|
||||
SSL_write@@OPENSSL_0.9.8
|
||||
SSLv23_method@@OPENSSL_0.9.8
|
||||
X509_NAME_get_text_by_NID@@OPENSSL_0.9.8
|
||||
X509_get_subject_name@@OPENSSL_0.9.8
|
||||
__ctype_b_loc@@GLIBC_2.3
|
||||
__errno_location@@GLIBC_2.2.5
|
||||
__isinf@@GLIBC_2.2.5
|
||||
__isnan@@GLIBC_2.2.5
|
||||
__isoc99_fscanf@@GLIBC_2.7
|
||||
__res_close@@GLIBC_2.2.5
|
||||
__res_init@@GLIBC_2.2.5
|
||||
__res_state@@GLIBC_2.2.5
|
||||
__sysv_signal@@GLIBC_2.2.5
|
||||
accept@@GLIBC_2.2.5
|
||||
atoi@@GLIBC_2.2.5
|
||||
bind@@GLIBC_2.2.5
|
||||
chdir@@GLIBC_2.2.5
|
||||
close@@GLIBC_2.2.5
|
||||
connect@@GLIBC_2.2.5
|
||||
crc32
|
||||
ctime@@GLIBC_2.2.5
|
||||
dlclose@@GLIBC_2.2.5
|
||||
dlerror@@GLIBC_2.2.5
|
||||
dlopen@@GLIBC_2.2.5
|
||||
dlsym@@GLIBC_2.2.5
|
||||
epoll_create@@GLIBC_2.3.2
|
||||
epoll_ctl@@GLIBC_2.3.2
|
||||
epoll_wait@@GLIBC_2.3.2
|
||||
exit@@GLIBC_2.2.5
|
||||
fclose@@GLIBC_2.2.5
|
||||
fcntl@@GLIBC_2.2.5
|
||||
fflush@@GLIBC_2.2.5
|
||||
fopen@@GLIBC_2.2.5
|
||||
fork@@GLIBC_2.2.5
|
||||
free@@GLIBC_2.2.5
|
||||
freeaddrinfo@@GLIBC_2.2.5
|
||||
freeifaddrs@@GLIBC_2.3
|
||||
freopen@@GLIBC_2.2.5
|
||||
fwrite@@GLIBC_2.2.5
|
||||
gai_strerror@@GLIBC_2.2.5
|
||||
getaddrinfo@@GLIBC_2.2.5
|
||||
gethostbyname@@GLIBC_2.2.5
|
||||
gethostname@@GLIBC_2.2.5
|
||||
getifaddrs@@GLIBC_2.3
|
||||
getpeername@@GLIBC_2.2.5
|
||||
getpid@@GLIBC_2.2.5
|
||||
getsockname@@GLIBC_2.2.5
|
||||
getsockopt@@GLIBC_2.2.5
|
||||
gettimeofday@@GLIBC_2.2.5
|
||||
htonl@@GLIBC_2.2.5
|
||||
htons@@GLIBC_2.2.5
|
||||
if_indextoname@@GLIBC_2.2.5
|
||||
inet_ntop@@GLIBC_2.2.5
|
||||
inet_pton@@GLIBC_2.2.5
|
||||
ioctl@@GLIBC_2.2.5
|
||||
listen@@GLIBC_2.2.5
|
||||
malloc@@GLIBC_2.2.5
|
||||
memcmp@@GLIBC_2.2.5
|
||||
memcpy@@GLIBC_2.2.5
|
||||
memmove@@GLIBC_2.2.5
|
||||
memset@@GLIBC_2.2.5
|
||||
ntohl@@GLIBC_2.2.5
|
||||
ntohs@@GLIBC_2.2.5
|
||||
open@@GLIBC_2.2.5
|
||||
pipe@@GLIBC_2.2.5
|
||||
poll@@GLIBC_2.2.5
|
||||
pthread_getspecific@@GLIBC_2.2.5
|
||||
pthread_key_create@@GLIBC_2.2.5
|
||||
pthread_mutex_init@@GLIBC_2.2.5
|
||||
pthread_mutex_lock@@GLIBC_2.2.5
|
||||
pthread_mutex_unlock@@GLIBC_2.2.5
|
||||
pthread_once@@GLIBC_2.2.5
|
||||
pthread_rwlock_destroy@@GLIBC_2.2.5
|
||||
pthread_rwlock_init@@GLIBC_2.2.5
|
||||
pthread_rwlock_rdlock@@GLIBC_2.2.5
|
||||
pthread_rwlock_tryrdlock@@GLIBC_2.2.5
|
||||
pthread_rwlock_trywrlock@@GLIBC_2.2.5
|
||||
pthread_rwlock_unlock@@GLIBC_2.2.5
|
||||
pthread_rwlock_wrlock@@GLIBC_2.2.5
|
||||
pthread_self@@GLIBC_2.2.5
|
||||
pthread_setspecific@@GLIBC_2.2.5
|
||||
read@@GLIBC_2.2.5
|
||||
realloc@@GLIBC_2.2.5
|
||||
recv@@GLIBC_2.2.5
|
||||
recvfrom@@GLIBC_2.2.5
|
||||
select@@GLIBC_2.2.5
|
||||
send@@GLIBC_2.2.5
|
||||
sendto@@GLIBC_2.2.5
|
||||
setrlimit@@GLIBC_2.2.5
|
||||
setsid@@GLIBC_2.2.5
|
||||
setsockopt@@GLIBC_2.2.5
|
||||
socket@@GLIBC_2.2.5
|
||||
srand@@GLIBC_2.2.5
|
||||
stderr@@GLIBC_2.2.5
|
||||
stdin@@GLIBC_2.2.5
|
||||
stdout@@GLIBC_2.2.5
|
||||
strcasecmp@@GLIBC_2.2.5
|
||||
strcmp@@GLIBC_2.2.5
|
||||
strerror@@GLIBC_2.2.5
|
||||
strlen@@GLIBC_2.2.5
|
||||
strncasecmp@@GLIBC_2.2.5
|
||||
strncpy@@GLIBC_2.2.5
|
||||
time@@GLIBC_2.2.5
|
||||
tolower@@GLIBC_2.2.5
|
||||
umask@@GLIBC_2.2.5
|
||||
uname@@GLIBC_2.2.5
|
||||
write@@GLIBC_2.2.5
|
53
include/re.h
Normal file
53
include/re.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* @file re.h Wrapper for all header files
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Basic types */
|
||||
#include "re_types.h"
|
||||
#include "re_fmt.h"
|
||||
#include "re_mbuf.h"
|
||||
#include "re_list.h"
|
||||
#include "re_sa.h"
|
||||
|
||||
/* Library modules */
|
||||
#include "re_base64.h"
|
||||
#include "re_conf.h"
|
||||
#include "re_crc32.h"
|
||||
#include "re_dns.h"
|
||||
#include "re_g711.h"
|
||||
#include "re_hash.h"
|
||||
#include "re_httpauth.h"
|
||||
#include "re_ice.h"
|
||||
#include "re_jbuf.h"
|
||||
#include "re_lock.h"
|
||||
#include "re_main.h"
|
||||
#include "re_md5.h"
|
||||
#include "re_mem.h"
|
||||
#include "re_mod.h"
|
||||
#include "re_mqueue.h"
|
||||
#include "re_net.h"
|
||||
#include "re_rtp.h"
|
||||
#include "re_sdp.h"
|
||||
#include "re_uri.h"
|
||||
#include "re_sip.h"
|
||||
#include "re_sipreg.h"
|
||||
#include "re_sipsess.h"
|
||||
#include "re_stun.h"
|
||||
#include "re_natbd.h"
|
||||
#include "re_sys.h"
|
||||
#include "re_tcp.h"
|
||||
#include "re_telev.h"
|
||||
#include "re_tmr.h"
|
||||
#include "re_tls.h"
|
||||
#include "re_turn.h"
|
||||
#include "re_udp.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
9
include/re_base64.h
Normal file
9
include/re_base64.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
/**
|
||||
* @file re_base64.h Interface to Base64 encoding/decoding functions
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
int base64_encode(const uint8_t *in, size_t ilen, char *out, size_t *olen);
|
||||
int base64_decode(const char *in, size_t ilen, uint8_t *out, size_t *olen);
|
73
include/re_bitv.h
Normal file
73
include/re_bitv.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* @file re_bitv.h Interface to Bit Vector functions
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
typedef unsigned long bitv_t;
|
||||
|
||||
enum {
|
||||
BITS_SZ = (8*sizeof(bitv_t)),
|
||||
BITS_MASK = (BITS_SZ-1)
|
||||
};
|
||||
|
||||
#define BITV_NELEM(nbits) (((nbits) + (BITS_SZ) - 1) / (BITS_SZ))
|
||||
#define BITV_DECL(name, nbits) bitv_t (name)[BITV_NELEM(nbits)]
|
||||
|
||||
|
||||
static inline uint32_t index2offset(uint32_t i)
|
||||
{
|
||||
return i/BITS_SZ;
|
||||
}
|
||||
|
||||
static inline bitv_t index2bit(uint32_t i)
|
||||
{
|
||||
return (bitv_t)1<<(i & BITS_MASK);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Public API
|
||||
*/
|
||||
|
||||
|
||||
static inline void bitv_init(bitv_t *bv, uint32_t nbits, bool val)
|
||||
{
|
||||
memset(bv, val?0xff:0x00, BITV_NELEM(nbits)*sizeof(bitv_t));
|
||||
}
|
||||
|
||||
static inline void bitv_set(bitv_t *bv, uint32_t i)
|
||||
{
|
||||
bv[index2offset(i)] |= index2bit(i);
|
||||
}
|
||||
|
||||
static inline void bitv_clr(bitv_t *bv, uint32_t i)
|
||||
{
|
||||
bv[index2offset(i)] &= ~index2bit(i);
|
||||
}
|
||||
|
||||
static inline void bitv_assign(bitv_t *bv, uint32_t i, bool val)
|
||||
{
|
||||
if (val)
|
||||
bitv_set(bv, i);
|
||||
else
|
||||
bitv_clr(bv, i);
|
||||
}
|
||||
|
||||
static inline bool bitv_val(const bitv_t *bv, uint32_t i)
|
||||
{
|
||||
return 0 != (bv[index2offset(i)] & index2bit(i));
|
||||
}
|
||||
|
||||
static inline void bitv_toggle(bitv_t *bv, uint32_t i)
|
||||
{
|
||||
bv[index2offset(i)] ^= index2bit(i);
|
||||
}
|
||||
|
||||
static inline void bitv_assign_range(bitv_t *bv, uint32_t i, uint32_t n,
|
||||
bool val)
|
||||
{
|
||||
while (n--)
|
||||
bitv_assign(bv, i+n, val);
|
||||
}
|
18
include/re_conf.h
Normal file
18
include/re_conf.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
/**
|
||||
* @file re_conf.h Interface to configuration
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
struct conf;
|
||||
|
||||
typedef int (conf_h)(const struct pl *val, void *arg);
|
||||
|
||||
int conf_alloc(struct conf **confp, const char *filename);
|
||||
int conf_alloc_buf(struct conf **confp, const uint8_t *buf, size_t sz);
|
||||
int conf_get(struct conf *conf, const char *name, struct pl *pl);
|
||||
int conf_get_str(struct conf *conf, const char *name, char *str,
|
||||
size_t size);
|
||||
int conf_get_u32(struct conf *conf, const char *name, uint32_t *num);
|
||||
int conf_apply(struct conf *conf, const char *name, conf_h *ch, void *arg);
|
12
include/re_crc32.h
Normal file
12
include/re_crc32.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
/**
|
||||
* @file re_crc32.h Interface to CRC-32 functions
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
#ifdef USE_ZLIB
|
||||
#include <zlib.h>
|
||||
#else
|
||||
uint32_t crc32(uint32_t crc, const void *buf, uint32_t size);
|
||||
#endif
|
193
include/re_dbg.h
Normal file
193
include/re_dbg.h
Normal file
|
@ -0,0 +1,193 @@
|
|||
/**
|
||||
* @file re_dbg.h Interface to debugging module
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Debug levels */
|
||||
enum {
|
||||
DBG_EMERG = 0, /**< System is unusable */
|
||||
DBG_ALERT = 1, /**< Action must be taken immediately */
|
||||
DBG_CRIT = 2, /**< Critical conditions */
|
||||
DBG_ERR = 3, /**< Error conditions */
|
||||
DBG_WARNING = 4, /**< Warning conditions */
|
||||
DBG_NOTICE = 5, /**< Normal but significant condition */
|
||||
DBG_INFO = 6, /**< Informational */
|
||||
DBG_DEBUG = 7 /**< Debug-level messages */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @def DEBUG_MODULE
|
||||
*
|
||||
* Module name defined by application
|
||||
*/
|
||||
|
||||
/**
|
||||
* @def DEBUG_LEVEL
|
||||
*
|
||||
* Debug level defined by application
|
||||
*/
|
||||
|
||||
#ifndef DEBUG_MODULE
|
||||
# warning "DEBUG_MODULE is not defined"
|
||||
#define DEBUG_MODULE "?"
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG_LEVEL
|
||||
# warning "DEBUG_LEVEL is not defined"
|
||||
#define DEBUG_LEVEL 7
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @def DEBUG_WARNING(...)
|
||||
*
|
||||
* Print warning message
|
||||
*/
|
||||
|
||||
/**
|
||||
* @def DEBUG_NOTICE(...)
|
||||
*
|
||||
* Print notice message
|
||||
*/
|
||||
|
||||
/**
|
||||
* @def DEBUG_INFO(...)
|
||||
*
|
||||
* Print info message
|
||||
*/
|
||||
|
||||
/**
|
||||
* @def DEBUG_PRINTF(...)
|
||||
*
|
||||
* Print debug message
|
||||
*/
|
||||
|
||||
|
||||
/* Check for ISO C99 variable argument macros */
|
||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) \
|
||||
|| (__GNUC__ >= 3)
|
||||
|
||||
#if (DEBUG_LEVEL >= 4)
|
||||
#define DEBUG_WARNING(...) \
|
||||
dbg_printf(DBG_WARNING, DEBUG_MODULE ": " __VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_WARNING(...)
|
||||
#endif
|
||||
|
||||
#if (DEBUG_LEVEL >= 5)
|
||||
#define DEBUG_NOTICE(...) \
|
||||
dbg_printf(DBG_NOTICE, DEBUG_MODULE ": " __VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_NOTICE(...)
|
||||
#endif
|
||||
|
||||
#if (DEBUG_LEVEL >= 6)
|
||||
#define DEBUG_INFO(...) \
|
||||
dbg_printf(DBG_INFO, DEBUG_MODULE ": " __VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_INFO(...)
|
||||
#endif
|
||||
|
||||
#if (DEBUG_LEVEL >= 7)
|
||||
#define DEBUG_PRINTF(...) \
|
||||
dbg_printf(DBG_DEBUG, DEBUG_MODULE ": " __VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_PRINTF(...)
|
||||
#endif
|
||||
|
||||
/* GNU extensions for variable argument macros */
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
#if (DEBUG_LEVEL >= 4)
|
||||
#define DEBUG_WARNING(a...) dbg_printf(DBG_WARNING, DEBUG_MODULE ": " a)
|
||||
#else
|
||||
#define DEBUG_WARNING(a...)
|
||||
#endif
|
||||
|
||||
#if (DEBUG_LEVEL >= 5)
|
||||
#define DEBUG_NOTICE(a...) dbg_printf(DBG_NOTICE, DEBUG_MODULE ": " a)
|
||||
#else
|
||||
#define DEBUG_NOTICE(a...)
|
||||
#endif
|
||||
|
||||
#if (DEBUG_LEVEL >= 6)
|
||||
#define DEBUG_INFO(a...) dbg_printf(DBG_INFO, DEBUG_MODULE ": " a)
|
||||
#else
|
||||
#define DEBUG_INFO(a...)
|
||||
#endif
|
||||
|
||||
#if (DEBUG_LEVEL >= 7)
|
||||
#define DEBUG_PRINTF(a...) dbg_printf(DBG_DEBUG, DEBUG_MODULE ": " a)
|
||||
#else
|
||||
#define DEBUG_PRINTF(a...)
|
||||
#endif
|
||||
|
||||
/* No variable argument macros */
|
||||
#else
|
||||
|
||||
#if (DEBUG_LEVEL >= 4)
|
||||
#define DEBUG_WARNING dbg_warning
|
||||
#else
|
||||
#define DEBUG_WARNING dbg_noprintf
|
||||
#endif
|
||||
|
||||
#if (DEBUG_LEVEL >= 5)
|
||||
#define DEBUG_NOTICE dbg_notice
|
||||
#else
|
||||
#define DEBUG_NOTICE dbg_noprintf
|
||||
#endif
|
||||
|
||||
#if (DEBUG_LEVEL >= 6)
|
||||
#define DEBUG_INFO dbg_info
|
||||
#else
|
||||
#define DEBUG_INFO dbg_noprintf
|
||||
#endif
|
||||
|
||||
#if (DEBUG_LEVEL >= 7)
|
||||
#define DEBUG_PRINTF dbg_noprintf
|
||||
#else
|
||||
#define DEBUG_PRINTF dbg_noprintf
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/** Debug flags */
|
||||
enum dbg_flags {
|
||||
DBG_NONE = 0, /**< No debug flags */
|
||||
DBG_TIME = 1<<0, /**< Print timestamp flag */
|
||||
DBG_ANSI = 1<<1, /**< Print ANSI color codes */
|
||||
DBG_ALL = DBG_TIME|DBG_ANSI /**< All flags enabled */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Defines the debug print handler
|
||||
*
|
||||
* @param level Debug level
|
||||
* @param p Debug string
|
||||
* @param len String length
|
||||
* @param arg Handler argument
|
||||
*/
|
||||
typedef void (dbg_print_h)(int level, const char *p, size_t len, void *arg);
|
||||
|
||||
void dbg_init(int level, enum dbg_flags flags);
|
||||
void dbg_close(void);
|
||||
int dbg_logfile_set(const char *name);
|
||||
void dbg_handler_set(dbg_print_h *ph, void *arg);
|
||||
void dbg_printf(int level, const char *fmt, ...);
|
||||
void dbg_noprintf(const char *fmt, ...);
|
||||
void dbg_warning(const char *fmt, ...);
|
||||
void dbg_notice(const char *fmt, ...);
|
||||
void dbg_info(const char *fmt, ...);
|
||||
const char *dbg_level_str(int level);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
192
include/re_dns.h
Normal file
192
include/re_dns.h
Normal file
|
@ -0,0 +1,192 @@
|
|||
/**
|
||||
* @file re_dns.h Interface to DNS module
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
enum {
|
||||
DNS_PORT = 53,
|
||||
DNS_HEADER_SIZE = 12
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
DNS_OPCODE_QUERY = 0,
|
||||
DNS_OPCODE_IQUERY = 1,
|
||||
DNS_OPCODE_STATUS = 2,
|
||||
DNS_OPCODE_NOTIFY = 4
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
DNS_RCODE_OK = 0,
|
||||
DNS_RCODE_FMT_ERR = 1,
|
||||
DNS_RCODE_SRV_FAIL = 2,
|
||||
DNS_RCODE_NAME_ERR = 3,
|
||||
DNS_RCODE_NOT_IMPL = 4,
|
||||
DNS_RCODE_REFUSED = 5,
|
||||
DNS_RCODE_NOT_AUTH = 9
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
DNS_TYPE_A = 0x0001,
|
||||
DNS_TYPE_NS = 0x0002,
|
||||
DNS_TYPE_CNAME = 0x0005,
|
||||
DNS_TYPE_SOA = 0x0006,
|
||||
DNS_TYPE_PTR = 0x000c,
|
||||
DNS_TYPE_MX = 0x000f,
|
||||
DNS_TYPE_AAAA = 0x001c,
|
||||
DNS_TYPE_SRV = 0x0021,
|
||||
DNS_TYPE_NAPTR = 0x0023,
|
||||
DNS_QTYPE_IXFR = 0x00fb,
|
||||
DNS_QTYPE_AXFR = 0x00fc,
|
||||
DNS_QTYPE_ANY = 0x00ff
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
DNS_CLASS_IN = 0x0001,
|
||||
DNS_QCLASS_ANY = 0x00ff
|
||||
};
|
||||
|
||||
|
||||
struct dnshdr {
|
||||
uint16_t id;
|
||||
bool qr;
|
||||
uint8_t opcode;
|
||||
bool aa;
|
||||
bool tc;
|
||||
bool rd;
|
||||
bool ra;
|
||||
uint8_t z;
|
||||
uint8_t rcode;
|
||||
uint16_t nq;
|
||||
uint16_t nans;
|
||||
uint16_t nauth;
|
||||
uint16_t nadd;
|
||||
};
|
||||
|
||||
|
||||
struct dnsrr {
|
||||
struct le le;
|
||||
struct le le_priv;
|
||||
char *name;
|
||||
uint16_t type;
|
||||
uint16_t dnsclass;
|
||||
int64_t ttl;
|
||||
uint16_t rdlen;
|
||||
union {
|
||||
struct {
|
||||
uint32_t addr;
|
||||
} a;
|
||||
struct {
|
||||
char *nsdname;
|
||||
} ns;
|
||||
struct {
|
||||
char *cname;
|
||||
} cname;
|
||||
struct {
|
||||
char *mname;
|
||||
char *rname;
|
||||
uint32_t serial;
|
||||
uint32_t refresh;
|
||||
uint32_t retry;
|
||||
uint32_t expire;
|
||||
uint32_t ttlmin;
|
||||
} soa;
|
||||
struct {
|
||||
char *ptrdname;
|
||||
} ptr;
|
||||
struct {
|
||||
uint16_t pref;
|
||||
char *exchange;
|
||||
} mx;
|
||||
struct {
|
||||
uint8_t addr[16];
|
||||
} aaaa;
|
||||
struct {
|
||||
uint16_t pri;
|
||||
uint16_t weight;
|
||||
uint16_t port;
|
||||
char *target;
|
||||
} srv;
|
||||
struct {
|
||||
uint16_t order;
|
||||
uint16_t pref;
|
||||
char *flags;
|
||||
char *services;
|
||||
char *regexp;
|
||||
char *replace;
|
||||
} naptr;
|
||||
} rdata;
|
||||
};
|
||||
|
||||
struct hash;
|
||||
|
||||
typedef void(dns_query_h)(int err, const struct dnshdr *hdr,
|
||||
struct list *ansl, struct list *authl,
|
||||
struct list *addl, void *arg);
|
||||
typedef bool(dns_rrlist_h)(struct dnsrr *rr, void *arg);
|
||||
|
||||
int dns_hdr_encode(struct mbuf *mb, const struct dnshdr *hdr);
|
||||
int dns_hdr_decode(struct mbuf *mb, struct dnshdr *hdr);
|
||||
const char *dns_hdr_opcodename(uint8_t opcode);
|
||||
const char *dns_hdr_rcodename(uint8_t rcode);
|
||||
struct dnsrr *dns_rr_alloc(void);
|
||||
int dns_rr_encode(struct mbuf *mb, const struct dnsrr *rr, int64_t ttl_offs,
|
||||
struct hash *ht_dname, size_t start);
|
||||
int dns_rr_decode(struct mbuf *mb, struct dnsrr **rr, size_t start);
|
||||
bool dns_rr_cmp(const struct dnsrr *rr1, const struct dnsrr *rr2, bool rdata);
|
||||
const char *dns_rr_typename(uint16_t type);
|
||||
const char *dns_rr_classname(uint16_t dnsclass);
|
||||
int dns_rr_print(struct re_printf *pf, const struct dnsrr *rr);
|
||||
int dns_dname_encode(struct mbuf *mb, const char *name,
|
||||
struct hash *ht_dname, size_t start, bool comp);
|
||||
int dns_dname_decode(struct mbuf *mb, char **name, size_t start);
|
||||
int dns_cstr_encode(struct mbuf *mb, const char *str);
|
||||
int dns_cstr_decode(struct mbuf *mb, char **str);
|
||||
void dns_rrlist_sort(struct list *rrl, uint16_t type);
|
||||
struct dnsrr *dns_rrlist_apply(struct list *rrl, const char *name,
|
||||
uint16_t type, uint16_t dnsclass,
|
||||
bool recurse, dns_rrlist_h *rrlh, void *arg);
|
||||
struct dnsrr *dns_rrlist_apply2(struct list *rrl, const char *name,
|
||||
uint16_t type1, uint16_t type2,
|
||||
uint16_t dnsclass, bool recurse,
|
||||
dns_rrlist_h *rrlh, void *arg);
|
||||
struct dnsrr *dns_rrlist_find(struct list *rrl, const char *name,
|
||||
uint16_t type, uint16_t dnsclass, bool recurse);
|
||||
|
||||
|
||||
/* DNS Client */
|
||||
struct sa;
|
||||
struct dnsc;
|
||||
struct dns_query;
|
||||
|
||||
struct dnsc_conf {
|
||||
uint32_t query_hash_size;
|
||||
uint32_t tcp_hash_size;
|
||||
uint32_t conn_timeout; /* in [ms] */
|
||||
uint32_t idle_timeout; /* in [ms] */
|
||||
bool udp_conn;
|
||||
};
|
||||
|
||||
int dnsc_alloc(struct dnsc **dcpp, const struct dnsc_conf *conf,
|
||||
const struct sa *srvv, uint32_t srvc);
|
||||
int dnsc_srv_set(struct dnsc *dnsc, const struct sa *srvv, uint32_t srvc);
|
||||
int dnsc_query(struct dns_query **qp, struct dnsc *dnsc, const char *name,
|
||||
uint16_t type, uint16_t dnsclass,
|
||||
bool rd, dns_query_h *qh, void *arg);
|
||||
int dnsc_query_srv(struct dns_query **qp, struct dnsc *dnsc, const char *name,
|
||||
uint16_t type, uint16_t dnsclass, int proto,
|
||||
const struct sa *srvv, const uint32_t *srvc,
|
||||
bool rd, dns_query_h *qh, void *arg);
|
||||
int dnsc_notify(struct dns_query **qp, struct dnsc *dnsc, const char *name,
|
||||
uint16_t type, uint16_t dnsclass, const struct dnsrr *ans_rr,
|
||||
int proto, const struct sa *srvv, const uint32_t *srvc,
|
||||
dns_query_h *qh, void *arg);
|
||||
|
||||
|
||||
/* DNS System functions */
|
||||
int dns_srv_get(char *domain, size_t dsize, struct sa *srvv, uint32_t *n);
|
118
include/re_fmt.h
Normal file
118
include/re_fmt.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
/**
|
||||
* @file re_fmt.h Interface to formatted text functions
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
struct mbuf;
|
||||
|
||||
|
||||
/** Defines a pointer-length string type */
|
||||
struct pl {
|
||||
const char *p; /**< Pointer to string */
|
||||
size_t l; /**< Length of string */
|
||||
};
|
||||
|
||||
/** Initialise a pointer-length object from a constant string */
|
||||
#define PL(s) {(s), sizeof((s))-1}
|
||||
|
||||
/** Pointer-length Initializer */
|
||||
#define PL_INIT {NULL, 0}
|
||||
|
||||
extern const struct pl pl_null;
|
||||
|
||||
void pl_set_str(struct pl *pl, const char *str);
|
||||
void pl_set_mbuf(struct pl *pl, const struct mbuf *mb);
|
||||
uint32_t pl_u32(const struct pl *pl);
|
||||
uint32_t pl_x32(const struct pl *pl);
|
||||
uint64_t pl_u64(const struct pl *pl);
|
||||
bool pl_isset(const struct pl *pl);
|
||||
int pl_strcpy(const struct pl *pl, char *str, size_t size);
|
||||
int pl_strdup(char **dst, const struct pl *src);
|
||||
int pl_dup(struct pl *dst, const struct pl *src);
|
||||
int pl_strcmp(const struct pl *pl, const char *str);
|
||||
int pl_strcasecmp(const struct pl *pl, const char *str);
|
||||
int pl_cmp(const struct pl *pl1, const struct pl *pl2);
|
||||
int pl_casecmp(const struct pl *pl1, const struct pl *pl2);
|
||||
const char *pl_strchr(const struct pl *pl, char c);
|
||||
|
||||
/** Advance pl position/length by +/- N bytes */
|
||||
static inline void pl_advance(struct pl *pl, ssize_t n)
|
||||
{
|
||||
pl->p += n;
|
||||
pl->l -= n;
|
||||
}
|
||||
|
||||
|
||||
/* Formatted printing */
|
||||
|
||||
/**
|
||||
* Defines the re_vhprintf() print handler
|
||||
*
|
||||
* @param p String to print
|
||||
* @param size Size of string to print
|
||||
* @param arg Handler argument
|
||||
*/
|
||||
typedef int(re_vprintf_h)(const char *p, size_t size, void *arg);
|
||||
|
||||
/** Defines a print backend */
|
||||
struct re_printf {
|
||||
re_vprintf_h *vph; /**< Print handler */
|
||||
void *arg; /**< Handler agument */
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines the %H print handler
|
||||
*
|
||||
* @param pf Print backend
|
||||
* @param arg Handler argument
|
||||
*/
|
||||
typedef int(re_printf_h)(struct re_printf *pf, void *arg);
|
||||
|
||||
int re_vhprintf(const char *fmt, va_list ap, re_vprintf_h *vph, void *arg);
|
||||
int re_vfprintf(FILE *stream, const char *fmt, va_list ap);
|
||||
int re_vprintf(const char *fmt, va_list ap);
|
||||
int re_vsnprintf(char *str, size_t size, const char *fmt, va_list ap);
|
||||
int re_vsdprintf(char **strp, const char *fmt, va_list ap);
|
||||
|
||||
int re_hprintf(struct re_printf *pf, const char *fmt, ...);
|
||||
int re_fprintf(FILE *stream, const char *fmt, ...);
|
||||
int re_printf(const char *fmt, ...);
|
||||
int re_snprintf(char *str, size_t size, const char *fmt, ...);
|
||||
int re_sdprintf(char **strp, const char *fmt, ...);
|
||||
|
||||
|
||||
/* Regular expressions */
|
||||
int re_regex(const char *ptr, size_t len, const char *expr, ...);
|
||||
|
||||
|
||||
/* Character functions */
|
||||
uint8_t ch_hex(char ch);
|
||||
|
||||
|
||||
/* String functions */
|
||||
int str_hex(uint8_t *hex, size_t len, const char *str);
|
||||
void str_ncpy(char *dst, const char *src, size_t n);
|
||||
int str_dup(char **dst, const char *src);
|
||||
int str_casecmp(const char *s1, const char *s2);
|
||||
size_t str_len(const char *s);
|
||||
|
||||
|
||||
/* time */
|
||||
int fmt_human_time(struct re_printf *pf, const uint32_t *seconds);
|
||||
|
||||
|
||||
void hexdump(FILE *f, const void *p, size_t len);
|
||||
|
||||
|
||||
/* param */
|
||||
typedef void (fmt_param_h)(const struct pl *name, const struct pl *val,
|
||||
void *arg);
|
||||
|
||||
bool fmt_param_get(const struct pl *pl, const char *pname, struct pl *val);
|
||||
void fmt_param_apply(const struct pl *pl, fmt_param_h *ph, void *arg);
|
47
include/re_g711.h
Normal file
47
include/re_g711.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* @file re_g711.h Interface to G.711 codec
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
extern const uint8_t g711_l2u[4096];
|
||||
extern const uint8_t g711_l2A[2048];
|
||||
extern const int16_t g711_u2l[256];
|
||||
extern const int16_t g711_A2l[256];
|
||||
|
||||
|
||||
static inline uint8_t g711_pcm2ulaw(int16_t l)
|
||||
{
|
||||
const uint8_t mask = (l < 0) ? 0x7f : 0xff;
|
||||
if (l < 0)
|
||||
l = -l;
|
||||
if (l < 4)
|
||||
return 0xff & mask;
|
||||
l -= 4;
|
||||
l >>= 3;
|
||||
|
||||
return g711_l2u[l] & mask;
|
||||
}
|
||||
|
||||
|
||||
static inline uint8_t g711_pcm2alaw(int16_t l)
|
||||
{
|
||||
const uint8_t mask = (l < 0) ? 0x7f : 0xff;
|
||||
if (l < 0)
|
||||
l = -l;
|
||||
l >>= 4;
|
||||
|
||||
return g711_l2A[l] & mask;
|
||||
}
|
||||
|
||||
|
||||
static inline int16_t g711_ulaw2pcm(uint8_t u)
|
||||
{
|
||||
return g711_u2l[u];
|
||||
}
|
||||
|
||||
|
||||
static inline int16_t g711_alaw2pcm(uint8_t a)
|
||||
{
|
||||
return g711_A2l[a];
|
||||
}
|
29
include/re_hash.h
Normal file
29
include/re_hash.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* @file re_hash.h Interface to hashmap table
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
struct hash;
|
||||
struct pl;
|
||||
|
||||
|
||||
int hash_alloc(struct hash **hp, uint32_t bsize);
|
||||
void hash_append(struct hash *h, uint32_t key, struct le *le, void *data);
|
||||
void hash_unlink(struct le *le);
|
||||
struct le *hash_lookup(const struct hash *h, uint32_t key, list_apply_h *ah,
|
||||
void *arg);
|
||||
struct le *hash_apply(const struct hash *h, list_apply_h *ah, void *arg);
|
||||
struct list *hash_list(const struct hash *h, uint32_t key);
|
||||
uint32_t hash_bsize(const struct hash *h);
|
||||
void hash_flush(struct hash *h);
|
||||
|
||||
|
||||
/* Hash functions */
|
||||
uint32_t hash_joaat(const uint8_t *key, size_t len);
|
||||
uint32_t hash_joaat_ci(const char *str, size_t len);
|
||||
uint32_t hash_joaat_str(const char *str);
|
||||
uint32_t hash_joaat_str_ci(const char *str);
|
||||
uint32_t hash_joaat_pl(const struct pl *pl);
|
||||
uint32_t hash_joaat_pl_ci(const struct pl *pl);
|
13
include/re_hmac.h
Normal file
13
include/re_hmac.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* @file re_hmac.h Interface to HMAC functions
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
void hmac_sha1(const uint8_t *k, /* secret key */
|
||||
size_t lk, /* length of the key in bytes */
|
||||
const uint8_t *d, /* data */
|
||||
size_t ld, /* length of data in bytes */
|
||||
uint8_t* out, /* output buffer, at least "t" bytes */
|
||||
size_t t);
|
58
include/re_httpauth.h
Normal file
58
include/re_httpauth.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* @file re_httpauth.h Interface to HTTP Authentication
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
/** Authentication type */
|
||||
enum httpauth_hdr {
|
||||
HTTPAUTH_WWW,
|
||||
HTTPAUTH_PROXY
|
||||
};
|
||||
|
||||
|
||||
/* Client code */
|
||||
struct httpauth_digest_chall {
|
||||
enum httpauth_hdr hdr;
|
||||
struct pl realm;
|
||||
struct pl nonce;
|
||||
|
||||
/* optional */
|
||||
struct pl opaque;
|
||||
struct pl stale;
|
||||
struct pl algorithm;
|
||||
struct pl qop;
|
||||
};
|
||||
|
||||
int httpauth_digest_challenge_decode(struct httpauth_digest_chall *chall,
|
||||
const struct pl *hval);
|
||||
int httpauth_digest_response_encode(struct mbuf *mb, const struct pl *hname,
|
||||
const struct httpauth_digest_chall *chall,
|
||||
const struct pl *username,
|
||||
const struct pl *uri,
|
||||
const struct pl *cnonce,
|
||||
const struct pl *qop,
|
||||
const struct pl *nc,
|
||||
const uint8_t *digest);
|
||||
|
||||
|
||||
/* Server code */
|
||||
struct httpauth_digest_resp {
|
||||
struct pl realm;
|
||||
struct pl nonce;
|
||||
struct pl response;
|
||||
struct pl nc;
|
||||
struct pl cnonce;
|
||||
struct pl qop;
|
||||
struct pl username;
|
||||
struct pl uri;
|
||||
};
|
||||
|
||||
int httpauth_digest_authenticate(struct httpauth_digest_resp *resp,
|
||||
bool *auth, const struct pl *method,
|
||||
const char *ha1);
|
||||
int httpauth_digest_decode_response(struct httpauth_digest_resp *resp,
|
||||
const struct pl *hval);
|
||||
int httpauth_digest_encode_challenge(struct mbuf *mb, const struct pl *hname,
|
||||
const struct pl *realm);
|
67
include/re_ice.h
Normal file
67
include/re_ice.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* @file re_ice.h Interface to Interactive Connectivity Establishment (ICE)
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
enum ice_mode {
|
||||
ICE_MODE_FULL,
|
||||
ICE_MODE_LITE
|
||||
};
|
||||
|
||||
enum ice_compid {
|
||||
ICE_COMPID_RTP = 1,
|
||||
ICE_COMPID_RTCP = 2
|
||||
};
|
||||
|
||||
struct ice;
|
||||
struct icem;
|
||||
|
||||
typedef void (ice_gather_h)(int err, uint16_t scode, const char *reason,
|
||||
void *arg);
|
||||
typedef void (ice_connchk_h)(int err, bool update, void *arg);
|
||||
|
||||
|
||||
/* ICE Session */
|
||||
int ice_alloc(struct ice **icep, enum ice_mode mode, bool offerer);
|
||||
void ice_set_offerer(struct ice *ice, bool offerer);
|
||||
int ice_sdp_decode(struct ice *ice, const char *name, const char *value);
|
||||
int ice_conncheck_start(struct ice *ice);
|
||||
int ice_debug(struct re_printf *pf, const struct ice *ice);
|
||||
struct list *ice_medialist(const struct ice *ice);
|
||||
const char *ice_ufrag(const struct ice *ice);
|
||||
const char *ice_pwd(const struct ice *ice);
|
||||
|
||||
|
||||
/* ICE Media */
|
||||
int icem_alloc(struct icem **icemp, struct ice *ice, int proto, int layer,
|
||||
ice_gather_h *gh, ice_connchk_h *chkh, void *arg);
|
||||
int icem_comp_add(struct icem *icem, uint8_t compid, void *sock);
|
||||
int icem_cand_add(struct icem *icem, uint8_t compid, uint16_t lprio,
|
||||
const char *ifname, const struct sa *addr);
|
||||
int icem_gather_srflx(struct icem *icem, const struct sa *stun_srv);
|
||||
int icem_gather_relay(struct icem *icem, const struct sa *stun_srv,
|
||||
const char *username, const char *password);
|
||||
bool icem_verify_support(struct icem *icem, uint8_t compid,
|
||||
const struct sa *raddr);
|
||||
int icem_add_chan(struct icem *icem, uint8_t compid, const struct sa *raddr);
|
||||
bool icem_mismatch(const struct icem *icem);
|
||||
int icem_sdp_decode(struct icem *icem, const char *name, const char *value);
|
||||
int icem_debug(struct re_printf *pf, const struct icem *icem);
|
||||
struct list *icem_lcandl(const struct icem *icem);
|
||||
const struct sa *icem_cand_default(struct icem *icem, uint8_t compid);
|
||||
const struct sa *icem_selected_laddr(const struct icem *icem, uint8_t compid);
|
||||
|
||||
|
||||
struct cand;
|
||||
bool ice_remotecands_avail(const struct icem *icem);
|
||||
int ice_cand_encode(struct re_printf *pf, const struct cand *cand);
|
||||
int ice_remotecands_encode(struct re_printf *pf, const struct icem *icem);
|
||||
|
||||
|
||||
extern const char ice_attr_cand[];
|
||||
extern const char ice_attr_lite[];
|
||||
extern const char ice_attr_mismatch[];
|
||||
extern const char ice_attr_pwd[];
|
||||
extern const char ice_attr_remote_cand[];
|
||||
extern const char ice_attr_ufrag[];
|
28
include/re_jbuf.h
Normal file
28
include/re_jbuf.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* @file re_jbuf.h Interface to Jitter Buffer
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
struct jbuf;
|
||||
struct rtp_header;
|
||||
|
||||
/** Jitter buffer statistics */
|
||||
struct jbuf_stat {
|
||||
uint32_t n_put; /**< Number of frames put into jitter buffer */
|
||||
uint32_t n_get; /**< Number of frames got from jitter buffer */
|
||||
uint32_t n_oos; /**< Number of out-of-sequence frames */
|
||||
uint32_t n_dups; /**< Number of duplicate frames detected */
|
||||
uint32_t n_late; /**< Number of frames arriving too late */
|
||||
uint32_t n_lost; /**< Number of lost frames */
|
||||
uint32_t n_overflow; /**< Number of overflows */
|
||||
uint32_t n_underflow; /**< Number of underflows */
|
||||
uint32_t n_flush; /**< Number of times jitter buffer flushed */
|
||||
};
|
||||
|
||||
|
||||
int jbuf_alloc(struct jbuf **jbp, uint32_t min, uint32_t max);
|
||||
int jbuf_put(struct jbuf *jb, const struct rtp_header *hdr, void *mem);
|
||||
int jbuf_get(struct jbuf *jb, struct rtp_header *hdr, void **mem);
|
||||
void jbuf_flush(struct jbuf *jb);
|
||||
int jbuf_stats(const struct jbuf *jb, struct jbuf_stat *jstat);
|
||||
int jbuf_debug(struct re_printf *pf, const struct jbuf *jb);
|
95
include/re_list.h
Normal file
95
include/re_list.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
/**
|
||||
* @file re_list.h Interface to Linked List
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
/** Linked-list element */
|
||||
struct le {
|
||||
struct le *prev; /**< Previous element */
|
||||
struct le *next; /**< Next element */
|
||||
struct list *list; /**< Parent list (NULL if not linked-in) */
|
||||
void *data; /**< User-data */
|
||||
};
|
||||
|
||||
/** List Element Initializer */
|
||||
#define LE_INIT {NULL, NULL, NULL, NULL}
|
||||
|
||||
|
||||
/** Defines a linked list */
|
||||
struct list {
|
||||
struct le *head; /**< First list element */
|
||||
struct le *tail; /**< Last list element */
|
||||
};
|
||||
|
||||
/** Linked list Initializer */
|
||||
#define LIST_INIT {NULL, NULL}
|
||||
|
||||
|
||||
/**
|
||||
* Defines the list apply handler
|
||||
*
|
||||
* @param le List element
|
||||
* @param arg Handler argument
|
||||
*
|
||||
* @return true to stop traversing, false to continue
|
||||
*/
|
||||
typedef bool (list_apply_h)(struct le *le, void *arg);
|
||||
|
||||
/**
|
||||
* Defines the list sort handler
|
||||
*
|
||||
* @param le1 Current list element
|
||||
* @param le2 Next list element
|
||||
* @param arg Handler argument
|
||||
*
|
||||
* @return true if sorted, otherwise false
|
||||
*/
|
||||
typedef bool (list_sort_h)(struct le *le1, struct le *le2, void *arg);
|
||||
|
||||
|
||||
void list_init(struct list *list);
|
||||
void list_flush(struct list *list);
|
||||
void list_append(struct list *list, struct le *le, void *data);
|
||||
void list_prepend(struct list *list, struct le *le, void *data);
|
||||
void list_insert_before(struct list *list, struct le *le, struct le *ile,
|
||||
void *data);
|
||||
void list_insert_after(struct list *list, struct le *le, struct le *ile,
|
||||
void *data);
|
||||
void list_unlink(struct le *le);
|
||||
void list_sort(struct list *list, list_sort_h *sh, void *arg);
|
||||
struct le *list_apply(const struct list *list, bool fwd, list_apply_h *ah,
|
||||
void *arg);
|
||||
struct le *list_head(const struct list *list);
|
||||
struct le *list_tail(const struct list *list);
|
||||
uint32_t list_count(const struct list *list);
|
||||
|
||||
|
||||
/**
|
||||
* Get the user-data from a list element
|
||||
*
|
||||
* @param le List element
|
||||
*
|
||||
* @return Pointer to user-data
|
||||
*/
|
||||
static inline void *list_ledata(const struct le *le)
|
||||
{
|
||||
return le ? le->data : NULL;
|
||||
}
|
||||
|
||||
|
||||
static inline bool list_contains(const struct list *list, const struct le *le)
|
||||
{
|
||||
return le ? le->list == list : false;
|
||||
}
|
||||
|
||||
|
||||
static inline bool list_isempty(const struct list *list)
|
||||
{
|
||||
return list ? list->head == NULL : true;
|
||||
}
|
||||
|
||||
|
||||
#define LIST_FOREACH(list, le) \
|
||||
for ((le) = list_head((list)); (le); (le) = (le)->next)
|
18
include/re_lock.h
Normal file
18
include/re_lock.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
/**
|
||||
* @file re_lock.h Interface to locking functions
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
struct lock;
|
||||
|
||||
int lock_alloc(struct lock **lp);
|
||||
|
||||
void lock_read_get(struct lock *l);
|
||||
void lock_write_get(struct lock *l);
|
||||
|
||||
int lock_read_try(struct lock *l);
|
||||
int lock_write_try(struct lock *l);
|
||||
|
||||
void lock_rel(struct lock *l);
|
67
include/re_main.h
Normal file
67
include/re_main.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* @file re_main.h Interface to main polling routine
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
enum {
|
||||
#ifndef FD_READ
|
||||
FD_READ = 1<<0,
|
||||
#endif
|
||||
#ifndef FD_WRITE
|
||||
FD_WRITE = 1<<1,
|
||||
#endif
|
||||
FD_EXCEPT = 1<<2
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* File descriptor event handler
|
||||
*
|
||||
* @param flags Event flags
|
||||
* @param arg Handler argument
|
||||
*/
|
||||
typedef void (fd_h)(int flags, void *arg);
|
||||
|
||||
/**
|
||||
* Thread-safe signal handler
|
||||
*
|
||||
* @param sig Signal number
|
||||
*/
|
||||
typedef void (re_signal_h)(int sig);
|
||||
|
||||
|
||||
int fd_listen(int fd, int flags, fd_h *fh, void *arg);
|
||||
void fd_close(int fd);
|
||||
int fd_setsize(int maxfds);
|
||||
void fd_debug(void);
|
||||
|
||||
int libre_init(void);
|
||||
void libre_close(void);
|
||||
|
||||
int re_main(re_signal_h *signalh);
|
||||
void re_cancel(void);
|
||||
int re_debug(struct re_printf *pf, void *unused);
|
||||
|
||||
int re_thread_init(void);
|
||||
void re_thread_close(void);
|
||||
void re_thread_enter(void);
|
||||
void re_thread_leave(void);
|
||||
|
||||
|
||||
/** Polling methods */
|
||||
enum poll_method {
|
||||
METHOD_NULL = 0,
|
||||
METHOD_POLL,
|
||||
METHOD_SELECT,
|
||||
METHOD_EPOLL,
|
||||
METHOD_ACTSCHED,
|
||||
/* sep */
|
||||
METHOD_MAX
|
||||
};
|
||||
|
||||
int poll_method_set(enum poll_method method);
|
||||
enum poll_method poll_method_best(void);
|
||||
const char *poll_method_name(enum poll_method method);
|
||||
int poll_method_type(enum poll_method *method, const struct pl *name);
|
165
include/re_mbuf.h
Normal file
165
include/re_mbuf.h
Normal file
|
@ -0,0 +1,165 @@
|
|||
/**
|
||||
* @file re_mbuf.h Interface to memory buffers
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
#ifndef RELEASE
|
||||
#define MBUF_DEBUG 1 /**< Mbuf debugging (0 or 1) */
|
||||
#endif
|
||||
|
||||
#if MBUF_DEBUG
|
||||
/** Check that mbuf position does not exceed end */
|
||||
#define MBUF_CHECK_POS(mb) \
|
||||
if ((mb) && (mb)->pos > (mb)->end) { \
|
||||
BREAKPOINT; \
|
||||
}
|
||||
/** Check that mbuf end does not exceed size */
|
||||
#define MBUF_CHECK_END(mb) \
|
||||
if ((mb) && (mb)->end > (mb)->size) { \
|
||||
BREAKPOINT; \
|
||||
}
|
||||
#else
|
||||
#define MBUF_CHECK_POS(mb)
|
||||
#define MBUF_CHECK_END(mb)
|
||||
#endif
|
||||
|
||||
/** Defines a memory buffer */
|
||||
struct mbuf {
|
||||
uint8_t *buf; /**< Buffer memory */
|
||||
size_t size; /**< Size of buffer */
|
||||
size_t pos; /**< Position in buffer */
|
||||
size_t end; /**< End of buffer */
|
||||
};
|
||||
|
||||
|
||||
struct pl;
|
||||
|
||||
struct mbuf *mbuf_alloc(size_t size);
|
||||
struct mbuf *mbuf_alloc_ref(struct mbuf *mbr);
|
||||
void mbuf_init(struct mbuf *mb);
|
||||
void mbuf_reset(struct mbuf *mb);
|
||||
int mbuf_resize(struct mbuf *mb, size_t size);
|
||||
void mbuf_trim(struct mbuf *mb);
|
||||
int mbuf_write_mem(struct mbuf *mb, const uint8_t *buf, size_t size);
|
||||
int mbuf_write_u8(struct mbuf *mb, uint8_t v);
|
||||
int mbuf_write_u16(struct mbuf *mb, uint16_t v);
|
||||
int mbuf_write_u32(struct mbuf *mb, uint32_t v);
|
||||
int mbuf_write_u64(struct mbuf *mb, uint64_t v);
|
||||
int mbuf_write_str(struct mbuf *mb, const char *str);
|
||||
int mbuf_write_pl(struct mbuf *mb, const struct pl *pl);
|
||||
int mbuf_read_mem(struct mbuf *mb, uint8_t *buf, size_t size);
|
||||
uint8_t mbuf_read_u8(struct mbuf *mb);
|
||||
uint16_t mbuf_read_u16(struct mbuf *mb);
|
||||
uint32_t mbuf_read_u32(struct mbuf *mb);
|
||||
uint64_t mbuf_read_u64(struct mbuf *mb);
|
||||
int mbuf_read_str(struct mbuf *mb, char *str, size_t size);
|
||||
int mbuf_strdup(struct mbuf *mb, char **strp, size_t len);
|
||||
int mbuf_vprintf(struct mbuf *mb, const char *fmt, va_list ap);
|
||||
int mbuf_printf(struct mbuf *mb, const char *fmt, ...);
|
||||
int mbuf_write_pl_skip(struct mbuf *mb, const struct pl *pl,
|
||||
const struct pl *skip);
|
||||
|
||||
|
||||
/**
|
||||
* Get the buffer from the current position
|
||||
*
|
||||
* @param mb Memory buffer
|
||||
*
|
||||
* @return Current buffer
|
||||
*/
|
||||
static inline uint8_t *mbuf_buf(const struct mbuf *mb)
|
||||
{
|
||||
return mb ? mb->buf + mb->pos : NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get number of bytes left in a memory buffer, from current position to end
|
||||
*
|
||||
* @param mb Memory buffer
|
||||
*
|
||||
* @return Number of bytes left
|
||||
*/
|
||||
static inline size_t mbuf_get_left(const struct mbuf *mb)
|
||||
{
|
||||
return mb ? (mb->end - mb->pos) : 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get available space in buffer (size - pos)
|
||||
*
|
||||
* @param mb Memory buffer
|
||||
*
|
||||
* @return Number of bytes available in buffer
|
||||
*/
|
||||
static inline size_t mbuf_get_space(const struct mbuf *mb)
|
||||
{
|
||||
return mb ? (mb->size - mb->pos) : 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set absolute position
|
||||
*
|
||||
* @param mb Memory buffer
|
||||
* @param pos Position
|
||||
*/
|
||||
static inline void mbuf_set_pos(struct mbuf *mb, size_t pos)
|
||||
{
|
||||
mb->pos = pos;
|
||||
MBUF_CHECK_POS(mb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set absolute end
|
||||
*
|
||||
* @param mb Memory buffer
|
||||
* @param end End position
|
||||
*/
|
||||
static inline void mbuf_set_end(struct mbuf *mb, size_t end)
|
||||
{
|
||||
mb->end = end;
|
||||
MBUF_CHECK_END(mb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Advance position +/- N bytes
|
||||
*
|
||||
* @param mb Memory buffer
|
||||
* @param n Number of bytes to advance
|
||||
*/
|
||||
static inline void mbuf_advance(struct mbuf *mb, ssize_t n)
|
||||
{
|
||||
mb->pos += n;
|
||||
MBUF_CHECK_POS(mb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rewind position and end to the beginning of buffer
|
||||
*
|
||||
* @param mb Memory buffer
|
||||
*/
|
||||
static inline void mbuf_rewind(struct mbuf *mb)
|
||||
{
|
||||
mb->pos = mb->end = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set position to the end of the buffer
|
||||
*
|
||||
* @param mb Memory buffer
|
||||
*/
|
||||
static inline void mbuf_skip_to_end(struct mbuf *mb)
|
||||
{
|
||||
mb->pos = mb->end;
|
||||
}
|
14
include/re_md5.h
Normal file
14
include/re_md5.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* @file re_md5.h Interface to MD5 functions
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
enum {
|
||||
MD5_SIZE = 16, /**< Number of bytes in MD5 hash */
|
||||
MD5_STR_SIZE = 2*MD5_SIZE + 1 /**< Number of bytes in MD5 string */
|
||||
};
|
||||
|
||||
void md5(const uint8_t *d, size_t n, uint8_t *md);
|
||||
int md5_printf(uint8_t *md, const char *fmt, ...);
|
37
include/re_mem.h
Normal file
37
include/re_mem.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* @file re_mem.h Interface to Memory management with reference counting
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Defines the memory destructor handler, which is called when the reference
|
||||
* of a memory object goes down to zero
|
||||
*
|
||||
* @param data Pointer to memory object
|
||||
*/
|
||||
typedef void (mem_destroy_h)(void *data);
|
||||
|
||||
/** Memory Statistics */
|
||||
struct memstat {
|
||||
size_t bytes_cur; /**< Current bytes allocated */
|
||||
size_t bytes_peak; /**< Peak bytes allocated */
|
||||
size_t blocks_cur; /**< Current blocks allocated */
|
||||
size_t blocks_peak; /**< Peak blocks allocated */
|
||||
size_t size_min; /**< Lowest block size allocated */
|
||||
size_t size_max; /**< Largest block size allocated */
|
||||
};
|
||||
|
||||
void *mem_alloc(size_t size, mem_destroy_h *dh);
|
||||
void *mem_zalloc(size_t size, mem_destroy_h *dh);
|
||||
void *mem_realloc(void *data, size_t size);
|
||||
void *mem_ref(void *data);
|
||||
void *mem_deref(void *data);
|
||||
uint32_t mem_nrefs(const void *data);
|
||||
|
||||
void mem_debug(void);
|
||||
void mem_threshold_set(ssize_t n);
|
||||
struct re_printf;
|
||||
int mem_status(struct re_printf *pf, void *unused);
|
||||
int mem_get_stat(struct memstat *mstat);
|
77
include/re_mod.h
Normal file
77
include/re_mod.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* @file re_mod.h Interface to loadable modules
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @def MOD_PRE
|
||||
*
|
||||
* Module Prefix
|
||||
*
|
||||
* @def MOD_EXT
|
||||
*
|
||||
* Module Extension
|
||||
*/
|
||||
#if defined (WIN32)
|
||||
#define MOD_PRE ""
|
||||
#define MOD_EXT ".dll"
|
||||
#elif defined (__SYMBIAN32__)
|
||||
#define MOD_PRE "mod_"
|
||||
#define MOD_EXT ".dll"
|
||||
#else
|
||||
#define MOD_PRE ""
|
||||
#define MOD_EXT ".so"
|
||||
#endif
|
||||
|
||||
|
||||
/** Symbol to enable exporting of functions from a module */
|
||||
#ifdef WIN32
|
||||
#define EXPORT_SYM __declspec(dllexport)
|
||||
#else
|
||||
#define EXPORT_SYM
|
||||
#endif
|
||||
|
||||
|
||||
/* ----- Module API ----- */
|
||||
|
||||
|
||||
/**
|
||||
* Defines the module initialisation handler
|
||||
*
|
||||
* @return 0 for success, otherwise errorcode
|
||||
*/
|
||||
typedef int (mod_init_h)(void);
|
||||
|
||||
/**
|
||||
* Defines the module close handler
|
||||
*
|
||||
* @return 0 for success, otherwise errorcode
|
||||
*/
|
||||
typedef int (mod_close_h)(void);
|
||||
|
||||
|
||||
struct mod;
|
||||
struct re_printf;
|
||||
|
||||
|
||||
/** Defines the module export */
|
||||
struct mod_export {
|
||||
const char *name; /**< Module name */
|
||||
const char *type; /**< Module type */
|
||||
mod_init_h *init; /**< Module init handler */
|
||||
mod_close_h *close; /**< Module close handler */
|
||||
};
|
||||
|
||||
|
||||
/* ----- Application API ----- */
|
||||
|
||||
void mod_init(void);
|
||||
void mod_close(void);
|
||||
|
||||
int mod_load(struct mod **mp, const char *name);
|
||||
int mod_add(struct mod **mp, const struct mod_export *me);
|
||||
struct mod *mod_find(const char *name);
|
||||
const struct mod_export *mod_export(const struct mod *m);
|
||||
int mod_debug(struct re_printf *pf, void *unused);
|
12
include/re_mqueue.h
Normal file
12
include/re_mqueue.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
/**
|
||||
* @file re_mqueue.h Thread Safe Message Queue
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
struct mqueue;
|
||||
|
||||
typedef void (mqueue_h)(int id, void *data);
|
||||
|
||||
int mqueue_alloc(struct mqueue **mqp);
|
||||
int mqueue_push(struct mqueue *mq, mqueue_h *h, int id, void *data);
|
128
include/re_natbd.h
Normal file
128
include/re_natbd.h
Normal file
|
@ -0,0 +1,128 @@
|
|||
/**
|
||||
* @file re_natbd.h NAT Behavior Discovery Using STUN
|
||||
* draft-ietf-behave-nat-behavior-discovery-06
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
/** NAT Mapping/Filtering types - See RFC 4787 for definitions */
|
||||
enum nat_type {
|
||||
NAT_TYPE_UNKNOWN = 0, /**< Unknown type */
|
||||
NAT_TYPE_ENDP_INDEP = 1, /**< Endpoint-Independent */
|
||||
NAT_TYPE_ADDR_DEP = 2, /**< Address-Dependent */
|
||||
NAT_TYPE_ADDR_PORT_DEP = 3 /**< Address and Port-Dependent */
|
||||
};
|
||||
|
||||
|
||||
/* Strings */
|
||||
const char *nat_type_str(enum nat_type type);
|
||||
|
||||
|
||||
/*
|
||||
* Diagnosing NAT Hairpinning
|
||||
*/
|
||||
struct nat_hairpinning;
|
||||
/**
|
||||
* Defines the NAT Hairpinning handler
|
||||
*/
|
||||
typedef void (nat_hairpinning_h)(int err, bool supported, void *arg);
|
||||
|
||||
int nat_hairpinning_alloc(struct nat_hairpinning **nhp,
|
||||
const struct sa *srv, int proto,
|
||||
const struct stun_conf *conf,
|
||||
nat_hairpinning_h *hph, void *arg);
|
||||
int nat_hairpinning_start(struct nat_hairpinning *nh);
|
||||
|
||||
|
||||
/*
|
||||
* Determining NAT Mapping Behavior
|
||||
*/
|
||||
struct nat_mapping;
|
||||
|
||||
/**
|
||||
* Defines the NAT Mapping handler
|
||||
*
|
||||
* @param err Errorcode
|
||||
* @param type NAT Mapping type
|
||||
* @param arg Handler argument
|
||||
*/
|
||||
typedef void (nat_mapping_h)(int err, enum nat_type map, void *arg);
|
||||
|
||||
int nat_mapping_alloc(struct nat_mapping **nmp, const struct sa *laddr,
|
||||
const struct sa *srv, int proto,
|
||||
const struct stun_conf *conf,
|
||||
nat_mapping_h *mh, void *arg);
|
||||
int nat_mapping_start(struct nat_mapping *nm);
|
||||
|
||||
|
||||
/*
|
||||
* Determining NAT Filtering Behavior
|
||||
*/
|
||||
struct nat_filtering;
|
||||
|
||||
/**
|
||||
* Defines the NAT Filtering handler
|
||||
*
|
||||
* @param err Errorcode
|
||||
* @param type NAT Filtering type
|
||||
* @param arg Handler argument
|
||||
*/
|
||||
typedef void (nat_filtering_h)(int err, enum nat_type filt, void *arg);
|
||||
|
||||
int nat_filtering_alloc(struct nat_filtering **nfp, const struct sa *srv,
|
||||
const struct stun_conf *conf,
|
||||
nat_filtering_h *fh, void *arg);
|
||||
int nat_filtering_start(struct nat_filtering *nf);
|
||||
|
||||
|
||||
/*
|
||||
* Binding Lifetime Discovery
|
||||
*/
|
||||
|
||||
/** Defines the NAT lifetime interval */
|
||||
struct nat_lifetime;
|
||||
struct nat_lifetime_interval {
|
||||
uint32_t min; /**< Minimum lifetime interval in [seconds] */
|
||||
uint32_t cur; /**< Current lifetime interval in [seconds] */
|
||||
uint32_t max; /**< Maximum lifetime interval in [seconds] */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Defines the NAT Lifetime handler
|
||||
*
|
||||
* @param err Errorcode
|
||||
* @param i NAT Lifetime intervals
|
||||
* @param arg Handler argument
|
||||
*/
|
||||
typedef void (nat_lifetime_h)(int err, const struct nat_lifetime_interval *i,
|
||||
void *arg);
|
||||
|
||||
int nat_lifetime_alloc(struct nat_lifetime **nlp, const struct sa *srv,
|
||||
uint32_t interval, const struct stun_conf *conf,
|
||||
nat_lifetime_h *lh, void *arg);
|
||||
int nat_lifetime_start(struct nat_lifetime *nl);
|
||||
|
||||
|
||||
/*
|
||||
* Detecting Generic ALGs
|
||||
*/
|
||||
struct nat_genalg;
|
||||
|
||||
/**
|
||||
* Defines the NAT Generic ALG handler
|
||||
*
|
||||
* @param err Errorcode
|
||||
* @param errcode STUN Error code (if set)
|
||||
* @param status Generic ALG status (-1=not detected, 1=detected)
|
||||
* @param map Mapped network address
|
||||
* @param arg Handler argument
|
||||
*/
|
||||
typedef void (nat_genalg_h)(int err, uint16_t scode, const char *reason,
|
||||
int status, const struct sa *map, void *arg);
|
||||
|
||||
int nat_genalg_alloc(struct nat_genalg **ngp, const struct sa *srv, int proto,
|
||||
const struct stun_conf *conf,
|
||||
nat_genalg_h *gh, void *arg);
|
||||
int nat_genalg_start(struct nat_genalg *ng);
|
135
include/re_net.h
Normal file
135
include/re_net.h
Normal file
|
@ -0,0 +1,135 @@
|
|||
/**
|
||||
* @file re_net.h Interface to Networking module.
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#ifdef CYGWIN
|
||||
#include <ws2tcpip.h>
|
||||
#include <winsock2.h>
|
||||
#elif defined(WIN32)
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#ifndef _BSD_SOCKLEN_T_
|
||||
#define _BSD_SOCKLEN_T_ int /**< Defines the BSD socket length type */
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_GAI_STRERROR
|
||||
/** stub */
|
||||
#ifndef gai_strerror
|
||||
#define gai_strerror(err) "?"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** Length of IPv4 address string */
|
||||
#ifndef INET_ADDRSTRLEN
|
||||
#define INET_ADDRSTRLEN 16
|
||||
#endif
|
||||
|
||||
/** Length of IPv6 address string */
|
||||
#ifndef INET6_ADDRSTRLEN
|
||||
#define INET6_ADDRSTRLEN 46
|
||||
#endif
|
||||
|
||||
/** Length of IPv4/v6 address string */
|
||||
#ifdef HAVE_INET6
|
||||
#define NET_ADDRSTRLEN INET6_ADDRSTRLEN
|
||||
#else
|
||||
#define NET_ADDRSTRLEN INET_ADDRSTRLEN
|
||||
#endif
|
||||
|
||||
/* forward declarations */
|
||||
struct sa;
|
||||
|
||||
|
||||
/* Net generic */
|
||||
int net_hostaddr(int af, struct sa *ip);
|
||||
int net_default_source_addr_get(int af, struct sa *ip);
|
||||
|
||||
|
||||
/* Net sockets */
|
||||
int net_sock_init(void);
|
||||
void net_sock_close(void);
|
||||
|
||||
|
||||
/* Net socket options */
|
||||
int net_sockopt_blocking_set(int fd, bool blocking);
|
||||
int net_sockopt_reuse_set(int fd, bool reuse);
|
||||
|
||||
|
||||
/* Net interface (if.c) */
|
||||
|
||||
/**
|
||||
* Defines the interface address handled - called once per interface
|
||||
*
|
||||
* @param ifname Name of the interface
|
||||
* @param sa IP address of the interface
|
||||
* @param arg Handler argument
|
||||
*
|
||||
* @return true to stop traversing, false to continue
|
||||
*/
|
||||
typedef bool (net_ifaddr_h)(const char *ifname, const struct sa *sa,
|
||||
void *arg);
|
||||
|
||||
int net_if_getname(char *ifname, size_t sz, int af, const struct sa *ip);
|
||||
int net_if_getaddr(const char *ifname, int af, struct sa *ip);
|
||||
int net_if_getaddr4(const char *ifname, int af, struct sa *ip);
|
||||
int net_if_list(net_ifaddr_h *ifh, void *arg);
|
||||
int net_if_apply(net_ifaddr_h *ifh, void *arg);
|
||||
int net_if_debug(struct re_printf *pf, void *unused);
|
||||
|
||||
|
||||
/* Net interface (ifaddrs.c) */
|
||||
int net_getifaddrs(net_ifaddr_h *ifh, void *arg);
|
||||
|
||||
|
||||
/* Net route */
|
||||
|
||||
/**
|
||||
* Defines the routing table handler - called once per route entry
|
||||
*
|
||||
* @param ifname Interface name
|
||||
* @param dst Destination IP address/network
|
||||
* @param dstlen Prefix length of destination
|
||||
* @param gw Gateway IP address
|
||||
* @param arg Handler argument
|
||||
*
|
||||
* @return true to stop traversing, false to continue
|
||||
*/
|
||||
typedef bool (net_rt_h)(const char *ifname, const struct sa *dst,
|
||||
int dstlen, const struct sa *gw, void *arg);
|
||||
|
||||
int net_rt_list(net_rt_h *rth, void *arg);
|
||||
int net_rt_default_get(int af, char *ifname, size_t size);
|
||||
int net_rt_debug(struct re_printf *pf, void *unused);
|
||||
|
||||
|
||||
/* Network connection */
|
||||
|
||||
/**
|
||||
* Defines the network connection handler
|
||||
*
|
||||
* @param err Error code
|
||||
* @param id Associated ID
|
||||
*/
|
||||
typedef void (net_conn_h)(int err, uint32_t id);
|
||||
|
||||
int net_conn_start(net_conn_h *ch, uint32_t id, bool prompt);
|
||||
void net_conn_stop(void);
|
||||
|
||||
|
||||
/* Net strings */
|
||||
const char *net_proto2name(int proto);
|
||||
const char *net_af2name(int af);
|
||||
|
||||
|
||||
/* todo: this does not really belong here.. */
|
||||
#ifdef __SYMBIAN32__
|
||||
int kerr2errno(int kerr);
|
||||
#endif
|
231
include/re_rtp.h
Normal file
231
include/re_rtp.h
Normal file
|
@ -0,0 +1,231 @@
|
|||
/**
|
||||
* @file re_rtp.h Interface to Real-time Transport Protocol
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
enum {
|
||||
RTP_VERSION = 2, /**< Defines the RTP version we support */
|
||||
RTCP_VERSION = 2, /**< Supported RTCP Version */
|
||||
RTP_HEADER_SIZE = 12 /**< Number of bytes in RTP Header */
|
||||
};
|
||||
|
||||
|
||||
/** Defines the RTP header */
|
||||
struct rtp_header {
|
||||
uint8_t ver; /**< RTP version number */
|
||||
bool pad; /**< Padding bit */
|
||||
bool ext; /**< Extension bit */
|
||||
uint8_t cc; /**< CSRC count */
|
||||
bool m; /**< Marker bit */
|
||||
uint8_t pt; /**< Payload type */
|
||||
uint16_t seq; /**< Sequence number */
|
||||
uint32_t ts; /**< Timestamp */
|
||||
uint32_t ssrc; /**< Synchronization source */
|
||||
uint32_t csrc[16]; /**< Contributing sources */
|
||||
struct {
|
||||
uint16_t type; /**< Defined by profile */
|
||||
uint16_t len; /**< Number of 32-bit words */
|
||||
} x;
|
||||
};
|
||||
|
||||
/** RTCP Packet Types */
|
||||
enum rtcp_type {
|
||||
RTCP_FIR = 192, /**< Full INTRA-frame Request (RFC 2032) */
|
||||
RTCP_NACK = 193, /**< Negative Acknowledgement (RFC 2032) */
|
||||
RTCP_SR = 200, /**< Sender Report */
|
||||
RTCP_RR = 201, /**< Receiver Report */
|
||||
RTCP_SDES = 202, /**< Source Description */
|
||||
RTCP_BYE = 203, /**< Goodbye */
|
||||
RTCP_APP = 204, /**< Application-defined */
|
||||
RTCP_RTPFB = 205, /**< Transport layer FB message (RFC 4585) */
|
||||
RTCP_PSFB = 206, /**< Payload-specific FB message (RFC 4585) */
|
||||
RTCP_XR = 207, /**< Extended Report (RFC 3611) */
|
||||
RTCP_AVB = 208, /**< AVB RTCP Packet (IEEE1733) */
|
||||
};
|
||||
|
||||
/** SDES Types */
|
||||
enum rtcp_sdes_type {
|
||||
RTCP_SDES_END = 0, /**< End of SDES list */
|
||||
RTCP_SDES_CNAME = 1, /**< Canonical name */
|
||||
RTCP_SDES_NAME = 2, /**< User name */
|
||||
RTCP_SDES_EMAIL = 3, /**< User's electronic mail address */
|
||||
RTCP_SDES_PHONE = 4, /**< User's phone number */
|
||||
RTCP_SDES_LOC = 5, /**< Geographic user location */
|
||||
RTCP_SDES_TOOL = 6, /**< Name of application or tool */
|
||||
RTCP_SDES_NOTE = 7, /**< Notice about the source */
|
||||
RTCP_SDES_PRIV = 8 /**< Private extension */
|
||||
};
|
||||
|
||||
/** Transport Layer Feedback Messages */
|
||||
enum rtcp_rtpfb {
|
||||
RTCP_RTPFB_GNACK = 1 /**< Generic NACK */
|
||||
};
|
||||
|
||||
/** Payload-Specific Feedback Messages */
|
||||
enum rtcp_psfb {
|
||||
RTCP_PSFB_PLI = 1, /**< Picture Loss Indication (PLI) */
|
||||
RTCP_PSFB_SLI = 2, /**< Slice Loss Indication (SLI) */
|
||||
};
|
||||
|
||||
/** Reception report block */
|
||||
struct rtcp_rr {
|
||||
uint32_t ssrc; /**< Data source being reported */
|
||||
unsigned int fraction:8; /**< Fraction lost since last SR/RR */
|
||||
int lost:24; /**< Cumul. no. pkts lost (signed!) */
|
||||
uint32_t last_seq; /**< Extended last seq. no. received */
|
||||
uint32_t jitter; /**< Interarrival jitter */
|
||||
uint32_t lsr; /**< Last SR packet from this source */
|
||||
uint32_t dlsr; /**< Delay since last SR packet */
|
||||
};
|
||||
|
||||
/** SDES item */
|
||||
struct rtcp_sdes_item {
|
||||
enum rtcp_sdes_type type; /**< Type of item (enum rtcp_sdes_type) */
|
||||
uint8_t length; /**< Length of item (in octets) */
|
||||
char *data; /**< Text, not null-terminated */
|
||||
};
|
||||
|
||||
/** One RTCP Message */
|
||||
struct rtcp_msg {
|
||||
/** RTCP Header */
|
||||
struct rtcp_hdr {
|
||||
unsigned int version:2; /**< Protocol version */
|
||||
unsigned int p:1; /**< Padding flag */
|
||||
unsigned int count:5; /**< Varies by packet type */
|
||||
unsigned int pt:8; /**< RTCP packet type */
|
||||
uint16_t length; /**< Packet len in words */
|
||||
} hdr;
|
||||
union {
|
||||
/** Sender report (SR) */
|
||||
struct {
|
||||
uint32_t ssrc; /**< Sender generating report */
|
||||
uint32_t ntp_sec; /**< NTP timestamp - seconds */
|
||||
uint32_t ntp_frac; /**< NTP timestamp - fractions */
|
||||
uint32_t rtp_ts; /**< RTP timestamp */
|
||||
uint32_t psent; /**< RTP packets sent */
|
||||
uint32_t osent; /**< RTP octets sent */
|
||||
struct rtcp_rr *rrv; /**< Reception report blocks */
|
||||
} sr;
|
||||
|
||||
/** Reception report (RR) */
|
||||
struct {
|
||||
uint32_t ssrc; /**< Receiver generating report*/
|
||||
struct rtcp_rr *rrv; /**< Reception report blocks */
|
||||
} rr;
|
||||
|
||||
/** Source Description (SDES) */
|
||||
struct rtcp_sdes {
|
||||
uint32_t src; /**< First SSRC/CSRC */
|
||||
struct rtcp_sdes_item *itemv; /**< SDES items */
|
||||
uint32_t n; /**< Number of SDES items */
|
||||
} *sdesv;
|
||||
|
||||
/** BYE */
|
||||
struct {
|
||||
uint32_t *srcv; /**< List of sources */
|
||||
char *reason; /**< Reason for leaving (opt.) */
|
||||
} bye;
|
||||
|
||||
/** Application-defined (APP) */
|
||||
struct {
|
||||
uint32_t src; /**< SSRC/CSRC */
|
||||
char name[4]; /**< Name (ASCII) */
|
||||
uint8_t *data; /**< Application data (32 bits) */
|
||||
size_t data_len; /**< Number of data bytes */
|
||||
} app;
|
||||
|
||||
/** Full INTRA-frame Request (FIR) packet */
|
||||
struct {
|
||||
uint32_t ssrc; /**< SSRC for sender of this packet */
|
||||
} fir;
|
||||
|
||||
/** Negative ACKnowledgements (NACK) packet */
|
||||
struct {
|
||||
uint32_t ssrc; /**< SSRC for sender of this packet */
|
||||
uint16_t fsn; /**< First Sequence Number lost */
|
||||
uint16_t blp; /**< Bitmask of lost packets */
|
||||
} nack;
|
||||
|
||||
/** Feedback (RTPFB or PSFB) packet */
|
||||
struct {
|
||||
uint32_t ssrc_packet;
|
||||
uint32_t ssrc_media;
|
||||
uint32_t n;
|
||||
/** Feedback Control Information (FCI) */
|
||||
union {
|
||||
struct gnack {
|
||||
uint16_t pid;
|
||||
uint16_t blp;
|
||||
} *gnackv;
|
||||
struct sli {
|
||||
uint16_t first;
|
||||
uint16_t number;
|
||||
uint8_t picid;
|
||||
} *sliv;
|
||||
void *p;
|
||||
} fci;
|
||||
} fb;
|
||||
} r;
|
||||
};
|
||||
|
||||
struct rtcp_stats {
|
||||
struct {
|
||||
uint32_t sent;
|
||||
int lost;
|
||||
uint32_t jit;
|
||||
} tx;
|
||||
struct {
|
||||
uint32_t sent;
|
||||
int lost;
|
||||
uint32_t jit;
|
||||
} rx;
|
||||
};
|
||||
|
||||
struct sa;
|
||||
struct re_printf;
|
||||
struct rtp_sock;
|
||||
|
||||
typedef void (rtp_recv_h)(const struct sa *src, const struct rtp_header *hdr,
|
||||
struct mbuf *mb, void *arg);
|
||||
typedef void (rtcp_recv_h)(const struct sa *src, struct rtcp_msg *msg,
|
||||
void *arg);
|
||||
|
||||
/* RTP api */
|
||||
int rtp_alloc(struct rtp_sock **rsp);
|
||||
int rtp_listen(struct rtp_sock **rsp, int proto, const struct sa *ip,
|
||||
uint16_t min_port, uint16_t max_port, bool enable_rtcp,
|
||||
rtp_recv_h *recvh, rtcp_recv_h *rtcph, void *arg);
|
||||
int rtp_hdr_encode(struct mbuf *mb, const struct rtp_header *hdr);
|
||||
int rtp_hdr_decode(struct rtp_header *hdr, struct mbuf *mb);
|
||||
int rtp_encode(struct rtp_sock *rs, bool marker, uint8_t pt,
|
||||
uint32_t ts, struct mbuf *mb);
|
||||
int rtp_decode(struct rtp_sock *rs, struct mbuf *mb, struct rtp_header *hdr);
|
||||
int rtp_send(struct rtp_sock *rs, const struct sa *dst,
|
||||
bool marker, uint8_t pt, uint32_t ts, struct mbuf *mb);
|
||||
int rtp_debug(struct re_printf *pf, const struct rtp_sock *rs);
|
||||
void *rtp_sock(const struct rtp_sock *rs);
|
||||
uint32_t rtp_sess_ssrc(const struct rtp_sock *rs);
|
||||
const struct sa *rtp_local(const struct rtp_sock *rs);
|
||||
|
||||
/* RTCP session api */
|
||||
void rtcp_start(struct rtp_sock *rs, const char *cname,
|
||||
const struct sa *peer);
|
||||
void rtcp_set_srate(struct rtp_sock *rs, uint32_t sr_tx, uint32_t sr_rx);
|
||||
int rtcp_send_app(struct rtp_sock *rs, const char name[4],
|
||||
const uint8_t *data, size_t len);
|
||||
int rtcp_send_fir(struct rtp_sock *rs, uint32_t ssrc);
|
||||
int rtcp_send_nack(struct rtp_sock *rs, uint16_t fsn, uint16_t blp);
|
||||
int rtcp_send_pli(struct rtp_sock *rs, uint32_t fb_ssrc);
|
||||
int rtcp_debug(struct re_printf *pf, const struct rtp_sock *rs);
|
||||
void *rtcp_sock(const struct rtp_sock *rs);
|
||||
int rtcp_stats(struct rtp_sock *rs, uint32_t ssrc, struct rtcp_stats *stats);
|
||||
|
||||
/* RTCP utils */
|
||||
int rtcp_encode(struct mbuf *mb, enum rtcp_type type, uint32_t count, ...);
|
||||
int rtcp_decode(struct rtcp_msg **msgp, struct mbuf *mb);
|
||||
int rtcp_msg_print(struct re_printf *pf, const struct rtcp_msg *msg);
|
||||
int rtcp_sdes_encode(struct mbuf *mb, uint32_t src, uint32_t itemc, ...);
|
||||
const char *rtcp_type_name(enum rtcp_type type);
|
||||
const char *rtcp_sdes_name(enum rtcp_sdes_type sdes);
|
55
include/re_sa.h
Normal file
55
include/re_sa.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* @file re_sa.h Interface to Socket Address
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#if defined(WIN32)
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
struct pl;
|
||||
|
||||
enum sa_flag {
|
||||
SA_ADDR = 1<<0,
|
||||
SA_PORT = 1<<1,
|
||||
SA_ALL = SA_ADDR | SA_PORT
|
||||
};
|
||||
|
||||
struct sa {
|
||||
union {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in in;
|
||||
#ifdef HAVE_INET6
|
||||
struct sockaddr_in6 in6;
|
||||
#endif
|
||||
} u;
|
||||
socklen_t len;
|
||||
};
|
||||
|
||||
void sa_init(struct sa *sa, int af);
|
||||
int sa_set(struct sa *sa, const struct pl *addr, uint16_t port);
|
||||
int sa_set_str(struct sa *sa, const char *addr, uint16_t port);
|
||||
void sa_set_in(struct sa *sa, uint32_t addr, uint16_t port);
|
||||
void sa_set_in6(struct sa *sa, const uint8_t *addr, uint16_t port);
|
||||
int sa_set_sa(struct sa *sa, const struct sockaddr *s);
|
||||
void sa_set_port(struct sa *sa, uint16_t port);
|
||||
int sa_decode(struct sa *sa, const char *str, size_t len);
|
||||
|
||||
int sa_af(const struct sa *sa);
|
||||
uint32_t sa_in(const struct sa *sa);
|
||||
void sa_in6(const struct sa *sa, uint8_t *addr);
|
||||
int sa_ntop(const struct sa *sa, char *buf, int size);
|
||||
uint16_t sa_port(const struct sa *sa);
|
||||
bool sa_isset(const struct sa *sa, int flag);
|
||||
uint32_t sa_hash(const struct sa *sa, int flag);
|
||||
|
||||
void sa_cpy(struct sa *dst, const struct sa *src);
|
||||
bool sa_cmp(const struct sa *l, const struct sa *r, int flag);
|
||||
|
||||
bool sa_is_linklocal(const struct sa *sa);
|
||||
bool sa_is_loopback(const struct sa *sa);
|
||||
bool sa_is_any(const struct sa *sa);
|
153
include/re_sdp.h
Normal file
153
include/re_sdp.h
Normal file
|
@ -0,0 +1,153 @@
|
|||
/**
|
||||
* @file re_sdp.h Interface to Session Description Protocol (SDP)
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
enum {
|
||||
SDP_VERSION = 0
|
||||
};
|
||||
|
||||
enum sdp_dir {
|
||||
SDP_INACTIVE = 0,
|
||||
SDP_RECVONLY = 1,
|
||||
SDP_SENDONLY = 2,
|
||||
SDP_SENDRECV = 3,
|
||||
};
|
||||
|
||||
/** SDP Bandwidth type */
|
||||
enum sdp_bandwidth {
|
||||
SDP_BANDWIDTH_MIN = 0,
|
||||
SDP_BANDWIDTH_CT = 0, /**< [kbit/s] Conference Total */
|
||||
SDP_BANDWIDTH_AS, /**< [kbit/s] Application Specific */
|
||||
SDP_BANDWIDTH_RS, /**< [bit/s] RTCP Senders (RFC 3556) */
|
||||
SDP_BANDWIDTH_RR, /**< [bit/s] RTCP Receivers (RFC 3556) */
|
||||
SDP_BANDWIDTH_TIAS, /**< [bit/s] Transport Independent Application
|
||||
Specific Maximum (RFC 3890) */
|
||||
SDP_BANDWIDTH_MAX,
|
||||
};
|
||||
|
||||
|
||||
struct sdp_format;
|
||||
|
||||
typedef bool(sdp_fmtp_cmp_h)(const char *params1, const char *params2,
|
||||
void *data);
|
||||
typedef bool(sdp_format_h)(struct sdp_format *fmt, void *arg);
|
||||
typedef bool(sdp_attr_h)(const char *name, const char *value, void *arg);
|
||||
|
||||
struct sdp_format {
|
||||
struct le le;
|
||||
char *id;
|
||||
char *params;
|
||||
char *name;
|
||||
sdp_fmtp_cmp_h *cmph;
|
||||
void *data;
|
||||
bool ref;
|
||||
bool sup;
|
||||
int pt;
|
||||
uint32_t srate;
|
||||
uint8_t ch;
|
||||
};
|
||||
|
||||
|
||||
/* session */
|
||||
struct sdp_session;
|
||||
|
||||
int sdp_session_alloc(struct sdp_session **sessp, const struct sa *laddr);
|
||||
void sdp_session_set_laddr(struct sdp_session *sess, const struct sa *laddr);
|
||||
void sdp_session_set_lbandwidth(struct sdp_session *sess,
|
||||
enum sdp_bandwidth type, int32_t bw);
|
||||
int sdp_session_set_lattr(struct sdp_session *sess, bool replace,
|
||||
const char *name, const char *value, ...);
|
||||
void sdp_session_del_lattr(struct sdp_session *sess, const char *name);
|
||||
int32_t sdp_session_rbandwidth(const struct sdp_session *sess,
|
||||
enum sdp_bandwidth type);
|
||||
const char *sdp_session_rattr(const struct sdp_session *sess,
|
||||
const char *name);
|
||||
const char *sdp_session_rattr_apply(const struct sdp_session *sess,
|
||||
const char *name,
|
||||
sdp_attr_h *attrh, void *arg);
|
||||
const struct list *sdp_session_medial(const struct sdp_session *sess,
|
||||
bool local);
|
||||
int sdp_session_debug(struct re_printf *pf, const struct sdp_session *sess);
|
||||
|
||||
|
||||
/* media */
|
||||
struct sdp_media;
|
||||
|
||||
int sdp_media_add(struct sdp_media **mp, struct sdp_session *sess,
|
||||
const char *name, uint16_t port, const char *proto);
|
||||
void sdp_media_set_disabled(struct sdp_media *m, bool disabled);
|
||||
void sdp_media_set_lport(struct sdp_media *m, uint16_t port);
|
||||
void sdp_media_set_laddr(struct sdp_media *m, const struct sa *laddr);
|
||||
void sdp_media_set_lbandwidth(struct sdp_media *m, enum sdp_bandwidth type,
|
||||
int32_t bw);
|
||||
void sdp_media_set_lport_rtcp(struct sdp_media *m, uint16_t port);
|
||||
void sdp_media_set_laddr_rtcp(struct sdp_media *m, const struct sa *laddr);
|
||||
void sdp_media_set_ldir(struct sdp_media *m, enum sdp_dir dir);
|
||||
int sdp_media_set_lattr(struct sdp_media *m, bool replace,
|
||||
const char *name, const char *value, ...);
|
||||
void sdp_media_del_lattr(struct sdp_media *m, const char *name);
|
||||
uint16_t sdp_media_rport(const struct sdp_media *m);
|
||||
const struct sa *sdp_media_raddr(const struct sdp_media *m);
|
||||
void sdp_media_raddr_rtcp(const struct sdp_media *m, struct sa *raddr);
|
||||
int32_t sdp_media_rbandwidth(const struct sdp_media *m,
|
||||
enum sdp_bandwidth type);
|
||||
enum sdp_dir sdp_media_ldir(const struct sdp_media *m);
|
||||
enum sdp_dir sdp_media_rdir(const struct sdp_media *m);
|
||||
enum sdp_dir sdp_media_dir(const struct sdp_media *m);
|
||||
const struct sdp_format *sdp_media_lformat(const struct sdp_media *m, int pt);
|
||||
const struct sdp_format *sdp_media_rformat(const struct sdp_media *m,
|
||||
const char *name);
|
||||
struct sdp_format *sdp_media_format(const struct sdp_media *m,
|
||||
bool local, const char *id,
|
||||
int pt, const char *name,
|
||||
int32_t srate, int8_t ch);
|
||||
struct sdp_format *sdp_media_format_apply(const struct sdp_media *m,
|
||||
bool local, const char *id,
|
||||
int pt, const char *name,
|
||||
int32_t srate, int8_t ch,
|
||||
sdp_format_h *fmth, void *arg);
|
||||
const struct list *sdp_media_format_lst(const struct sdp_media *m, bool local);
|
||||
const char *sdp_media_rattr(const struct sdp_media *m, const char *name);
|
||||
const char *sdp_media_rattr_apply(const struct sdp_media *m, const char *name,
|
||||
sdp_attr_h *attrh, void *arg);
|
||||
const char *sdp_media_name(const struct sdp_media *m);
|
||||
int sdp_media_debug(struct re_printf *pf, const struct sdp_media *m);
|
||||
|
||||
|
||||
/* format */
|
||||
int sdp_format_add(struct sdp_format **fmtp, struct sdp_media *m,
|
||||
bool prepend, const char *id, const char *name,
|
||||
uint32_t srate, uint8_t ch,
|
||||
sdp_fmtp_cmp_h *cmph, void *data, bool ref,
|
||||
const char *params, ...);
|
||||
int sdp_format_set_params(struct sdp_format *fmt, const char *params, ...);
|
||||
bool sdp_format_cmp(const struct sdp_format *fmt1,
|
||||
const struct sdp_format *fmt2);
|
||||
int sdp_format_debug(struct re_printf *pf, const struct sdp_format *fmt);
|
||||
|
||||
|
||||
/* encode/decode */
|
||||
int sdp_encode(struct mbuf **mbp, struct sdp_session *sess, bool offer);
|
||||
int sdp_decode(struct sdp_session *sess, struct mbuf *mb, bool offer);
|
||||
|
||||
|
||||
/* strings */
|
||||
const char *sdp_dir_name(enum sdp_dir dir);
|
||||
const char *sdp_bandwidth_name(enum sdp_bandwidth type);
|
||||
|
||||
|
||||
extern const char sdp_attr_fmtp[];
|
||||
extern const char sdp_attr_maxptime[];
|
||||
extern const char sdp_attr_ptime[];
|
||||
extern const char sdp_attr_rtcp[];
|
||||
extern const char sdp_attr_rtpmap[];
|
||||
|
||||
extern const char sdp_media_audio[];
|
||||
extern const char sdp_media_video[];
|
||||
extern const char sdp_media_text[];
|
||||
|
||||
extern const char sdp_proto_rtpavp[];
|
||||
extern const char sdp_proto_rtpsavp[];
|
34
include/re_sha.h
Normal file
34
include/re_sha.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* @file re_sha.h Interface to SHA (Secure Hash Standard) functions
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
#include <openssl/sha.h>
|
||||
#else
|
||||
|
||||
/* public api for steve reid's public domain SHA-1 implementation */
|
||||
/* this file is in the public domain */
|
||||
|
||||
/** SHA-1 Context */
|
||||
typedef struct {
|
||||
uint32_t state[5]; /**< Context state */
|
||||
uint32_t count[2]; /**< Counter */
|
||||
uint8_t buffer[64]; /**< SHA-1 buffer */
|
||||
} SHA1_CTX;
|
||||
|
||||
/** SHA-1 Context (OpenSSL compat) */
|
||||
typedef SHA1_CTX SHA_CTX;
|
||||
|
||||
/** SHA-1 Digest size in bytes */
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
/** SHA-1 Digest size in bytes (OpenSSL compat) */
|
||||
#define SHA_DIGEST_LENGTH SHA1_DIGEST_SIZE
|
||||
|
||||
void SHA1_Init(SHA1_CTX* context);
|
||||
void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len);
|
||||
void SHA1_Final(uint8_t digest[SHA1_DIGEST_SIZE], SHA1_CTX* context);
|
||||
|
||||
#endif
|
319
include/re_sip.h
Normal file
319
include/re_sip.h
Normal file
|
@ -0,0 +1,319 @@
|
|||
/**
|
||||
* @file re_sip.h Session Initiation Protocol
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
enum {
|
||||
SIP_PORT = 5060,
|
||||
SIP_PORT_TLS = 5061,
|
||||
};
|
||||
|
||||
enum sip_transp {
|
||||
SIP_TRANSP_NONE = -1,
|
||||
SIP_TRANSP_UDP = 0,
|
||||
SIP_TRANSP_TCP,
|
||||
SIP_TRANSP_TLS,
|
||||
SIP_TRANSPC,
|
||||
};
|
||||
|
||||
|
||||
enum sip_hdrid {
|
||||
SIP_HDR_ACCEPT = 3186,
|
||||
SIP_HDR_ACCEPT_CONTACT = 232,
|
||||
SIP_HDR_ACCEPT_ENCODING = 708,
|
||||
SIP_HDR_ACCEPT_LANGUAGE = 2867,
|
||||
SIP_HDR_ACCEPT_RESOURCE_PRIORITY = 1848,
|
||||
SIP_HDR_ALERT_INFO = 274,
|
||||
SIP_HDR_ALLOW = 2429,
|
||||
SIP_HDR_ALLOW_EVENTS = 66,
|
||||
SIP_HDR_ANSWER_MODE = 2905,
|
||||
SIP_HDR_AUTHENTICATION_INFO = 3144,
|
||||
SIP_HDR_AUTHORIZATION = 2503,
|
||||
SIP_HDR_CALL_ID = 3095,
|
||||
SIP_HDR_CALL_INFO = 586,
|
||||
SIP_HDR_CONTACT = 229,
|
||||
SIP_HDR_CONTENT_DISPOSITION = 1425,
|
||||
SIP_HDR_CONTENT_ENCODING = 580,
|
||||
SIP_HDR_CONTENT_LANGUAGE = 3371,
|
||||
SIP_HDR_CONTENT_LENGTH = 3861,
|
||||
SIP_HDR_CONTENT_TYPE = 809,
|
||||
SIP_HDR_CSEQ = 746,
|
||||
SIP_HDR_DATE = 1027,
|
||||
SIP_HDR_ENCRYPTION = 3125,
|
||||
SIP_HDR_ERROR_INFO = 21,
|
||||
SIP_HDR_EVENT = 3286,
|
||||
SIP_HDR_EXPIRES = 1983,
|
||||
SIP_HDR_FROM = 1963,
|
||||
SIP_HDR_HIDE = 283,
|
||||
SIP_HDR_HISTORY_INFO = 2582,
|
||||
SIP_HDR_IDENTITY = 2362,
|
||||
SIP_HDR_IDENTITY_INFO = 980,
|
||||
SIP_HDR_IN_REPLY_TO = 1577,
|
||||
SIP_HDR_JOIN = 3479,
|
||||
SIP_HDR_MAX_BREADTH = 3701,
|
||||
SIP_HDR_MAX_FORWARDS = 3549,
|
||||
SIP_HDR_MIME_VERSION = 3659,
|
||||
SIP_HDR_MIN_EXPIRES = 1121,
|
||||
SIP_HDR_MIN_SE = 2847,
|
||||
SIP_HDR_ORGANIZATION = 3247,
|
||||
SIP_HDR_P_ACCESS_NETWORK_INFO = 1662,
|
||||
SIP_HDR_P_ANSWER_STATE = 42,
|
||||
SIP_HDR_P_ASSERTED_IDENTITY = 1233,
|
||||
SIP_HDR_P_ASSOCIATED_URI = 900,
|
||||
SIP_HDR_P_CALLED_PARTY_ID = 3347,
|
||||
SIP_HDR_P_CHARGING_FUNCTION_ADDRESSES = 2171,
|
||||
SIP_HDR_P_CHARGING_VECTOR = 25,
|
||||
SIP_HDR_P_DCS_TRACE_PARTY_ID = 3027,
|
||||
SIP_HDR_P_DCS_OSPS = 1788,
|
||||
SIP_HDR_P_DCS_BILLING_INFO = 2017,
|
||||
SIP_HDR_P_DCS_LAES = 693,
|
||||
SIP_HDR_P_DCS_REDIRECT = 1872,
|
||||
SIP_HDR_P_EARLY_MEDIA = 2622,
|
||||
SIP_HDR_P_MEDIA_AUTHORIZATION = 1035,
|
||||
SIP_HDR_P_PREFERRED_IDENTITY = 1263,
|
||||
SIP_HDR_P_PROFILE_KEY = 1904,
|
||||
SIP_HDR_P_REFUSED_URI_LIST = 1047,
|
||||
SIP_HDR_P_SERVED_USER = 1588,
|
||||
SIP_HDR_P_USER_DATABASE = 2827,
|
||||
SIP_HDR_P_VISITED_NETWORK_ID = 3867,
|
||||
SIP_HDR_PATH = 2741,
|
||||
SIP_HDR_PERMISSION_MISSING = 1409,
|
||||
SIP_HDR_PRIORITY = 3520,
|
||||
SIP_HDR_PRIV_ANSWER_MODE = 2476,
|
||||
SIP_HDR_PRIVACY = 3150,
|
||||
SIP_HDR_PROXY_AUTHENTICATE = 116,
|
||||
SIP_HDR_PROXY_AUTHORIZATION = 2363,
|
||||
SIP_HDR_PROXY_REQUIRE = 3562,
|
||||
SIP_HDR_RACK = 2523,
|
||||
SIP_HDR_REASON = 3732,
|
||||
SIP_HDR_RECORD_ROUTE = 278,
|
||||
SIP_HDR_REFER_SUB = 2458,
|
||||
SIP_HDR_REFER_TO = 1521,
|
||||
SIP_HDR_REFERRED_BY = 3456,
|
||||
SIP_HDR_REJECT_CONTACT = 285,
|
||||
SIP_HDR_REPLACES = 2534,
|
||||
SIP_HDR_REPLY_TO = 2404,
|
||||
SIP_HDR_REQUEST_DISPOSITION = 3715,
|
||||
SIP_HDR_REQUIRE = 3905,
|
||||
SIP_HDR_RESOURCE_PRIORITY = 1643,
|
||||
SIP_HDR_RESPONSE_KEY = 1548,
|
||||
SIP_HDR_RETRY_AFTER = 409,
|
||||
SIP_HDR_ROUTE = 661,
|
||||
SIP_HDR_RSEQ = 445,
|
||||
SIP_HDR_SECURITY_CLIENT = 1358,
|
||||
SIP_HDR_SECURITY_SERVER = 811,
|
||||
SIP_HDR_SECURITY_VERIFY = 519,
|
||||
SIP_HDR_SERVER = 973,
|
||||
SIP_HDR_SERVICE_ROUTE = 1655,
|
||||
SIP_HDR_SESSION_EXPIRES = 1979,
|
||||
SIP_HDR_SIP_ETAG = 1997,
|
||||
SIP_HDR_SIP_IF_MATCH = 3056,
|
||||
SIP_HDR_SUBJECT = 1043,
|
||||
SIP_HDR_SUBSCRIPTION_STATE = 2884,
|
||||
SIP_HDR_SUPPORTED = 119,
|
||||
SIP_HDR_TARGET_DIALOG = 3450,
|
||||
SIP_HDR_TIMESTAMP = 938,
|
||||
SIP_HDR_TO = 1449,
|
||||
SIP_HDR_TRIGGER_CONSENT = 3180,
|
||||
SIP_HDR_UNSUPPORTED = 982,
|
||||
SIP_HDR_USER_AGENT = 4064,
|
||||
SIP_HDR_VIA = 3961,
|
||||
SIP_HDR_WARNING = 2108,
|
||||
SIP_HDR_WWW_AUTHENTICATE = 2763,
|
||||
|
||||
SIP_HDR_NONE = -1
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
SIP_T1 = 500,
|
||||
SIP_T2 = 4000,
|
||||
SIP_T4 = 5000,
|
||||
};
|
||||
|
||||
|
||||
struct sip_via {
|
||||
struct pl transp;
|
||||
struct pl sentby;
|
||||
struct sa addr;
|
||||
struct pl params;
|
||||
struct pl branch;
|
||||
struct pl val;
|
||||
};
|
||||
|
||||
struct sip_addr {
|
||||
struct pl dname;
|
||||
struct pl auri;
|
||||
struct uri uri;
|
||||
struct pl params;
|
||||
};
|
||||
|
||||
struct sip_taddr {
|
||||
struct pl dname;
|
||||
struct pl auri;
|
||||
struct uri uri;
|
||||
struct pl params;
|
||||
struct pl tag;
|
||||
struct pl val;
|
||||
};
|
||||
|
||||
struct sip_cseq {
|
||||
struct pl met;
|
||||
uint32_t num;
|
||||
};
|
||||
|
||||
struct sip_hdr {
|
||||
struct le le;
|
||||
struct le he;
|
||||
struct pl name;
|
||||
struct pl val;
|
||||
enum sip_hdrid id;
|
||||
};
|
||||
|
||||
struct sip_msg {
|
||||
struct sa src;
|
||||
struct sa dst;
|
||||
struct pl ver;
|
||||
struct pl met;
|
||||
struct pl ruri;
|
||||
struct uri uri;
|
||||
uint16_t scode;
|
||||
struct pl reason;
|
||||
struct list hdrl;
|
||||
struct sip_via via;
|
||||
struct sip_taddr to;
|
||||
struct sip_taddr from;
|
||||
struct sip_cseq cseq;
|
||||
struct pl callid;
|
||||
struct pl maxfwd;
|
||||
struct pl expires;
|
||||
struct pl ctype;
|
||||
struct pl clen;
|
||||
struct hash *hdrht;
|
||||
struct mbuf *mb;
|
||||
void *sock;
|
||||
uint64_t tag;
|
||||
enum sip_transp tp;
|
||||
bool req;
|
||||
};
|
||||
|
||||
struct sip_loopstate {
|
||||
uint32_t failc;
|
||||
uint16_t last_scode;
|
||||
};
|
||||
|
||||
struct sip;
|
||||
struct sip_lsnr;
|
||||
struct sip_request;
|
||||
struct sip_strans;
|
||||
struct sip_auth;
|
||||
struct sip_dialog;
|
||||
struct dnsc;
|
||||
|
||||
typedef bool(sip_msg_h)(const struct sip_msg *msg, void *arg);
|
||||
typedef int(sip_send_h)(enum sip_transp tp, const struct sa *src,
|
||||
const struct sa *dst, struct mbuf *mb, void *arg);
|
||||
typedef void(sip_resp_h)(int err, const struct sip_msg *msg, void *arg);
|
||||
typedef void(sip_cancel_h)(void *arg);
|
||||
typedef void(sip_exit_h)(void *arg);
|
||||
typedef int(sip_auth_h)(char **username, char **password, const char *realm,
|
||||
void *arg);
|
||||
typedef bool(sip_hdr_h)(const struct sip_hdr *hdr, const struct sip_msg *msg,
|
||||
void *arg);
|
||||
|
||||
|
||||
/* sip */
|
||||
int sip_alloc(struct sip **sipp, struct dnsc *dnsc, uint32_t ctsz,
|
||||
uint32_t stsz, uint32_t tcsz, const char *software,
|
||||
sip_exit_h *exith, void *arg);
|
||||
int sip_transp_add(struct sip *sip, enum sip_transp tp,
|
||||
const struct sa *laddr, ...);
|
||||
void sip_transp_flush(struct sip *sip);
|
||||
void sip_close(struct sip *sip, bool force);
|
||||
int sip_listen(struct sip_lsnr **lsnrp, struct sip *sip, bool req,
|
||||
sip_msg_h *msgh, void *arg);
|
||||
int sip_debug(struct re_printf *pf, const struct sip *sip);
|
||||
int sip_send(struct sip *sip, void *sock, enum sip_transp tp,
|
||||
const struct sa *dst, struct mbuf *mb);
|
||||
const char *sip_transp_name(enum sip_transp tp);
|
||||
const char *sip_transp_param(enum sip_transp tp);
|
||||
|
||||
|
||||
/* request */
|
||||
int sip_request(struct sip_request **reqp, struct sip *sip, bool stateful,
|
||||
const char *met, int metl, const char *uri, int uril,
|
||||
const struct uri *route, struct mbuf *mb,
|
||||
sip_send_h *sendh, sip_resp_h *resph, void *arg);
|
||||
int sip_requestf(struct sip_request **reqp, struct sip *sip, bool stateful,
|
||||
const char *met, const char *uri, const struct uri *route,
|
||||
struct sip_auth *auth, sip_send_h *sendh, sip_resp_h *resph,
|
||||
void *arg, const char *fmt, ...);
|
||||
int sip_drequestf(struct sip_request **reqp, struct sip *sip, bool stateful,
|
||||
const char *met, struct sip_dialog *dlg, uint32_t cseq,
|
||||
struct sip_auth *auth, sip_send_h *sendh, sip_resp_h *resph,
|
||||
void *arg, const char *fmt, ...);
|
||||
void sip_request_cancel(struct sip_request *req);
|
||||
bool sip_request_loops(struct sip_loopstate *ls, uint16_t scode);
|
||||
void sip_loopstate_reset(struct sip_loopstate *ls);
|
||||
|
||||
|
||||
/* reply */
|
||||
int sip_strans_alloc(struct sip_strans **stp, struct sip *sip,
|
||||
const struct sip_msg *msg, sip_cancel_h *cancelh,
|
||||
void *arg);
|
||||
int sip_strans_reply(struct sip_strans **stp, struct sip *sip,
|
||||
const struct sip_msg *msg, const struct sa *dst,
|
||||
uint16_t scode, struct mbuf *mb);
|
||||
int sip_treplyf(struct sip_strans **stp, struct mbuf **mbp, struct sip *sip,
|
||||
const struct sip_msg *msg, bool rec_route, uint16_t scode,
|
||||
const char *reason, const char *fmt, ...);
|
||||
int sip_treply(struct sip_strans **stp, struct sip *sip,
|
||||
const struct sip_msg *msg, uint16_t scode, const char *reason);
|
||||
int sip_replyf(struct sip *sip, const struct sip_msg *msg, uint16_t scode,
|
||||
const char *reason, const char *fmt, ...);
|
||||
int sip_reply(struct sip *sip, const struct sip_msg *msg, uint16_t scode,
|
||||
const char *reason);
|
||||
void sip_reply_addr(struct sa *addr, const struct sip_msg *msg, bool rport);
|
||||
|
||||
|
||||
/* auth */
|
||||
int sip_auth_authenticate(struct sip_auth *auth, const struct sip_msg *msg);
|
||||
int sip_auth_alloc(struct sip_auth **authp, sip_auth_h *authh,
|
||||
void *arg, bool ref);
|
||||
|
||||
|
||||
/* dialog */
|
||||
int sip_dialog_alloc(struct sip_dialog **dlgp,
|
||||
const char *uri, const char *to_uri,
|
||||
const char *from_name, const char *from_uri,
|
||||
const char *routev[], uint32_t routec);
|
||||
int sip_dialog_accept(struct sip_dialog **dlgp, const struct sip_msg *msg);
|
||||
int sip_dialog_create(struct sip_dialog *dlg, const struct sip_msg *msg);
|
||||
int sip_dialog_update(struct sip_dialog *dlg, const struct sip_msg *msg);
|
||||
bool sip_dialog_rseq_valid(struct sip_dialog *dlg, const struct sip_msg *msg);
|
||||
const char *sip_dialog_callid(const struct sip_dialog *dlg);
|
||||
bool sip_dialog_cmp(const struct sip_dialog *dlg, const struct sip_msg *msg);
|
||||
|
||||
|
||||
/* msg */
|
||||
int sip_msg_decode(struct sip_msg **msgp, struct mbuf *mb);
|
||||
const struct sip_hdr *sip_msg_hdr(const struct sip_msg *msg,
|
||||
enum sip_hdrid id);
|
||||
const struct sip_hdr *sip_msg_hdr_apply(const struct sip_msg *msg,
|
||||
bool fwd, enum sip_hdrid id,
|
||||
sip_hdr_h *h, void *arg);
|
||||
const struct sip_hdr *sip_msg_xhdr(const struct sip_msg *msg,
|
||||
const char *name);
|
||||
const struct sip_hdr *sip_msg_xhdr_apply(const struct sip_msg *msg,
|
||||
bool fwd, const char *name,
|
||||
sip_hdr_h *h, void *arg);
|
||||
struct tcp_conn *sip_msg_tcpconn(const struct sip_msg *msg);
|
||||
void sip_msg_dump(const struct sip_msg *msg);
|
||||
|
||||
int sip_addr_decode(struct sip_addr *addr, const struct pl *pl);
|
||||
int sip_via_decode(struct sip_via *via, const struct pl *pl);
|
||||
int sip_cseq_decode(struct sip_cseq *cseq, const struct pl *pl);
|
||||
int sip_param_decode(const struct pl *pl, const char *name, struct pl *val);
|
||||
int sip_param_exists(const struct pl *pl, const char *name, struct pl *end);
|
15
include/re_sipreg.h
Normal file
15
include/re_sipreg.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* @file re_sipreg.h SIP Registration
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
struct sipreg;
|
||||
|
||||
|
||||
int sipreg_register(struct sipreg **regp, struct sip *sip, const char *reg_uri,
|
||||
const char *to_uri, const char *from_uri, uint32_t expires,
|
||||
const char *cuser, const char *routev[], uint32_t routec,
|
||||
sip_auth_h *authh, void *aarg, bool ref,
|
||||
sip_resp_h *resph, void *arg,
|
||||
const char *params, const char *fmt, ...);
|
59
include/re_sipsess.h
Normal file
59
include/re_sipsess.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* @file re_sipsess.h SIP Session
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
struct sipsess_sock;
|
||||
struct sipsess;
|
||||
|
||||
|
||||
typedef void (sipsess_conn_h)(const struct sip_msg *msg, void *arg);
|
||||
typedef int (sipsess_offer_h)(struct mbuf **descp, const struct sip_msg *msg,
|
||||
void *arg);
|
||||
typedef int (sipsess_answer_h)(const struct sip_msg *msg, void *arg);
|
||||
typedef void (sipsess_progr_h)(const struct sip_msg *msg, void *arg);
|
||||
typedef void (sipsess_estab_h)(const struct sip_msg *msg, void *arg);
|
||||
typedef void (sipsess_info_h)(struct sip *sip, const struct sip_msg *msg,
|
||||
void *arg);
|
||||
typedef void (sipsess_refer_h)(struct sip *sip, const struct sip_msg *msg,
|
||||
void *arg);
|
||||
typedef void (sipsess_close_h)(int err, const struct sip_msg *msg, void *arg);
|
||||
|
||||
|
||||
int sipsess_listen(struct sipsess_sock **sockp, struct sip *sip,
|
||||
int htsize, sipsess_conn_h *connh, void *arg);
|
||||
|
||||
int sipsess_connect(struct sipsess **sessp, struct sipsess_sock *sock,
|
||||
const char *to_uri, const char *from_name,
|
||||
const char *from_uri, const char *cuser,
|
||||
const char *routev[], uint32_t routec,
|
||||
const char *ctype, struct mbuf *desc,
|
||||
sip_auth_h *authh, void *aarg, bool aref,
|
||||
sipsess_offer_h *offerh, sipsess_answer_h *answerh,
|
||||
sipsess_progr_h *progrh, sipsess_estab_h *estabh,
|
||||
sipsess_info_h *infoh, sipsess_refer_h *referh,
|
||||
sipsess_close_h *closeh, void *arg, const char *fmt, ...);
|
||||
|
||||
int sipsess_accept(struct sipsess **sessp, struct sipsess_sock *sock,
|
||||
const struct sip_msg *msg, uint16_t scode,
|
||||
const char *reason, const char *cuser, const char *ctype,
|
||||
struct mbuf *desc,
|
||||
sip_auth_h *authh, void *aarg, bool aref,
|
||||
sipsess_offer_h *offerh, sipsess_answer_h *answerh,
|
||||
sipsess_estab_h *estabh, sipsess_info_h *infoh,
|
||||
sipsess_refer_h *referh, sipsess_close_h *closeh,
|
||||
void *arg, const char *fmt, ...);
|
||||
|
||||
int sipsess_progress(struct sipsess *sess, uint16_t scode,
|
||||
const char *reason, struct mbuf *desc,
|
||||
const char *fmt, ...);
|
||||
int sipsess_answer(struct sipsess *sess, uint16_t scode, const char *reason,
|
||||
struct mbuf *desc, const char *fmt, ...);
|
||||
int sipsess_reject(struct sipsess *sess, uint16_t scode, const char *reason,
|
||||
const char *fmt, ...);
|
||||
int sipsess_modify(struct sipsess *sess, struct mbuf *desc);
|
||||
int sipsess_info(struct sipsess *sess, const char *ctype, struct mbuf *body,
|
||||
sip_resp_h *resph, void *arg);
|
||||
void sipsess_close_all(struct sipsess_sock *sock);
|
||||
struct sip_dialog *sipsess_dialog(struct sipsess *sess);
|
278
include/re_stun.h
Normal file
278
include/re_stun.h
Normal file
|
@ -0,0 +1,278 @@
|
|||
/**
|
||||
* @file re_stun.h Session Traversal Utilities for (NAT) (STUN)
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
enum {
|
||||
STUN_PORT = 3478, /**< STUN Port number */
|
||||
STUN_HEADER_SIZE = 20, /**< Number of bytes in header */
|
||||
STUN_ATTR_HEADER_SIZE = 4, /**< Size of attribute header */
|
||||
STUN_TID_SIZE = 12, /**< Number of bytes in transaction ID */
|
||||
STUN_DEFAULT_RTO = 500, /**< Default Retrans Timeout in [ms] */
|
||||
STUN_DEFAULT_RC = 7, /**< Default number of retransmits */
|
||||
STUN_DEFAULT_RM = 16, /**< Wait time after last request is sent */
|
||||
STUN_DEFAULT_TI = 39500 /**< Reliable timeout */
|
||||
};
|
||||
|
||||
/** STUN Address Family */
|
||||
enum stun_af {
|
||||
STUN_AF_IPv4 = 0x01, /**< IPv4 Address Family */
|
||||
STUN_AF_IPv6 = 0x02 /**< IPv6 Address Family */
|
||||
};
|
||||
|
||||
/** STUN Methods */
|
||||
enum stun_method {
|
||||
STUN_METHOD_BINDING = 0x001,
|
||||
STUN_METHOD_ALLOCATE = 0x003,
|
||||
STUN_METHOD_REFRESH = 0x004,
|
||||
STUN_METHOD_SEND = 0x006,
|
||||
STUN_METHOD_DATA = 0x007,
|
||||
STUN_METHOD_CREATEPERM = 0x008,
|
||||
STUN_METHOD_CHANBIND = 0x009,
|
||||
};
|
||||
|
||||
/** STUN Message class */
|
||||
enum stun_msg_class {
|
||||
STUN_CLASS_REQUEST = 0x0, /**< STUN Request */
|
||||
STUN_CLASS_INDICATION = 0x1, /**< STUN Indication */
|
||||
STUN_CLASS_SUCCESS_RESP = 0x2, /**< STUN Success Response */
|
||||
STUN_CLASS_ERROR_RESP = 0x3 /**< STUN Error Response */
|
||||
};
|
||||
|
||||
/** STUN Attributes */
|
||||
enum stun_attrib {
|
||||
/* Comprehension-required range (0x0000-0x7FFF) */
|
||||
STUN_ATTR_MAPPED_ADDR = 0x0001,
|
||||
STUN_ATTR_CHANGE_REQ = 0x0003,
|
||||
STUN_ATTR_USERNAME = 0x0006,
|
||||
STUN_ATTR_MSG_INTEGRITY = 0x0008,
|
||||
STUN_ATTR_ERR_CODE = 0x0009,
|
||||
STUN_ATTR_UNKNOWN_ATTR = 0x000a,
|
||||
STUN_ATTR_CHANNEL_NUMBER = 0x000c,
|
||||
STUN_ATTR_LIFETIME = 0x000d,
|
||||
STUN_ATTR_XOR_PEER_ADDR = 0x0012,
|
||||
STUN_ATTR_DATA = 0x0013,
|
||||
STUN_ATTR_REALM = 0x0014,
|
||||
STUN_ATTR_NONCE = 0x0015,
|
||||
STUN_ATTR_XOR_RELAY_ADDR = 0x0016,
|
||||
STUN_ATTR_REQ_ADDR_FAMILY = 0x0017,
|
||||
STUN_ATTR_EVEN_PORT = 0x0018,
|
||||
STUN_ATTR_REQ_TRANSPORT = 0x0019,
|
||||
STUN_ATTR_DONT_FRAGMENT = 0x001a,
|
||||
STUN_ATTR_XOR_MAPPED_ADDR = 0x0020,
|
||||
STUN_ATTR_RSV_TOKEN = 0x0022,
|
||||
STUN_ATTR_PRIORITY = 0x0024,
|
||||
STUN_ATTR_USE_CAND = 0x0025,
|
||||
STUN_ATTR_PADDING = 0x0026,
|
||||
STUN_ATTR_RESP_PORT = 0x0027,
|
||||
|
||||
/* Comprehension-optional range (0x8000-0xFFFF) */
|
||||
STUN_ATTR_SOFTWARE = 0x8022,
|
||||
STUN_ATTR_ALT_SERVER = 0x8023,
|
||||
STUN_ATTR_FINGERPRINT = 0x8028,
|
||||
STUN_ATTR_CONTROLLED = 0x8029,
|
||||
STUN_ATTR_CONTROLLING = 0x802a,
|
||||
STUN_ATTR_RESP_ORIGIN = 0x802b,
|
||||
STUN_ATTR_OTHER_ADDR = 0x802c,
|
||||
};
|
||||
|
||||
|
||||
struct stun_change_req {
|
||||
bool ip;
|
||||
bool port;
|
||||
};
|
||||
|
||||
struct stun_errcode {
|
||||
uint16_t code;
|
||||
char *reason;
|
||||
};
|
||||
|
||||
struct stun_unknown_attr {
|
||||
uint16_t typev[8];
|
||||
uint32_t typec;
|
||||
};
|
||||
|
||||
struct stun_even_port {
|
||||
bool r;
|
||||
};
|
||||
|
||||
struct stun_attr {
|
||||
struct le le;
|
||||
uint16_t type;
|
||||
union {
|
||||
/* generic types */
|
||||
struct sa sa;
|
||||
char *str;
|
||||
uint64_t uint64;
|
||||
uint32_t uint32;
|
||||
uint16_t uint16;
|
||||
uint8_t uint8;
|
||||
struct mbuf mb;
|
||||
|
||||
/* actual attributes */
|
||||
struct sa mapped_addr;
|
||||
struct stun_change_req change_req;
|
||||
char *username;
|
||||
uint8_t msg_integrity[20];
|
||||
struct stun_errcode err_code;
|
||||
struct stun_unknown_attr unknown_attr;
|
||||
uint16_t channel_number;
|
||||
uint32_t lifetime;
|
||||
struct sa xor_peer_addr;
|
||||
struct mbuf data;
|
||||
char *realm;
|
||||
char *nonce;
|
||||
struct sa xor_relay_addr;
|
||||
uint8_t req_addr_family;
|
||||
struct stun_even_port even_port;
|
||||
uint8_t req_transport;
|
||||
struct sa xor_mapped_addr;
|
||||
uint64_t rsv_token;
|
||||
uint32_t priority;
|
||||
struct mbuf padding;
|
||||
uint16_t resp_port;
|
||||
char *software;
|
||||
struct sa alt_server;
|
||||
uint32_t fingerprint;
|
||||
uint64_t controlled;
|
||||
uint64_t controlling;
|
||||
struct sa resp_origin;
|
||||
struct sa other_addr;
|
||||
} v;
|
||||
};
|
||||
|
||||
|
||||
struct stun_conf {
|
||||
uint32_t rto;
|
||||
uint32_t rc;
|
||||
uint32_t rm;
|
||||
uint32_t ti;
|
||||
uint8_t tos; /**< Type-of-service field */
|
||||
};
|
||||
|
||||
|
||||
extern const char *stun_software;
|
||||
struct stun;
|
||||
struct stun_msg;
|
||||
struct stun_ctrans;
|
||||
|
||||
typedef void(stun_resp_h)(int err, uint16_t scode, const char *reason,
|
||||
const struct stun_msg *msg, void *arg);
|
||||
typedef void(stun_ind_h)(struct stun_msg *msg, void *arg);
|
||||
typedef bool(stun_attr_h)(const struct stun_attr *attr, void *arg);
|
||||
|
||||
int stun_alloc(struct stun **stunp, const struct stun_conf *conf,
|
||||
stun_ind_h *indh, void *arg);
|
||||
struct stun_conf *stun_conf(struct stun *stun);
|
||||
int stun_send(int proto, void *sock, const struct sa *dst, struct mbuf *mb);
|
||||
int stun_recv(struct stun *stun, struct mbuf *mb);
|
||||
int stun_ctrans_recv(struct stun *stun, const struct stun_msg *msg,
|
||||
const struct stun_unknown_attr *ua);
|
||||
struct re_printf;
|
||||
int stun_debug(struct re_printf *pf, const struct stun *stun);
|
||||
|
||||
int stun_request(struct stun_ctrans **ctp, struct stun *stun, int proto,
|
||||
void *sock, const struct sa *dst, size_t presz,
|
||||
uint16_t method, const uint8_t *key, size_t keylen, bool fp,
|
||||
stun_resp_h *resph, void *arg, uint32_t attrc, ...);
|
||||
int stun_reply(int proto, void *sock, const struct sa *dst, size_t presz,
|
||||
const struct stun_msg *req, const uint8_t *key,
|
||||
size_t keylen, bool fp, uint32_t attrc, ...);
|
||||
int stun_ereply(int proto, void *sock, const struct sa *dst, size_t presz,
|
||||
const struct stun_msg *req, uint16_t scode,
|
||||
const char *reason, const uint8_t *key, size_t keylen,
|
||||
bool fp, uint32_t attrc, ...);
|
||||
int stun_indication(int proto, void *sock, const struct sa *dst, size_t presz,
|
||||
uint16_t method, const uint8_t *key, size_t keylen,
|
||||
bool fp, uint32_t attrc, ...);
|
||||
|
||||
int stun_msg_encode(struct mbuf *mb, uint16_t method, uint8_t cls,
|
||||
const uint8_t *tid, const struct stun_errcode *ec,
|
||||
const uint8_t *key, size_t keylen, bool fp,
|
||||
uint8_t padding, uint32_t attrc, ...);
|
||||
int stun_msg_decode(struct stun_msg **msgpp, struct mbuf *mb,
|
||||
struct stun_unknown_attr *ua);
|
||||
uint16_t stun_msg_type(const struct stun_msg *msg);
|
||||
uint16_t stun_msg_class(const struct stun_msg *msg);
|
||||
uint16_t stun_msg_method(const struct stun_msg *msg);
|
||||
bool stun_msg_mcookie(const struct stun_msg *msg);
|
||||
const uint8_t *stun_msg_tid(const struct stun_msg *msg);
|
||||
struct stun_attr *stun_msg_attr(const struct stun_msg *msg, uint16_t type);
|
||||
struct stun_attr *stun_msg_attr_apply(const struct stun_msg *msg,
|
||||
stun_attr_h *h, void *arg);
|
||||
int stun_msg_chk_mi(const struct stun_msg *msg, const uint8_t *key,
|
||||
size_t keylen);
|
||||
int stun_msg_chk_fingerprint(const struct stun_msg *msg);
|
||||
void stun_msg_dump(const struct stun_msg *msg);
|
||||
|
||||
const char *stun_class_name(uint16_t cls);
|
||||
const char *stun_method_name(uint16_t method);
|
||||
const char *stun_attr_name(uint16_t type);
|
||||
|
||||
|
||||
/* DNS Discovery of a STUN Server */
|
||||
extern const char *stun_proto_udp;
|
||||
extern const char *stun_proto_tcp;
|
||||
|
||||
extern const char *stun_usage_binding;
|
||||
extern const char *stuns_usage_binding;
|
||||
extern const char *stun_usage_relay;
|
||||
extern const char *stuns_usage_relay;
|
||||
extern const char *stun_usage_behavior;
|
||||
extern const char *stuns_usage_behavior;
|
||||
|
||||
|
||||
/**
|
||||
* Defines the STUN Server Discovery handler
|
||||
*
|
||||
* @param err Errorcode
|
||||
* @param srv IP Address and port of STUN Server
|
||||
* @param arg Handler argument
|
||||
*/
|
||||
typedef void (stun_dns_h)(int err, const struct sa *srv, void *arg);
|
||||
|
||||
struct stun_dns;
|
||||
struct dnsc;
|
||||
int stun_server_discover(struct stun_dns **dnsp, struct dnsc *dnsc,
|
||||
const char *service, const char *proto,
|
||||
int af, const char *domain, uint16_t port,
|
||||
stun_dns_h *dnsh, void *arg);
|
||||
|
||||
|
||||
/* NAT Keepalives */
|
||||
struct stun_keepalive;
|
||||
|
||||
/**
|
||||
* Defines the STUN Keepalive Mapped-Address handler
|
||||
*
|
||||
* @param err Errorcode
|
||||
* @param map Mapped Address
|
||||
* @param arg Handler argument
|
||||
*/
|
||||
typedef void (stun_mapped_addr_h)(int err, const struct sa *map, void *arg);
|
||||
|
||||
|
||||
int stun_keepalive_alloc(struct stun_keepalive **skap,
|
||||
int proto, void *sock, int layer,
|
||||
const struct sa *dst, const struct stun_conf *conf,
|
||||
stun_mapped_addr_h *mah, void *arg);
|
||||
void stun_keepalive_enable(struct stun_keepalive *ska, uint32_t interval);
|
||||
|
||||
|
||||
/* STUN Reason Phrase */
|
||||
extern const char *stun_reason_300;
|
||||
extern const char *stun_reason_400;
|
||||
extern const char *stun_reason_401;
|
||||
extern const char *stun_reason_403;
|
||||
extern const char *stun_reason_420;
|
||||
extern const char *stun_reason_437;
|
||||
extern const char *stun_reason_438;
|
||||
extern const char *stun_reason_440;
|
||||
extern const char *stun_reason_441;
|
||||
extern const char *stun_reason_442;
|
||||
extern const char *stun_reason_443;
|
||||
extern const char *stun_reason_486;
|
||||
extern const char *stun_reason_500;
|
||||
extern const char *stun_reason_508;
|
75
include/re_sys.h
Normal file
75
include/re_sys.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* @file re_sys.h Interface to system module
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
#ifndef VERSION
|
||||
#define VERSION "?"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def ARCH
|
||||
*
|
||||
* Architecture
|
||||
*/
|
||||
#ifndef ARCH
|
||||
#ifdef __SYMBIAN32__
|
||||
#if defined(__WINS__)
|
||||
#define ARCH "WINS"
|
||||
#elif defined(__MARM__)
|
||||
#define ARCH "ARM"
|
||||
#elif defined(__MARM_ARMI__)
|
||||
#define ARCH "ARMI"
|
||||
#elif defined(EKA2)
|
||||
#define ARCH "EKA2"
|
||||
#else
|
||||
#define ARCH "Symbian Arch"
|
||||
#endif
|
||||
#else
|
||||
#define ARCH "?"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OS
|
||||
*
|
||||
* Operating System
|
||||
*/
|
||||
#ifndef OS
|
||||
#ifdef __SYMBIAN32__
|
||||
#define OS "Symbian"
|
||||
#elif defined (WIN32)
|
||||
#define OS "win32"
|
||||
#else
|
||||
#define OS "?"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct re_printf;
|
||||
int sys_rel_get(uint32_t *rel, uint32_t *maj, uint32_t *min,
|
||||
uint32_t *patch);
|
||||
int sys_kernel_get(struct re_printf *pf, void *unused);
|
||||
int sys_build_get(struct re_printf *pf, void *unused);
|
||||
const char *sys_arch_get(void);
|
||||
const char *sys_os_get(void);
|
||||
const char *sys_libre_version_get(void);
|
||||
int sys_coredump_set(bool enable);
|
||||
int sys_daemon(void);
|
||||
|
||||
|
||||
uint16_t sys_ltohs(uint16_t v);
|
||||
uint32_t sys_ltohl(uint32_t v);
|
||||
uint64_t sys_htonll(uint64_t v);
|
||||
uint64_t sys_ntohll(uint64_t v);
|
||||
|
||||
|
||||
/* Random */
|
||||
void rand_init(void);
|
||||
uint16_t rand_u16(void);
|
||||
uint32_t rand_u32(void);
|
||||
uint64_t rand_u64(void);
|
||||
char rand_char(void);
|
||||
void rand_str(char *str, size_t size);
|
||||
void rand_bytes(uint8_t *p, size_t size);
|
101
include/re_tcp.h
Normal file
101
include/re_tcp.h
Normal file
|
@ -0,0 +1,101 @@
|
|||
/**
|
||||
* @file re_tcp.h Interface to Transport Control Protocol
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
struct sa;
|
||||
struct tcp_sock;
|
||||
struct tcp_conn;
|
||||
|
||||
|
||||
/**
|
||||
* Defines the incoming TCP connection handler
|
||||
*
|
||||
* @param peer Network address of peer
|
||||
* @param arg Handler argument
|
||||
*/
|
||||
typedef void (tcp_conn_h)(const struct sa *peer, void *arg);
|
||||
|
||||
/**
|
||||
* Defines the TCP connection established handler
|
||||
*
|
||||
* @param arg Handler argument
|
||||
*/
|
||||
typedef void (tcp_estab_h)(void *arg);
|
||||
|
||||
/**
|
||||
* Defines the TCP connection data send handler
|
||||
*
|
||||
* @param arg Handler argument
|
||||
*/
|
||||
typedef void (tcp_send_h)(void *arg);
|
||||
|
||||
/**
|
||||
* Defines the TCP connection data receive handler
|
||||
*
|
||||
* @param mb Buffer with data
|
||||
* @param arg Handler argument
|
||||
*/
|
||||
typedef void (tcp_recv_h)(struct mbuf *mb, void *arg);
|
||||
|
||||
/**
|
||||
* Defines the TCP connection close handler
|
||||
*
|
||||
* @param err Error code
|
||||
* @param arg Handler argument
|
||||
*/
|
||||
typedef void (tcp_close_h)(int err, void *arg);
|
||||
|
||||
|
||||
/* TCP Socket */
|
||||
int tcp_sock_alloc(struct tcp_sock **tsp, const struct sa *local,
|
||||
tcp_conn_h *ch, void *arg);
|
||||
int tcp_sock_bind(struct tcp_sock *ts, const struct sa *local);
|
||||
int tcp_sock_listen(struct tcp_sock *ts, int backlog);
|
||||
int tcp_accept(struct tcp_conn **tcp, struct tcp_sock *ts, tcp_estab_h *eh,
|
||||
tcp_recv_h *rh, tcp_close_h *ch, void *arg);
|
||||
void tcp_reject(struct tcp_sock *ts);
|
||||
int tcp_sock_local_get(const struct tcp_sock *ts, struct sa *local);
|
||||
|
||||
|
||||
/* TCP Connection */
|
||||
int tcp_conn_alloc(struct tcp_conn **tcp, const struct sa *peer,
|
||||
tcp_estab_h *eh, tcp_recv_h *rh, tcp_close_h *ch,
|
||||
void *arg);
|
||||
int tcp_conn_bind(struct tcp_conn *tc, const struct sa *local);
|
||||
int tcp_conn_connect(struct tcp_conn *tc, const struct sa *peer);
|
||||
int tcp_send(struct tcp_conn *tc, struct mbuf *mb);
|
||||
int tcp_set_send(struct tcp_conn *tc, tcp_send_h *sendh);
|
||||
void tcp_conn_rxsz_set(struct tcp_conn *tc, size_t rxsz);
|
||||
int tcp_conn_local_get(const struct tcp_conn *tc, struct sa *local);
|
||||
int tcp_conn_peer_get(const struct tcp_conn *tc, struct sa *peer);
|
||||
int tcp_conn_fd(const struct tcp_conn *tc);
|
||||
|
||||
|
||||
/* High-level API */
|
||||
int tcp_listen(struct tcp_sock **tsp, const struct sa *local,
|
||||
tcp_conn_h *ch, void *arg);
|
||||
int tcp_connect(struct tcp_conn **tcp, const struct sa *peer,
|
||||
tcp_estab_h *eh, tcp_recv_h *rh, tcp_close_h *ch, void *arg);
|
||||
int tcp_local_get(const struct tcp_sock *ts, struct sa *local);
|
||||
|
||||
|
||||
#ifdef __SYMBIAN32__
|
||||
struct RSocketServ;
|
||||
struct RConnection;
|
||||
void tcp_rconn_set(struct RSocketServ *sockSrv, struct RConnection *rconn);
|
||||
#endif
|
||||
|
||||
|
||||
/* Helper API */
|
||||
typedef bool (tcp_helper_estab_h)(int *err, bool active, void *arg);
|
||||
typedef bool (tcp_helper_send_h)(int *err, struct mbuf *mb, void *arg);
|
||||
typedef bool (tcp_helper_recv_h)(int *err, struct mbuf *mb, bool *estab,
|
||||
void *arg);
|
||||
|
||||
struct tcp_helper;
|
||||
|
||||
|
||||
int tcp_register_helper(struct tcp_helper **thp, struct tcp_conn *tc, int *fd,
|
||||
tcp_helper_estab_h *eh, tcp_helper_send_h *sh,
|
||||
tcp_helper_recv_h *rh, void *arg);
|
22
include/re_telev.h
Normal file
22
include/re_telev.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* @file re_telev.h Interface to Telephony Events (RFC 4733)
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
enum {
|
||||
TELEV_PTIME = 50,
|
||||
TELEV_SRATE = 8000
|
||||
};
|
||||
|
||||
struct telev;
|
||||
|
||||
extern const char telev_rtpfmt[];
|
||||
|
||||
int telev_alloc(struct telev **tp, uint32_t ptime);
|
||||
int telev_send(struct telev *tel, int event, bool end);
|
||||
int telev_recv(struct telev *tel, struct mbuf *mb, int *event, bool *end);
|
||||
int telev_poll(struct telev *tel, bool *marker, struct mbuf *mb);
|
||||
|
||||
int telev_digit2code(int digit);
|
||||
int telev_code2digit(int code);
|
17
include/re_tls.h
Normal file
17
include/re_tls.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* @file re_tls.h Interface to Transport Layer Security
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
struct tls;
|
||||
struct tls_conn;
|
||||
|
||||
|
||||
int tls_alloc(struct tls **tlsp, const char *keyfile, const char *pwd);
|
||||
int tls_add_ca(struct tls *tls, const char *capath);
|
||||
int tls_verify_cert(struct tls_conn *tc, char *cn, size_t cn_size);
|
||||
|
||||
int tls_start_tcp(struct tls_conn **ptc, struct tls *tls,
|
||||
struct tcp_conn *tcp);
|
33
include/re_tmr.h
Normal file
33
include/re_tmr.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* @file re_tmr.h Interface to timer implementation
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Defines the timeout handler
|
||||
*
|
||||
* @param arg Handler argument
|
||||
*/
|
||||
typedef void (tmr_h)(void *arg);
|
||||
|
||||
/** Defines a timer */
|
||||
struct tmr {
|
||||
struct le le; /**< Linked list element */
|
||||
struct list *tmrl; /**< Parent list */
|
||||
tmr_h *th; /**< Timeout handler */
|
||||
void *arg; /**< Handler argument */
|
||||
uint64_t jfs; /**< Jiffies for timeout */
|
||||
};
|
||||
|
||||
|
||||
void tmr_poll(struct list *tmrl);
|
||||
uint64_t tmr_jiffies(void);
|
||||
uint64_t tmr_next_timeout(struct list *tmrl);
|
||||
void tmr_debug(void);
|
||||
|
||||
void tmr_init(struct tmr *tmr);
|
||||
void tmr_start(struct tmr *tmr, uint64_t delay, tmr_h *th, void *arg);
|
||||
void tmr_cancel(struct tmr *tmr);
|
||||
uint64_t tmr_get_expire(const struct tmr *tmr);
|
28
include/re_turn.h
Normal file
28
include/re_turn.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* @file re_turn.h Interface to TURN implementation
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
enum {
|
||||
TURN_DEFAULT_LIFETIME = 600, /**< Default lifetime is 10 minutes */
|
||||
TURN_MAX_LIFETIME = 3600 /**< Maximum lifetime is 1 hour */
|
||||
};
|
||||
|
||||
typedef void(turnc_h)(int err, uint16_t scode, const char *reason,
|
||||
const struct sa *relay_addr,
|
||||
const struct sa *mapped_addr,
|
||||
void *arg);
|
||||
typedef void(turnc_perm_h)(void *arg);
|
||||
typedef void(turnc_chan_h)(void *arg);
|
||||
|
||||
struct turnc;
|
||||
|
||||
int turnc_alloc(struct turnc **turncp, const struct stun_conf *conf, int proto,
|
||||
void *sock, int layer, const struct sa *srv,
|
||||
const char *username, const char *password,
|
||||
uint32_t lifetime, turnc_h *th, void *arg);
|
||||
int turnc_add_perm(struct turnc *turnc, const struct sa *peer,
|
||||
turnc_perm_h *ph, void *arg);
|
||||
int turnc_add_chan(struct turnc *turnc, const struct sa *peer,
|
||||
turnc_chan_h *ch, void *arg);
|
234
include/re_types.h
Normal file
234
include/re_types.h
Normal file
|
@ -0,0 +1,234 @@
|
|||
/**
|
||||
* @file re_types.h Defines basic types
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Basic integral types from C99
|
||||
*/
|
||||
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
|
||||
#ifndef __int8_t_defined
|
||||
#define __int8_t_defined
|
||||
|
||||
/* Hack for OpenBSD */
|
||||
#ifndef __BIT_TYPES_DEFINED__
|
||||
|
||||
#if defined(_CHAR_IS_SIGNED)
|
||||
typedef char int8_t;
|
||||
#elif defined(__STDC__)
|
||||
typedef signed char int8_t;
|
||||
#else
|
||||
typedef char int8_t;
|
||||
#endif
|
||||
|
||||
typedef signed short int int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef signed long long int int64_t;
|
||||
|
||||
#ifndef __uint32_t_defined
|
||||
#define __uint32_t_defined
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short int uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned long long int uint64_t;
|
||||
#endif
|
||||
|
||||
#endif /* __BIT_TYPES_DEFINED__ */
|
||||
|
||||
#endif /* __int8_t_defined */
|
||||
#ifndef __ssize_t_defined
|
||||
typedef long ssize_t;
|
||||
#define __ssize_t_defined
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
typedef uint32_t socklen_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Hack for Solaris which does not define int64_t/uint64_t for strict ANSI C
|
||||
*/
|
||||
#ifdef SOLARIS
|
||||
#if !(__STDC__ - 0 == 0 && !defined(_NO_LONGLONG))
|
||||
typedef signed long long int int64_t;
|
||||
typedef unsigned long long int uint64_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Boolean type
|
||||
* see http://www.opengroup.org/onlinepubs/000095399/basedefs/stdbool.h.html
|
||||
* www.gnu.org/software/autoconf/manual/html_node/Particular-Headers.html
|
||||
*/
|
||||
#ifdef HAVE_STDBOOL_H
|
||||
# include <stdbool.h>
|
||||
#else
|
||||
# ifndef HAVE__BOOL
|
||||
# ifdef __cplusplus
|
||||
typedef bool _Bool;
|
||||
# else
|
||||
# define _Bool signed char
|
||||
# endif
|
||||
# endif
|
||||
# define bool _Bool
|
||||
# define false 0
|
||||
# define true 1
|
||||
# define __bool_true_false_are_defined 1
|
||||
#endif
|
||||
|
||||
/* Needed for MS compiler */
|
||||
#ifdef _MSC_VER
|
||||
#define inline _inline
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Misc macros
|
||||
*/
|
||||
|
||||
/** Defines the NULL pointer */
|
||||
#ifndef NULL
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
/** Get number of elements in an array */
|
||||
#undef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(a) ((sizeof(a))/(sizeof((a)[0])))
|
||||
|
||||
/** Align a value to the boundary of mask */
|
||||
#define ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
|
||||
|
||||
|
||||
/** Get the minimal value */
|
||||
#undef MIN
|
||||
#define MIN(a,b) (((a)<(b)) ? (a) : (b))
|
||||
|
||||
/** Get the maximal value */
|
||||
#undef MAX
|
||||
#define MAX(a,b) (((a)>(b)) ? (a) : (b))
|
||||
|
||||
/** Get the minimal value */
|
||||
#undef min
|
||||
#define min(x,y) MIN(x, y)
|
||||
|
||||
/** Get the maximal value */
|
||||
#undef max
|
||||
#define max(x,y) MAX(x, y)
|
||||
|
||||
/** Defines a soft breakpoint */
|
||||
#if (defined(__i386__) || defined(__x86_64__)) && !defined(__SYMBIAN32__)
|
||||
#define BREAKPOINT __asm__("int $0x03")
|
||||
#else
|
||||
#define BREAKPOINT
|
||||
#endif
|
||||
|
||||
|
||||
/* Error codes */
|
||||
#include <errno.h>
|
||||
|
||||
/* Duplication of error codes. Values are from linux asm-generic/errno.h */
|
||||
|
||||
/** No data available */
|
||||
#ifndef ENODATA
|
||||
#define ENODATA 61
|
||||
#endif
|
||||
|
||||
/** Protocol error */
|
||||
#ifndef EPROTO
|
||||
#define EPROTO 71
|
||||
#endif
|
||||
|
||||
/** Not a data message */
|
||||
#ifndef EBADMSG
|
||||
#define EBADMSG 74
|
||||
#endif
|
||||
|
||||
/** Value too large for defined data type */
|
||||
#ifndef EOVERFLOW
|
||||
#define EOVERFLOW 75
|
||||
#endif
|
||||
|
||||
/** Accessing a corrupted shared library */
|
||||
#ifndef ELIBBAD
|
||||
#define ELIBBAD 80
|
||||
#endif
|
||||
|
||||
/** Destination address required */
|
||||
#ifndef EDESTADDRREQ
|
||||
#define EDESTADDRREQ 89
|
||||
#endif
|
||||
|
||||
/** Protocol not supported */
|
||||
#ifndef EPROTONOSUPPORT
|
||||
#define EPROTONOSUPPORT 93
|
||||
#endif
|
||||
|
||||
/** Operation not supported on transport endpoint */
|
||||
#ifndef ENOTSUP
|
||||
#define ENOTSUP 95
|
||||
#endif
|
||||
|
||||
/** Address family not supported by protocol */
|
||||
#ifndef EAFNOSUPPORT
|
||||
#define EAFNOSUPPORT 97
|
||||
#endif
|
||||
|
||||
/** Cannot assign requested address */
|
||||
#ifndef EADDRNOTAVAIL
|
||||
#define EADDRNOTAVAIL 99
|
||||
#endif
|
||||
|
||||
/** Software caused connection abort */
|
||||
#ifndef ECONNABORTED
|
||||
#define ECONNABORTED 103
|
||||
#endif
|
||||
|
||||
/** Connection reset by peer */
|
||||
#ifndef ECONNRESET
|
||||
#define ECONNRESET 104
|
||||
#endif
|
||||
|
||||
/** Transport endpoint is not connected */
|
||||
#ifndef ENOTCONN
|
||||
#define ENOTCONN 107
|
||||
#endif
|
||||
|
||||
/** Connection timed out */
|
||||
#ifndef ETIMEDOUT
|
||||
#define ETIMEDOUT 110
|
||||
#endif
|
||||
|
||||
/** Connection refused */
|
||||
#ifndef ECONNREFUSED
|
||||
#define ECONNREFUSED 111
|
||||
#endif
|
||||
|
||||
/** Operation already in progress */
|
||||
#ifndef EALREADY
|
||||
#define EALREADY 114
|
||||
#endif
|
||||
|
||||
/** Operation now in progress */
|
||||
#ifndef EINPROGRESS
|
||||
#define EINPROGRESS 115
|
||||
#endif
|
||||
|
||||
/** Authentication error */
|
||||
#ifndef EAUTH
|
||||
#define EAUTH 116
|
||||
#endif
|
58
include/re_udp.h
Normal file
58
include/re_udp.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* @file re_udp.h Interface to User Datagram Protocol
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
struct sa;
|
||||
struct udp_sock;
|
||||
|
||||
|
||||
/**
|
||||
* Defines the UDP Receive handler
|
||||
*
|
||||
* @param src Source address
|
||||
* @param mb Datagram buffer
|
||||
* @param arg Handler argument
|
||||
*/
|
||||
typedef void (udp_recv_h)(const struct sa *src, struct mbuf *mb, void *arg);
|
||||
|
||||
|
||||
int udp_listen(struct udp_sock **usp, const struct sa *local,
|
||||
udp_recv_h *rh, void *arg);
|
||||
void udp_connect(struct udp_sock *us, bool conn);
|
||||
int udp_send(struct udp_sock *us, const struct sa *dst, struct mbuf *mb);
|
||||
int udp_send_anon(const struct sa *dst, struct mbuf *mb);
|
||||
int udp_local_get(const struct udp_sock *us, struct sa *local);
|
||||
int udp_setsockopt(struct udp_sock *us, int level, int optname,
|
||||
const void *optval, uint32_t optlen);
|
||||
int udp_sockbuf_set(struct udp_sock *us, int size);
|
||||
void udp_rxsz_set(struct udp_sock *us, size_t rxsz);
|
||||
void udp_rxbuf_presz_set(struct udp_sock *us, size_t rx_presz);
|
||||
void udp_handler_set(struct udp_sock *us, udp_recv_h *rh, void *arg);
|
||||
int udp_thread_attach(struct udp_sock *us);
|
||||
void udp_thread_detach(struct udp_sock *us);
|
||||
int udp_sock_fd(const struct udp_sock *us, int af);
|
||||
|
||||
|
||||
/* Helper API */
|
||||
typedef bool (udp_helper_send_h)(int *err, struct sa *dst,
|
||||
struct mbuf *mb, void *arg);
|
||||
typedef bool (udp_helper_recv_h)(struct sa *src,
|
||||
struct mbuf *mb, void *arg);
|
||||
|
||||
struct udp_helper;
|
||||
|
||||
|
||||
int udp_register_helper(struct udp_helper **uhp, struct udp_sock *us,
|
||||
int *fd, int layer,
|
||||
udp_helper_send_h *sh, udp_helper_recv_h *rh,
|
||||
void *arg);
|
||||
|
||||
|
||||
#ifdef __SYMBIAN32__
|
||||
struct RConnection;
|
||||
struct RSocketServ;
|
||||
void udp_rconn_set(struct RSocketServ *sockSrv, struct RConnection *rconn);
|
||||
#endif
|
43
include/re_uri.h
Normal file
43
include/re_uri.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* @file re_uri.h Interface to URI module
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
/** Defines a URI - Uniform Resource Identifier */
|
||||
struct uri {
|
||||
struct pl scheme; /**< URI scheme e.g. "sip:" "sips:" */
|
||||
struct pl user; /**< Username */
|
||||
struct pl password; /**< Optional password */
|
||||
struct pl host; /**< Hostname or IP-address */
|
||||
int af; /**< Address family of host IP-address */
|
||||
uint16_t port; /**< Port number */
|
||||
struct pl params; /**< Optional URI-parameters */
|
||||
struct pl headers; /**< Optional URI-headers */
|
||||
};
|
||||
|
||||
typedef int (uri_apply_h)(const struct pl *name, const struct pl *val,
|
||||
void *arg);
|
||||
|
||||
struct re_printf;
|
||||
int uri_encode(struct re_printf *pf, const struct uri *uri);
|
||||
int uri_decode(struct uri *uri, const struct pl *pl);
|
||||
int uri_param_get(const struct pl *pl, const struct pl *pname,
|
||||
struct pl *pvalue);
|
||||
int uri_params_apply(const struct pl *pl, uri_apply_h *ah, void *arg);
|
||||
int uri_header_get(const struct pl *pl, const struct pl *hname,
|
||||
struct pl *hvalue);
|
||||
int uri_headers_apply(const struct pl *pl, uri_apply_h *ah, void *arg);
|
||||
bool uri_cmp(const struct uri *l, const struct uri *r);
|
||||
|
||||
|
||||
/* Special URI escaping/unescaping */
|
||||
int uri_user_escape(struct re_printf *pf, const struct pl *pl);
|
||||
int uri_user_unescape(struct re_printf *pf, const struct pl *pl);
|
||||
int uri_password_escape(struct re_printf *pf, const struct pl *pl);
|
||||
int uri_password_unescape(struct re_printf *pf, const struct pl *pl);
|
||||
int uri_param_escape(struct re_printf *pf, const struct pl *pl);
|
||||
int uri_param_unescape(struct re_printf *pf, const struct pl *pl);
|
||||
int uri_header_escape(struct re_printf *pf, const struct pl *pl);
|
||||
int uri_header_unescape(struct re_printf *pf, const struct pl *pl);
|
252
mk/Doxyfile
Normal file
252
mk/Doxyfile
Normal file
|
@ -0,0 +1,252 @@
|
|||
# Doxyfile 1.4.7
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
PROJECT_NAME = libre
|
||||
PROJECT_NUMBER = 0.1.0
|
||||
OUTPUT_DIRECTORY = ../re-dox
|
||||
CREATE_SUBDIRS = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
#USE_WINDOWS_ENCODING = NO
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ABBREVIATE_BRIEF = "The $name class" \
|
||||
"The $name widget" \
|
||||
"The $name file" \
|
||||
is \
|
||||
provides \
|
||||
specifies \
|
||||
contains \
|
||||
represents \
|
||||
a \
|
||||
an \
|
||||
the
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = NO
|
||||
STRIP_FROM_PATH =
|
||||
STRIP_FROM_INC_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
#DETAILS_AT_TOP = NO
|
||||
INHERIT_DOCS = YES
|
||||
SEPARATE_MEMBER_PAGES = NO
|
||||
TAB_SIZE = 8
|
||||
ALIASES =
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
#BUILTIN_STL_SUPPORT = NO
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
SUBGROUPING = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_STATIC = NO
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
EXTRACT_LOCAL_METHODS = NO
|
||||
HIDE_UNDOC_MEMBERS = YES
|
||||
HIDE_UNDOC_CLASSES = YES
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
SORT_BRIEF_DOCS = NO
|
||||
SORT_BY_SCOPE_NAME = NO
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_DIRECTORIES = NO
|
||||
FILE_VERSION_FILTER =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = YES
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = NO
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = include src
|
||||
FILE_PATTERNS = *.c \
|
||||
*.h \
|
||||
*.dox
|
||||
RECURSIVE = YES
|
||||
EXCLUDE = test.c \
|
||||
include/re_bitv.h \
|
||||
src/md5/md5.h src/md5/md5.c \
|
||||
src/conf include/re_conf.h \
|
||||
src/dns include/re_dns.h \
|
||||
src/httpauth include/re_httpauth.h \
|
||||
src/ice include/re_ice.h \
|
||||
src/lock include/re_lock.h \
|
||||
src/sdp include/re_sdp.h \
|
||||
src/stun include/re_stun.h \
|
||||
src/tcp include/re_tcp.h \
|
||||
src/telev include/re_telev.h \
|
||||
src/tls include/re_tls.h \
|
||||
src/turn include/re_turn.h \
|
||||
src/udp include/re_udp.h
|
||||
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS = */.svn/* *src/sip* *include/re_sip*
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS = *
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = YES
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
#REFERENCES_LINK_SOURCE = YES
|
||||
#USE_HTAGS = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = YES
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
GENERATE_HTMLHELP = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
GENERATE_TREEVIEW = NO
|
||||
TREEVIEW_WIDTH = 250
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = NO
|
||||
USE_PDFLATEX = NO
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
XML_OUTPUT = xml
|
||||
XML_SCHEMA =
|
||||
XML_DTD =
|
||||
XML_PROGRAMLISTING = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the Perl module output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = YES
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH = include
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED = HAVE_INTTYPES_H HAVE_INET6 HAVE_STDBOOL_H
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = YES
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = YES
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
GROUP_GRAPHS = YES
|
||||
UML_LOOK = NO
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
#CALL_GRAPH = YES todo: disabled to run faster
|
||||
#CALLER_GRAPH = YES
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DIRECTORY_GRAPH = YES
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
#MAX_DOT_GRAPH_WIDTH = 1024
|
||||
#MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
#MAX_DOT_GRAPH_DEPTH = 1000
|
||||
DOT_TRANSPARENT = NO
|
||||
DOT_MULTI_TARGETS = NO
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
SEARCHENGINE = NO
|
2
mk/exclude
Normal file
2
mk/exclude
Normal file
|
@ -0,0 +1,2 @@
|
|||
debian/
|
||||
rpm/
|
750
mk/re.mk
Normal file
750
mk/re.mk
Normal file
|
@ -0,0 +1,750 @@
|
|||
#
|
||||
# re.mk - common make rules
|
||||
#
|
||||
# Copyright (C) 2010 Creytiv.com
|
||||
#
|
||||
# Imported variables:
|
||||
#
|
||||
# PROJECT Project name
|
||||
# VERSION Version number
|
||||
# CC Compiler
|
||||
# GCOV If non-empty, enable GNU Coverage testing
|
||||
# GPROF If non-empty, enable GNU Profiling
|
||||
# OPT_SPEED If non-empty, optimize for speed
|
||||
# OPT_SIZE If non-empty, optimize for size
|
||||
# USE_OPENSSL If non-empty, link to libssl library
|
||||
# USE_ZLIB If non-empty, link to libz library
|
||||
# SYSROOT System root of library and include files
|
||||
# SYSROOT_ALT Alternative system root of library and include files
|
||||
# EXTRA_CFLAGS Extra compiler flags appended to CFLAGS
|
||||
# EXTRA_LFLAGS Extra linker flags appended to LFLAGS
|
||||
#
|
||||
# Exported variables:
|
||||
#
|
||||
# CC Compiler
|
||||
# CCACHE Compiler ccache tool
|
||||
# CFLAGS Compiler flags
|
||||
# DFLAGS Dependency generator flags
|
||||
# LFLAGS Common linker flags
|
||||
# SH_LFLAGS Linker flags for shared libraries
|
||||
# MOD_LFLAGS Linker flags for dynamic modules
|
||||
# APP_LFLAGS Linker flags for applications using modules
|
||||
# LIBS Libraries to link against
|
||||
# LIB_SUFFIX Suffix for shared libraries
|
||||
# MOD_SUFFIX Suffix for dynamic modules
|
||||
# BIN_SUFFIX Suffix for binary executables
|
||||
#
|
||||
|
||||
|
||||
ifneq ($(RELEASE),)
|
||||
CFLAGS += -DRELEASE
|
||||
OPT_SPEED=1
|
||||
endif
|
||||
|
||||
|
||||
# Default system root
|
||||
ifeq ($(SYSROOT),)
|
||||
SYSROOT := /usr
|
||||
endif
|
||||
|
||||
# Alternative Systemroot
|
||||
ifeq ($(SYSROOT_ALT),)
|
||||
SYSROOT_ALT := $(shell [ -d /sw/include ] && echo "/sw")
|
||||
endif
|
||||
ifeq ($(SYSROOT_ALT),)
|
||||
SYSROOT_ALT := $(shell [ -d /opt/local/include ] && echo "/opt/local")
|
||||
endif
|
||||
|
||||
ifneq ($(SYSROOT_ALT),)
|
||||
CFLAGS += -I$(SYSROOT_ALT)/include
|
||||
LFLAGS += -L$(SYSROOT_ALT)/lib
|
||||
endif
|
||||
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Compiler section
|
||||
#
|
||||
# find compiler name & version
|
||||
|
||||
ifeq ($(CC),)
|
||||
CC := gcc
|
||||
endif
|
||||
ifeq ($(CC),cc)
|
||||
CC := gcc
|
||||
endif
|
||||
LD := $(CC)
|
||||
CC_LONGVER := $(shell if $(CC) -v 2>/dev/null; then \
|
||||
$(CC) -v 2>&1 ;\
|
||||
else \
|
||||
$(CC) -V 2>&1 ; \
|
||||
fi )
|
||||
|
||||
# find-out the compiler's name
|
||||
|
||||
ifneq (,$(findstring gcc, $(CC_LONGVER)))
|
||||
CC_NAME := gcc
|
||||
CC_VER := $(word 1,$(CC)) $(shell $(CC) - --version|head -n 1|\
|
||||
cut -d" " -f 3|\
|
||||
sed -e 's/^.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/'\
|
||||
-e 's/^[^0-9].*\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/')
|
||||
# sun sed is a little brain damaged => this complicated expression
|
||||
MKDEP := $(CC) -MM
|
||||
#transform gcc version into 2.9x, 3.x or 4.x
|
||||
CC_SHORTVER := $(shell echo "$(CC_VER)" | cut -d" " -f 2| \
|
||||
sed -e 's/[^0-9]*-\(.*\)/\1/'| \
|
||||
sed -e 's/2\.9.*/2.9x/' -e 's/3\.[0-3]\..*/3.0/' -e \
|
||||
's/3\.[0-3]/3.0/' -e 's/3\.[4-9]\..*/3.4/' -e\
|
||||
's/3\.[4-9]/3.4/' -e 's/4\.[0-9]\..*/4.x/' -e\
|
||||
's/4\.[0-9]/4.x/' )
|
||||
endif
|
||||
|
||||
ifneq (, $(findstring Sun, $(CC_LONGVER)))
|
||||
CC_NAME := suncc
|
||||
CC_SHORTVER := $(shell echo "$(CC_LONGVER)"|head -n 1| \
|
||||
sed -e 's/.*\([0-9]\.[0-9]\).*/\1/g' )
|
||||
CC_VER := $(CC) $(CC_SHORTVER)
|
||||
MKDEP := $(CC) -xM1
|
||||
endif
|
||||
|
||||
ifneq (, $(findstring Intel(R) C++ Compiler, $(CC_LONGVER)))
|
||||
# very nice: gcc compatible
|
||||
CC_NAME := icc
|
||||
CC_FULLVER := $(shell echo "$(CC_LONGVER)"|head -n 1| \
|
||||
sed -e 's/.*Version \([0-9]\.[0-9]\.[0-9]*\).*/\1/g')
|
||||
CC_SHORTVER := $(shell echo "$(CC_FULLVER)" | cut -d. -f1,2 )
|
||||
CC_VER := $(CC) $(CC_FULLVER)
|
||||
MKDEP := $(CC) -MM
|
||||
endif
|
||||
|
||||
|
||||
ifeq (,$(CC_NAME))
|
||||
#not found
|
||||
CC_NAME := $(CC)
|
||||
CC_SHORTVER := unknown
|
||||
CC_VER := unknown
|
||||
MKDEP := gcc -MM
|
||||
$(warning Unknown compiler $(CC)\; supported compilers: \
|
||||
gcc, sun cc, intel icc )
|
||||
endif
|
||||
|
||||
|
||||
# Compiler warning flags
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wmissing-prototypes
|
||||
CFLAGS += -Wstrict-prototypes
|
||||
CFLAGS += -Wbad-function-cast
|
||||
CFLAGS += -Wsign-compare
|
||||
CFLAGS += -Wnested-externs
|
||||
CFLAGS += -Wshadow
|
||||
CFLAGS += -Waggregate-return
|
||||
CFLAGS += -Wcast-align
|
||||
|
||||
|
||||
ifeq ($(CC_SHORTVER),4.x)
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -Wold-style-definition
|
||||
CFLAGS += -Wdeclaration-after-statement
|
||||
endif
|
||||
|
||||
CFLAGS += -g
|
||||
ifneq ($(OPT_SPEED),)
|
||||
CFLAGS += -O3 # Optimize for speed - takes longer to compile!
|
||||
OPTIMIZE := 1
|
||||
endif
|
||||
ifneq ($(OPT_SIZE),)
|
||||
CFLAGS += -Os # Optimize for size - takes longer to compile!
|
||||
OPTIMIZE := 1
|
||||
endif
|
||||
|
||||
ifneq ($(OPTIMIZE),)
|
||||
CFLAGS += -Wuninitialized
|
||||
ifneq ($(CC_SHORTVER), 2.9x)
|
||||
CFLAGS += -Wno-strict-aliasing
|
||||
endif
|
||||
endif
|
||||
|
||||
# Compiler dependency flags
|
||||
ifeq ($(CC_SHORTVER), 2.9x)
|
||||
DFLAGS = -MD
|
||||
else
|
||||
DFLAGS = -MD -MF $(@:.o=.d) -MT $@
|
||||
endif
|
||||
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# OS section
|
||||
#
|
||||
MACHINE := $(shell $(CC) -dumpmachine)
|
||||
OS := $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")
|
||||
#ARCH := $(shell echo $(MACHINE) | sed -e 's/\([^-]*\)-.*/\1/')
|
||||
|
||||
# TODO get ARCH from first tuple in CC -dumpmachine which is more future proof
|
||||
ifeq ($(MACHINE), i386-mingw32)
|
||||
OS := win32
|
||||
ARCH := i386
|
||||
endif
|
||||
ifeq ($(MACHINE), i486-mingw32)
|
||||
OS := win32
|
||||
ARCH := i486
|
||||
endif
|
||||
ifeq ($(MACHINE), i586-mingw32msvc)
|
||||
OS := win32
|
||||
ARCH := i586
|
||||
endif
|
||||
ifeq ($(MACHINE), i686-pc-cygwin)
|
||||
OS := cygwin
|
||||
ARCH := i686
|
||||
endif
|
||||
ifeq ($(MACHINE), mipsel-linux-uclibc)
|
||||
OS := linux
|
||||
ARCH := mipsel
|
||||
endif
|
||||
ifeq ($(MACHINE), bfin-linux-uclibc)
|
||||
OS := linux
|
||||
ARCH := bfin
|
||||
endif
|
||||
ifeq ($(MACHINE), bfin-uclinux)
|
||||
OS := linux
|
||||
ARCH := bfin
|
||||
endif
|
||||
ifeq ($(MACHINE), arm-apple-darwin)
|
||||
OS := darwin
|
||||
ARCH := arm
|
||||
CROSS_COMPILE ?= $(MACHINE)-
|
||||
CFLAGS += -F/Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks
|
||||
endif
|
||||
ifeq ($(MACHINE), arm-apple-darwin9)
|
||||
OS := darwin
|
||||
ARCH := arm
|
||||
CROSS_COMPILE ?= $(MACHINE)-
|
||||
ROOT := /Developer//Platforms/iPhoneOS.platform/Developer
|
||||
SDK := $(ROOT)/SDKs/iPhoneOS3.0.sdk
|
||||
CFLAGS += -F$(SDK)/System/Library/Frameworks/
|
||||
CFLAGS += -I$(SDK)/usr/include
|
||||
CFLAGS += -I$(SDK)/usr/lib/gcc/arm-apple-darwin9/4.2.1/include
|
||||
CFLAGS += -isysroot $(SDK)
|
||||
LFLAGS += -F$(SDK)/System/Library/Frameworks
|
||||
LFLAGS += -L$(SDK)/usr/lib
|
||||
LFLAGS += -L$(SDK)/usr/lib/gcc/arm-apple-darwin9/4.2.1/
|
||||
endif
|
||||
|
||||
# default
|
||||
LIB_SUFFIX := .so
|
||||
MOD_SUFFIX := .so
|
||||
BIN_SUFFIX :=
|
||||
|
||||
ifeq ($(OS),solaris)
|
||||
CFLAGS += -fPIC -DSOLARIS
|
||||
LIBS += -ldl -lsocket -lnsl
|
||||
LFLAGS += -fPIC
|
||||
SH_LFLAGS += -G
|
||||
MOD_LFLAGS +=
|
||||
APP_LFLAGS +=
|
||||
AR := ar
|
||||
AFLAGS := cru
|
||||
endif
|
||||
ifeq ($(OS),linux)
|
||||
CFLAGS += -fPIC -DLINUX
|
||||
LIBS += -ldl
|
||||
LFLAGS += -fPIC
|
||||
SH_LFLAGS += -shared
|
||||
MOD_LFLAGS +=
|
||||
APP_LFLAGS += -rdynamic
|
||||
AR := ar
|
||||
AFLAGS := cru
|
||||
endif
|
||||
ifeq ($(OS),darwin)
|
||||
CFLAGS += -fPIC -dynamic -DDARWIN
|
||||
CFLAGS += -Wshorten-64-to-32
|
||||
DFLAGS := -MD
|
||||
LFLAGS += -fPIC
|
||||
SH_LFLAGS += -dynamiclib -dylib
|
||||
ifneq ($(VERSION),)
|
||||
SH_LFLAGS += -current_version $(VERSION)
|
||||
SH_LFLAGS += -compatibility_version $(VERSION)
|
||||
endif
|
||||
MOD_LFLAGS += -undefined dynamic_lookup
|
||||
APP_LFLAGS +=
|
||||
AR := ar
|
||||
AFLAGS := cru
|
||||
LIB_SUFFIX := .dylib
|
||||
ARCH := $(shell echo $(MACHINE) | \
|
||||
sed -e 's/\([^-]*\)-.*/\1/')
|
||||
endif
|
||||
ifeq ($(OS),netbsd)
|
||||
CFLAGS += -fPIC -DNETBSD
|
||||
LFLAGS += -fPIC
|
||||
SH_LFLAGS += -shared
|
||||
MOD_LFLAGS +=
|
||||
APP_LFLAGS += -rdynamic
|
||||
AR := ar
|
||||
AFLAGS := cru
|
||||
endif
|
||||
ifeq ($(OS),freebsd)
|
||||
CFLAGS += -fPIC -DFREEBSD
|
||||
LFLAGS += -fPIC
|
||||
SH_LFLAGS += -shared
|
||||
MOD_LFLAGS +=
|
||||
APP_LFLAGS += -rdynamic
|
||||
AR := ar
|
||||
AFLAGS := cru
|
||||
endif
|
||||
ifeq ($(OS),openbsd)
|
||||
CFLAGS += -fPIC -DOPENBSD
|
||||
LFLAGS += -fPIC
|
||||
SH_LFLAGS += -shared
|
||||
MOD_LFLAGS +=
|
||||
APP_LFLAGS += -rdynamic
|
||||
AR := ar
|
||||
AFLAGS := cru
|
||||
endif
|
||||
ifeq ($(OS),win32)
|
||||
CFLAGS += -DWIN32 -D_WIN32_WINNT=0x0501
|
||||
LIBS += -lwsock32 -lws2_32 -liphlpapi
|
||||
LFLAGS +=
|
||||
SH_LFLAGS += -shared
|
||||
MOD_LFLAGS +=
|
||||
APP_LFLAGS += -Wl,-E
|
||||
AR := ar
|
||||
AFLAGS := cru
|
||||
CROSS_COMPILE := $(MACHINE)-
|
||||
RANLIB := $(CROSS_COMPILE)ranlib
|
||||
LIB_SUFFIX := .dll
|
||||
MOD_SUFFIX := .dll
|
||||
BIN_SUFFIX := .exe
|
||||
SYSROOT := /usr/$(MACHINE)/
|
||||
endif
|
||||
ifeq ($(OS),cygwin)
|
||||
CFLAGS += -DCYGWIN -D_WIN32_WINNT=0x0501
|
||||
LIBS += -lwsock32 -lws2_32
|
||||
LFLAGS +=
|
||||
SH_LFLAGS += -shared
|
||||
MOD_LFLAGS +=
|
||||
APP_LFLAGS += -Wl,-E
|
||||
AR := ar
|
||||
AFLAGS := cru
|
||||
endif
|
||||
|
||||
CFLAGS += -DOS=\"$(OS)\"
|
||||
|
||||
ifeq ($(CC_SHORTVER),2.9x)
|
||||
CFLAGS += -Wno-long-long
|
||||
else
|
||||
CFLAGS += -std=c99
|
||||
PEDANTIC := 1
|
||||
endif # CC_SHORTVER
|
||||
|
||||
ifneq ($(PEDANTIC),)
|
||||
CFLAGS += -pedantic
|
||||
endif
|
||||
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Architecture section
|
||||
#
|
||||
|
||||
ifeq ($(OS),solaris)
|
||||
GETARCH=uname -p
|
||||
else
|
||||
GETARCH=uname -m
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),)
|
||||
ARCH := $(shell $(GETARCH) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
|
||||
-e s/armv4l/arm/ -e "s/Power Macintosh/ppc/" \
|
||||
-e "s/cobalt/mips2/" \
|
||||
-e s/amd64/x86_64/ )
|
||||
endif
|
||||
# fix sparc -> sparc64
|
||||
ifeq ($(ARCH),sparc)
|
||||
ifeq ($(shell uname -m),sun4u)
|
||||
ARCH := sparc64
|
||||
endif
|
||||
endif
|
||||
|
||||
CFLAGS += -DARCH=\"$(ARCH)\"
|
||||
|
||||
ifeq ($(ARCH),mipsel)
|
||||
CFLAGS += -march=mips32
|
||||
endif
|
||||
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# External libraries section
|
||||
#
|
||||
|
||||
USE_OPENSSL := $(shell [ -f $(SYSROOT)/include/openssl/ssl.h ] || \
|
||||
[ -f $(SYSROOT_ALT)/include/openssl/ssl.h ] && echo "yes")
|
||||
USE_ZLIB := $(shell [ -f $(SYSROOT)/include/zlib.h ] || \
|
||||
[ -f $(SYSROOT_ALT)/include/zlib.h ] && echo "yes")
|
||||
|
||||
ifneq ($(USE_OPENSSL),)
|
||||
CFLAGS += -DUSE_OPENSSL -DUSE_TLS
|
||||
LIBS += -lssl -lcrypto
|
||||
USE_TLS := yes
|
||||
endif
|
||||
ifneq ($(USE_ZLIB),)
|
||||
CFLAGS += -DUSE_ZLIB
|
||||
LIBS += -lz
|
||||
endif
|
||||
|
||||
|
||||
ifneq ($(OS),win32)
|
||||
|
||||
HAVE_PTHREAD := $(shell [ -f $(SYSROOT)/include/pthread.h ] && echo "1")
|
||||
ifneq ($(HAVE_PTHREAD),)
|
||||
HAVE_PTHREAD_RWLOCK := 1
|
||||
CFLAGS += -DHAVE_PTHREAD
|
||||
HAVE_LIBPTHREAD := 1
|
||||
ifneq ($(HAVE_LIBPTHREAD),)
|
||||
LIBS += -lpthread
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(ARCH),mipsel)
|
||||
HAVE_GETIFADDRS := $(shell [ -f $(SYSROOT)/include/ifaddrs.h ] && echo "1")
|
||||
ifneq ($(HAVE_GETIFADDRS),)
|
||||
CFLAGS += -DHAVE_GETIFADDRS
|
||||
endif
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
HAVE_GETOPT := $(shell [ -f $(SYSROOT)/include/getopt.h ] && echo "1")
|
||||
ifneq ($(HAVE_GETOPT),)
|
||||
CFLAGS += -DHAVE_GETOPT
|
||||
endif
|
||||
HAVE_INTTYPES_H := $(shell [ -f $(SYSROOT)/include/inttypes.h ] && echo "1")
|
||||
ifneq ($(HAVE_INTTYPES_H),)
|
||||
CFLAGS += -DHAVE_INTTYPES_H
|
||||
endif
|
||||
HAVE_NET_ROUTE_H := $(shell [ -f $(SYSROOT)/include/net/route.h ] && echo "1")
|
||||
ifneq ($(HAVE_NET_ROUTE_H),)
|
||||
CFLAGS += -DHAVE_NET_ROUTE_H
|
||||
endif
|
||||
HAVE_SYS_SYSCTL_H := \
|
||||
$(shell [ -f $(SYSROOT)/include/sys/sysctl.h ] && echo "1")
|
||||
ifneq ($(HAVE_SYS_SYSCTL_H),)
|
||||
CFLAGS += -DHAVE_SYS_SYSCTL_H
|
||||
endif
|
||||
|
||||
CFLAGS += -DHAVE_STDBOOL_H
|
||||
|
||||
HAVE_INET6 := 1
|
||||
ifneq ($(HAVE_INET6),)
|
||||
CFLAGS += -DHAVE_INET6
|
||||
endif
|
||||
|
||||
ifeq ($(OS),win32)
|
||||
CFLAGS += -DHAVE_SELECT
|
||||
CFLAGS += -DHAVE_IO_H
|
||||
else
|
||||
HAVE_SYSLOG := $(shell [ -f $(SYSROOT)/include/syslog.h ] && echo "1")
|
||||
HAVE_DLFCN_H := $(shell [ -f $(SYSROOT)/include/dlfcn.h ] && echo "1")
|
||||
ifneq ($(OS),darwin)
|
||||
HAVE_EPOLL := $(shell [ -f $(SYSROOT)/include/sys/epoll.h ] && echo "1")
|
||||
endif
|
||||
HAVE_LIBRESOLV := $(shell [ -f $(SYSROOT)/include/resolv.h ] && echo "1")
|
||||
|
||||
ifneq ($(HAVE_LIBRESOLV),)
|
||||
CFLAGS += -DHAVE_LIBRESOLV
|
||||
ifneq ($(OS),freebsd)
|
||||
LIBS += -lresolv
|
||||
endif
|
||||
endif
|
||||
ifneq ($(HAVE_SYSLOG),)
|
||||
CFLAGS += -DHAVE_SYSLOG
|
||||
endif
|
||||
|
||||
CFLAGS += -DHAVE_FORK
|
||||
CFLAGS += -DHAVE_INET_NTOP
|
||||
CFLAGS += -DHAVE_PWD_H
|
||||
ifneq ($(OS),darwin)
|
||||
CFLAGS += -DHAVE_POLL # Darwin: poll() does not support devices
|
||||
CFLAGS += -DHAVE_INET_PTON
|
||||
endif
|
||||
CFLAGS += -DHAVE_SELECT -DHAVE_SELECT_H
|
||||
CFLAGS += -DHAVE_SETRLIMIT
|
||||
CFLAGS += -DHAVE_SIGNAL
|
||||
CFLAGS += -DHAVE_SYS_TIME_H
|
||||
ifneq ($(HAVE_EPOLL),)
|
||||
CFLAGS += -DHAVE_EPOLL
|
||||
endif
|
||||
CFLAGS += -DHAVE_UNAME
|
||||
CFLAGS += -DHAVE_UNISTD_H
|
||||
ifneq ($(OS),cygwin)
|
||||
CFLAGS += -DHAVE_STRINGS_H
|
||||
CFLAGS += -DHAVE_GAI_STRERROR
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Misc tools section
|
||||
#
|
||||
CCACHE := $(shell [ -e /usr/bin/ccache ] 2>/dev/null \
|
||||
|| [ -e /opt/local/bin/ccache ] \
|
||||
&& echo "ccache")
|
||||
CFLAGS += -DVERSION=\"$(VERSION)\"
|
||||
|
||||
# Enable gcov Coverage testing
|
||||
#
|
||||
# - generated during build: .gcno files
|
||||
# - generated during exec: .gcda files
|
||||
#
|
||||
ifneq ($(GCOV),)
|
||||
CFLAGS += -fprofile-arcs -ftest-coverage
|
||||
LFLAGS += -fprofile-arcs -ftest-coverage
|
||||
# Disable ccache
|
||||
CCACHE :=
|
||||
endif
|
||||
|
||||
# gprof - GNU Profiling
|
||||
#
|
||||
# - generated during exec: gmon.out
|
||||
#
|
||||
ifneq ($(GPROF),)
|
||||
CFLAGS += -pg
|
||||
LFLAGS += -pg
|
||||
# Disable ccache
|
||||
CCACHE :=
|
||||
endif
|
||||
|
||||
CC := $(CCACHE) $(CC)
|
||||
CFLAGS += $(EXTRA_CFLAGS)
|
||||
LFLAGS += $(EXTRA_LFLAGS)
|
||||
|
||||
BUILD := build-$(ARCH)
|
||||
|
||||
|
||||
default: all
|
||||
|
||||
.PHONY: distclean
|
||||
distclean:
|
||||
@rm -rf build* *core*
|
||||
@rm -f *stamp $(BIN)
|
||||
@rm -f `find . -name "*.[oda]"` `find . -name "*.so"`
|
||||
@rm -f `find . -name "*~"` `find . -name "\.\#*"`
|
||||
@rm -f `find . -name "*.orig"` `find . -name "*.rej"`
|
||||
@rm -f `find . -name "*.previous"` `find . -name "*.gcov"`
|
||||
@rm -f `find . -name "*.exe"` `find . -name "*.dll"`
|
||||
@rm -f `find . -name "*.dylib"`
|
||||
|
||||
.PHONY: info
|
||||
info:
|
||||
@echo "info - $(PROJECT) version $(VERSION)"
|
||||
@echo " MODULES: $(MODULES)"
|
||||
# @echo " SRCS: $(SRCS)"
|
||||
@echo " MACHINE: $(MACHINE)"
|
||||
@echo " ARCH: $(ARCH)"
|
||||
@echo " OS: $(OS)"
|
||||
@echo " BUILD: $(BUILD)"
|
||||
@echo " CCACHE: $(CCACHE)"
|
||||
@echo " CC: $(CC_NAME) $(CC_SHORTVER)"
|
||||
@echo " CFLAGS: $(CFLAGS)"
|
||||
@echo " DFLAGS: $(DFLAGS)"
|
||||
@echo " LFLAGS: $(LFLAGS)"
|
||||
@echo " SH_LFLAGS: $(SH_LFLAGS)"
|
||||
@echo " MOD_LFLAGS: $(MOD_LFLAGS)"
|
||||
@echo " APP_LFLAGS: $(APP_LFLAGS)"
|
||||
@echo " LIBS: $(LIBS)"
|
||||
@echo " LIBRE_MK: $(LIBRE_MK)"
|
||||
@echo " LIBRE_INC: $(LIBRE_INC)"
|
||||
@echo " LIBRE_SO: $(LIBRE_SO)"
|
||||
@echo " USE_OPENSSL: $(USE_OPENSSL)"
|
||||
@echo " USE_ZLIB: $(USE_ZLIB)"
|
||||
@echo " GCOV: $(GCOV)"
|
||||
@echo " GPROF: $(GPROF)"
|
||||
@echo " CROSS_COMPILE: $(CROSS_COMPILE)"
|
||||
@echo " SYSROOT: $(SYSROOT)"
|
||||
@echo " SYSROOT_ALT: $(SYSROOT_ALT)"
|
||||
@echo " LIB_SUFFIX: $(LIB_SUFFIX)"
|
||||
@echo " MOD_SUFFIX: $(MOD_SUFFIX)"
|
||||
@echo " BIN_SUFFIX: $(BIN_SUFFIX)"
|
||||
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Packaging section
|
||||
#
|
||||
TAR_SRC := $(PROJECT)-$(VERSION)
|
||||
|
||||
release:
|
||||
@rm -rf ../$(TAR_SRC)
|
||||
@svn export . ../$(TAR_SRC)
|
||||
@if [ -f ../$(TAR_SRC)/mk/exclude ]; then \
|
||||
cat ../$(TAR_SRC)/mk/exclude \
|
||||
| sed 's|^|../$(TAR_SRC)/|' | xargs -t rm -rf ; \
|
||||
rm -f ../$(TAR_SRC)/mk/exclude ; \
|
||||
fi
|
||||
@cd .. && rm -f $(TAR_SRC).tar.gz \
|
||||
&& tar -zcf $(TAR_SRC).tar.gz $(TAR_SRC) \
|
||||
&& echo "created release tarball `pwd`/$(TAR_SRC).tar.gz"
|
||||
|
||||
tar:
|
||||
@rm -rf ../$(TAR_SRC)
|
||||
@svn export . ../$(TAR_SRC)
|
||||
@cd .. && rm -f $(TAR_SRC).tar.gz \
|
||||
&& tar -zcf $(TAR_SRC).tar.gz $(TAR_SRC) \
|
||||
&& echo "created source tarball `pwd`/$(TAR_SRC).tar.gz"
|
||||
|
||||
|
||||
# Debian
|
||||
.PHONY: deb
|
||||
deb:
|
||||
dpkg-buildpackage -rfakeroot
|
||||
|
||||
# RPM
|
||||
RPM := $(shell [ -d /usr/src/rpm ] 2>/dev/null && echo "rpm")
|
||||
ifeq ($(RPM),)
|
||||
RPM := $(shell [ -d /usr/src/redhat ] 2>/dev/null && echo "redhat")
|
||||
endif
|
||||
.PHONY: rpm
|
||||
rpm: tar
|
||||
sudo cp ../$(PROJECT)-$(VERSION).tar.gz /usr/src/$(RPM)/SOURCES
|
||||
sudo rpmbuild -ba rpm/$(PROJECT).spec
|
||||
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Library and header files location section - in prioritised order
|
||||
#
|
||||
# - relative path
|
||||
# - local installation
|
||||
# - system installation
|
||||
#
|
||||
|
||||
# Include path
|
||||
LIBRE_INC := $(shell [ -f ../re/include/re.h ] && echo "../re/include")
|
||||
ifeq ($(LIBRE_INC),)
|
||||
LIBRE_INC := $(shell [ -f /usr/local/include/re/re.h ] && \
|
||||
echo "/usr/local/include/re")
|
||||
endif
|
||||
ifeq ($(LIBRE_INC),)
|
||||
LIBRE_INC := $(shell [ -f /usr/include/re/re.h ] && echo "/usr/include/re")
|
||||
endif
|
||||
|
||||
# Library path
|
||||
LIBRE_SO := $(shell [ -f ../re/libre$(LIB_SUFFIX) ] && echo "../re")
|
||||
ifeq ($(LIBRE_SO),)
|
||||
LIBRE_SO := $(shell [ -f /usr/local/lib/libre$(LIB_SUFFIX) ] \
|
||||
&& echo "/usr/local/lib")
|
||||
endif
|
||||
ifeq ($(LIBRE_SO),)
|
||||
LIBRE_SO := $(shell [ -f /usr/lib/libre$(LIB_SUFFIX) ] && echo "/usr/lib")
|
||||
endif
|
||||
ifeq ($(LIBRE_SO),)
|
||||
LIBRE_SO := $(shell [ -f /usr/lib64/libre$(LIB_SUFFIX) ] && echo "/usr/lib64")
|
||||
endif
|
||||
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Splint section
|
||||
#
|
||||
|
||||
SPLINT_OPTIONS += +unixlib
|
||||
SPLINT_OPTIONS += +skipsysheaders
|
||||
SPLINT_OPTIONS += -noeffect # Statement has no effect: (void)reg
|
||||
SPLINT_OPTIONS += -compdef # Passed storage buf not completely..
|
||||
SPLINT_OPTIONS += -mustfreefresh # Fresh storage st not released before
|
||||
SPLINT_OPTIONS += -nullret # Null storage returned as non-null
|
||||
SPLINT_OPTIONS += -compmempass
|
||||
SPLINT_OPTIONS += -observertrans # Observer storage returned without..
|
||||
SPLINT_OPTIONS += -fixedformalarray # e.g. param: int linesize[4]
|
||||
SPLINT_OPTIONS += +voidabstract
|
||||
|
||||
# these options can be tuned:
|
||||
SPLINT_OPTIONS += -mayaliasunique # Parameter 1 (ua->stat.rphrase)
|
||||
SPLINT_OPTIONS += -boolops # Left operand of && is non-boolean
|
||||
SPLINT_OPTIONS += -nullpass # Possibly null storage resp passed..
|
||||
SPLINT_OPTIONS += -type
|
||||
SPLINT_OPTIONS += -mustfreeonly # Implicitly only storage ua->callt..
|
||||
SPLINT_OPTIONS += -nullassign
|
||||
SPLINT_OPTIONS += -unrecog # Unrecognized identifier: strdup
|
||||
SPLINT_OPTIONS += -unqualifiedtrans # Unqualified storage ua->lhost assign
|
||||
SPLINT_OPTIONS += -temptrans # Implicitly temp storage assigned to
|
||||
SPLINT_OPTIONS += -usereleased
|
||||
SPLINT_OPTIONS += -predboolint
|
||||
SPLINT_OPTIONS += -statictrans
|
||||
SPLINT_OPTIONS += -globstate # Function returns with global..
|
||||
SPLINT_OPTIONS += -compdestroy # Only storage call->conf derived
|
||||
SPLINT_OPTIONS += -onlytrans # Only storage alias->mb assigned
|
||||
SPLINT_OPTIONS += -shiftimplementation
|
||||
SPLINT_OPTIONS += -shiftnegative
|
||||
SPLINT_OPTIONS += -predboolothers
|
||||
SPLINT_OPTIONS += -nullstate # Null storage ct->timer_a derivable..
|
||||
SPLINT_OPTIONS += -redef # Enum member T1 defined more than once
|
||||
SPLINT_OPTIONS += -usedef # Variable tv used before definition
|
||||
SPLINT_OPTIONS += -dependenttrans # Dependent storage m returned as..
|
||||
SPLINT_OPTIONS += -immediatetrans # Immediate address &xyz returned
|
||||
SPLINT_OPTIONS += -branchstate # Storage is released in one path
|
||||
SPLINT_OPTIONS += -kepttrans # Kept storage le assigned to implic..
|
||||
SPLINT_OPTIONS += -incondefs
|
||||
SPLINT_OPTIONS += -exportlocal
|
||||
SPLINT_OPTIONS += -nullderef
|
||||
SPLINT_OPTIONS += -fullinitblock # problem in main/main.c init block
|
||||
SPLINT_OPTIONS += -evalorder # problem with e.g. foo(rand(), rand())
|
||||
SPLINT_OPTIONS += -uniondef # union in struct sa
|
||||
SPLINT_OPTIONS += -realcompare # tping: comp double types rtt < 0
|
||||
SPLINT_OPTIONS += -fcnuse
|
||||
SPLINT_OPTIONS += -retvalother # Return value ignored (not int)
|
||||
SPLINT_OPTIONS += -Iinclude -I$(LIBRE_INC)
|
||||
SPLINT_OPTIONS += -DHAVE_GETOPT -DHAVE_POLL -DHAVE_STDBOOL_H
|
||||
SPLINT_OPTIONS += -DHAVE_INET_NTOP -DHAVE_INET_PTON -DHAVE_INET6
|
||||
|
||||
# ignore these files for now
|
||||
SPLINT_IGNORE := src/tls/openssl/tls.c src/tls/openssl/tls_tcp.c
|
||||
SPLINT_IGNORE += src/dns/darwin/srv.c
|
||||
|
||||
SPLINT_SOURCES += $(filter-out $(SPLINT_IGNORE), $(patsubst %,src/%,$(SRCS)))
|
||||
|
||||
|
||||
splint-sources:
|
||||
@echo $(SPLINT_SOURCES)
|
||||
|
||||
splint-all:
|
||||
@splint $(SPLINT_LIBS) $(SPLINT_OPTIONS) $(SPLINT_SOURCES)
|
||||
|
||||
splint:
|
||||
@for n in $(SPLINT_SOURCES); do \
|
||||
splint $(SPLINT_LIBS) $(SPLINT_OPTIONS) $${n} 2>/dev/null ; \
|
||||
done
|
||||
|
||||
splint-verbose:
|
||||
@for n in $(SPLINT_SOURCES); do \
|
||||
echo "running splint on $${n}"; \
|
||||
splint $(SPLINT_LIBS) $(SPLINT_OPTIONS) $${n} ; \
|
||||
done
|
||||
|
||||
splint-test:
|
||||
@splint $(SPLINT_LIBS) $(SPLINT_OPTIONS) test.c
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Documentation section
|
||||
#
|
||||
DOX_DIR=../$(PROJECT)-dox
|
||||
DOX_TAR=$(PROJECT)-dox-$(VERSION)
|
||||
|
||||
$(DOX_DIR):
|
||||
@mkdir $@
|
||||
|
||||
$(DOX_DIR)/Doxyfile: mk/Doxyfile Makefile
|
||||
@cp $< $@
|
||||
@perl -pi -e 's/PROJECT_NUMBER\s*=.*/PROJECT_NUMBER = $(VERSION)/' \
|
||||
$(DOX_DIR)/Doxyfile
|
||||
|
||||
.PHONY:
|
||||
dox: $(DOX_DIR) $(DOX_DIR)/Doxyfile
|
||||
@doxygen $(DOX_DIR)/Doxyfile 2>&1 | grep -v DEBUG_ ; true
|
||||
@cd .. && rm -f $(DOX_TAR).tar.gz && \
|
||||
tar -zcf $(DOX_TAR).tar.gz $(PROJECT)-dox > /dev/null && \
|
||||
echo "Doxygen docs in `pwd`/$(DOX_TAR).tar.gz"
|
59
mk/symbian/bld.inf
Normal file
59
mk/symbian/bld.inf
Normal file
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* @file bld.inf Symbian build information
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
PRJ_EXPORTS
|
||||
|
||||
..\..\include\re.h \epoc32\include\re\re.h
|
||||
..\..\include\re_base64.h \epoc32\include\re\re_base64.h
|
||||
..\..\include\re_bitv.h \epoc32\include\re\re_bitv.h
|
||||
..\..\include\re_conf.h \epoc32\include\re\re_conf.h
|
||||
..\..\include\re_crc32.h \epoc32\include\re\re_crc32.h
|
||||
..\..\include\re_dbg.h \epoc32\include\re\re_dbg.h
|
||||
..\..\include\re_dns.h \epoc32\include\re\re_dns.h
|
||||
..\..\include\re_fmt.h \epoc32\include\re\re_fmt.h
|
||||
..\..\include\re_g711.h \epoc32\include\re\re_g711.h
|
||||
..\..\include\re_hash.h \epoc32\include\re\re_hash.h
|
||||
..\..\include\re_hmac.h \epoc32\include\re\re_hmac.h
|
||||
..\..\include\re_httpauth.h \epoc32\include\re\re_httpauth.h
|
||||
..\..\include\re_ice.h \epoc32\include\re\re_ice.h
|
||||
..\..\include\re_jbuf.h \epoc32\include\re\re_jbuf.h
|
||||
..\..\include\re_list.h \epoc32\include\re\re_list.h
|
||||
..\..\include\re_lock.h \epoc32\include\re\re_lock.h
|
||||
..\..\include\re_main.h \epoc32\include\re\re_main.h
|
||||
..\..\include\re_mbuf.h \epoc32\include\re\re_mbuf.h
|
||||
..\..\include\re_md5.h \epoc32\include\re\re_md5.h
|
||||
..\..\include\re_mem.h \epoc32\include\re\re_mem.h
|
||||
..\..\include\re_mod.h \epoc32\include\re\re_mod.h
|
||||
..\..\include\re_mqueue.h \epoc32\include\re\re_mqueue.h
|
||||
..\..\include\re_natbd.h \epoc32\include\re\re_natbd.h
|
||||
..\..\include\re_net.h \epoc32\include\re\re_net.h
|
||||
..\..\include\re_rtp.h \epoc32\include\re\re_rtp.h
|
||||
..\..\include\re_sa.h \epoc32\include\re\re_sa.h
|
||||
..\..\include\re_sdp.h \epoc32\include\re\re_sdp.h
|
||||
..\..\include\re_sha.h \epoc32\include\re\re_sha.h
|
||||
..\..\include\re_sip.h \epoc32\include\re\re_sip.h
|
||||
..\..\include\re_sipreg.h \epoc32\include\re\re_sipreg.h
|
||||
..\..\include\re_sipsess.h \epoc32\include\re\re_sipsess.h
|
||||
..\..\include\re_stun.h \epoc32\include\re\re_stun.h
|
||||
..\..\include\re_sys.h \epoc32\include\re\re_sys.h
|
||||
..\..\include\re_tcp.h \epoc32\include\re\re_tcp.h
|
||||
..\..\include\re_telev.h \epoc32\include\re\re_telev.h
|
||||
..\..\include\re_tls.h \epoc32\include\re\re_tls.h
|
||||
..\..\include\re_tmr.h \epoc32\include\re\re_tmr.h
|
||||
..\..\include\re_turn.h \epoc32\include\re\re_turn.h
|
||||
..\..\include\re_types.h \epoc32\include\re\re_types.h
|
||||
..\..\include\re_udp.h \epoc32\include\re\re_udp.h
|
||||
..\..\include\re_uri.h \epoc32\include\re\re_uri.h
|
||||
|
||||
|
||||
PRJ_MMPFILES
|
||||
|
||||
re.mmp
|
||||
redns.mmp
|
||||
resdp.mmp
|
||||
resip.mmp
|
||||
resipsess.mmp
|
||||
restun.mmp
|
10
mk/symbian/dll.cpp
Normal file
10
mk/symbian/dll.cpp
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include <e32def.h>
|
||||
#include <e32std.h>
|
||||
|
||||
|
||||
#ifndef EKA2
|
||||
GLDEF_C TInt E32Dll(TDllReason /*aReason*/)
|
||||
{
|
||||
return KErrNone;
|
||||
}
|
||||
#endif
|
31
mk/symbian/ecrt.cpp
Normal file
31
mk/symbian/ecrt.cpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* @file ecrt.cpp ECRT wrapper for Symbian OS
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <e32base.h>
|
||||
#include <e32cons.h>
|
||||
#include <sys/reent.h>
|
||||
|
||||
_LIT(KAppName, "retest");
|
||||
extern "C" int main(int argc, char** argv);
|
||||
|
||||
|
||||
TInt E32Main()
|
||||
{
|
||||
__UHEAP_MARK;
|
||||
CTrapCleanup* cleanup = CTrapCleanup::New();
|
||||
int ret = 0;
|
||||
TRAPD(err, ret = main(0, NULL));
|
||||
if (err)
|
||||
printf("main left with error %d\n", err);
|
||||
if (ret)
|
||||
printf("main returned %d\n", ret);
|
||||
__ASSERT_ALWAYS(!err, User::Panic(KAppName, err));
|
||||
CloseSTDLIB();
|
||||
delete cleanup;
|
||||
__UHEAP_MARKEND;
|
||||
return err;
|
||||
}
|
154
mk/symbian/re.mmp
Normal file
154
mk/symbian/re.mmp
Normal file
|
@ -0,0 +1,154 @@
|
|||
/**
|
||||
* @file re.mmp Symbian makefile for libre
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
TARGET re.lib
|
||||
TARGETTYPE lib
|
||||
TARGETPATH system\libs
|
||||
UID 0x10000fd3 0x200112fa
|
||||
|
||||
#ifdef EKA2
|
||||
VENDORID 0
|
||||
CAPABILITY NetworkServices
|
||||
#endif
|
||||
|
||||
MACRO HAVE_SYS_TIME_H
|
||||
MACRO HAVE_UNISTD_H
|
||||
MACRO HAVE_ACTSCHED
|
||||
|
||||
#ifndef EKA2
|
||||
SOURCEPATH .
|
||||
SOURCE dll.cpp
|
||||
#endif
|
||||
|
||||
SOURCEPATH ..\..\src\base64
|
||||
SOURCE b64.c
|
||||
|
||||
SOURCEPATH ..\..\src\conf
|
||||
SOURCE conf.c
|
||||
|
||||
SOURCEPATH ..\..\src\crc32
|
||||
SOURCE crc32.c
|
||||
|
||||
SOURCEPATH ..\..\src\dbg
|
||||
SOURCE dbg.c
|
||||
|
||||
SOURCEPATH ..\..\src\fmt
|
||||
SOURCE ch.c
|
||||
SOURCE hexdump.c
|
||||
SOURCE pl.c
|
||||
SOURCE print.c
|
||||
SOURCE prm.c
|
||||
SOURCE regex.c
|
||||
SOURCE str.c
|
||||
SOURCE time.c
|
||||
|
||||
SOURCEPATH ..\..\src\g711
|
||||
SOURCE g711.c
|
||||
|
||||
SOURCEPATH ..\..\src\hash
|
||||
SOURCE hash.c
|
||||
SOURCE func.c
|
||||
|
||||
SOURCEPATH ..\..\src\hmac
|
||||
SOURCE hmac_sha1.c
|
||||
|
||||
SOURCEPATH ..\..\src\httpauth
|
||||
SOURCE basic.c
|
||||
SOURCE digest.c
|
||||
|
||||
SOURCEPATH ..\..\src\jbuf
|
||||
SOURCE jbuf.c
|
||||
|
||||
SOURCEPATH ..\..\src\list
|
||||
SOURCE list.c
|
||||
|
||||
SOURCEPATH ..\..\src\lock
|
||||
SOURCE symbian\rmutex.cpp
|
||||
|
||||
SOURCEPATH ..\..\src\main
|
||||
SOURCE init.c
|
||||
SOURCE main.c
|
||||
SOURCE method.c
|
||||
SOURCE symbian\actsched.cpp
|
||||
|
||||
SOURCEPATH ..\..\src\mbuf
|
||||
SOURCE mbuf.c
|
||||
|
||||
SOURCEPATH ..\..\src\md5
|
||||
SOURCE md5.c
|
||||
SOURCE wrap.c
|
||||
|
||||
SOURCEPATH ..\..\src\mem
|
||||
SOURCE mem.c
|
||||
|
||||
SOURCEPATH ..\..\src\mod
|
||||
SOURCE mod.c
|
||||
SOURCE symbian\rlib.cpp
|
||||
|
||||
SOURCEPATH ..\..\src\net
|
||||
SOURCE sock.c
|
||||
SOURCE netstr.c
|
||||
SOURCE if.c
|
||||
SOURCE rt.c
|
||||
SOURCE net.c
|
||||
SOURCE symbian\sif.cpp
|
||||
SOURCE symbian\snet.cpp
|
||||
SOURCE symbian\srt.cpp
|
||||
SOURCE symbian\rconn.cpp
|
||||
|
||||
SOURCEPATH ..\..\src\rtp
|
||||
SOURCE fb.c
|
||||
SOURCE member.c
|
||||
SOURCE ntp.c
|
||||
SOURCE pkt.c
|
||||
SOURCE rr.c
|
||||
SOURCE rtcp.c
|
||||
SOURCE rtp.c
|
||||
SOURCE sdes.c
|
||||
SOURCE sess.c
|
||||
SOURCE source.c
|
||||
|
||||
SOURCEPATH ..\..\src\sa
|
||||
SOURCE ntop.c
|
||||
SOURCE pton.c
|
||||
SOURCE sa.c
|
||||
|
||||
SOURCEPATH ..\..\src\sha
|
||||
SOURCE sha1.c
|
||||
|
||||
SOURCEPATH ..\..\src\sys
|
||||
SOURCE daemon.c
|
||||
SOURCE endian.c
|
||||
SOURCE rand.c
|
||||
SOURCE sys.c
|
||||
|
||||
SOURCEPATH ..\..\src\telev
|
||||
SOURCE telev.c
|
||||
|
||||
SOURCEPATH ..\..\src\tmr
|
||||
SOURCE tmr.c
|
||||
|
||||
SOURCEPATH ..\..\src\udp
|
||||
SOURCE symbian\udp.cpp
|
||||
|
||||
SOURCEPATH ..\..\src\tcp
|
||||
SOURCE tcp_high.c
|
||||
SOURCE symbian\tcp.cpp
|
||||
|
||||
SOURCEPATH ..\..\src\uri
|
||||
SOURCE ucmp.c
|
||||
SOURCE uri.c
|
||||
SOURCE uric.c
|
||||
|
||||
USERINCLUDE . ..\..\include
|
||||
SYSTEMINCLUDE \epoc32\include
|
||||
SYSTEMINCLUDE \epoc32\include\libc
|
||||
SYSTEMINCLUDE ..\..\include
|
||||
#ifndef EKA2
|
||||
LIBRARY estlib.lib euser.lib
|
||||
LIBRARY esock.lib insock.lib
|
||||
#endif
|
||||
|
||||
EXPORTUNFROZEN
|
38
mk/symbian/redns.mmp
Normal file
38
mk/symbian/redns.mmp
Normal file
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* @file redns.mmp Symbian makefile for libre DNS
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
TARGET redns.lib
|
||||
TARGETTYPE lib
|
||||
TARGETPATH system\libs
|
||||
UID 0x10000fd3 0x20011309
|
||||
|
||||
#ifdef EKA2
|
||||
VENDORID 0
|
||||
CAPABILITY NetworkServices
|
||||
#endif
|
||||
|
||||
SOURCEPATH .
|
||||
SOURCE dll.cpp
|
||||
|
||||
SOURCEPATH ..\..\src\dns
|
||||
SOURCE client.c
|
||||
SOURCE cstr.c
|
||||
SOURCE dname.c
|
||||
SOURCE hdr.c
|
||||
SOURCE ns.c
|
||||
SOURCE rr.c
|
||||
SOURCE rrlist.c
|
||||
SOURCE symbian\srv.cpp
|
||||
|
||||
USERINCLUDE .
|
||||
SYSTEMINCLUDE \epoc32\include
|
||||
SYSTEMINCLUDE \epoc32\include\libc
|
||||
SYSTEMINCLUDE ..\..\include
|
||||
#ifndef EKA2
|
||||
LIBRARY estlib.lib euser.lib
|
||||
LIBRARY esock.lib insock.lib
|
||||
#endif
|
||||
|
||||
EXPORTUNFROZEN
|
36
mk/symbian/resdp.mmp
Normal file
36
mk/symbian/resdp.mmp
Normal file
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* @file resdp.mmp Symbian makefile for libre SDP
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
TARGET resdp.lib
|
||||
TARGETTYPE lib
|
||||
TARGETPATH system\libs
|
||||
UID 0x10000fd3 0x2001130C
|
||||
|
||||
#ifdef EKA2
|
||||
VENDORID 0
|
||||
CAPABILITY NetworkServices
|
||||
#endif
|
||||
|
||||
SOURCEPATH .
|
||||
SOURCE dll.cpp
|
||||
|
||||
SOURCEPATH ..\..\src\sdp
|
||||
SOURCE attr.c
|
||||
SOURCE format.c
|
||||
SOURCE media.c
|
||||
SOURCE msg.c
|
||||
SOURCE session.c
|
||||
SOURCE str.c
|
||||
|
||||
USERINCLUDE . ..\..\include
|
||||
SYSTEMINCLUDE \epoc32\include
|
||||
SYSTEMINCLUDE \epoc32\include\libc
|
||||
SYSTEMINCLUDE ..\..\include
|
||||
#ifndef EKA2
|
||||
LIBRARY estlib.lib euser.lib
|
||||
LIBRARY esock.lib insock.lib
|
||||
#endif
|
||||
|
||||
EXPORTUNFROZEN
|
50
mk/symbian/resip.mmp
Normal file
50
mk/symbian/resip.mmp
Normal file
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* @file resip.mmp Symbian makefile for libre SIP
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
TARGET resip.lib
|
||||
TARGETTYPE lib
|
||||
TARGETPATH system\libs
|
||||
UID 0x10000fd3 0x2001130A
|
||||
|
||||
#ifdef EKA2
|
||||
VENDORID 0
|
||||
CAPABILITY NetworkServices
|
||||
#endif
|
||||
|
||||
SOURCEPATH .
|
||||
SOURCE dll.cpp
|
||||
|
||||
SOURCEPATH ..\..\src\httpauth
|
||||
SOURCE basic.c
|
||||
SOURCE digest.c
|
||||
|
||||
SOURCEPATH ..\..\src\sip
|
||||
SOURCE addr.c
|
||||
SOURCE auth.c
|
||||
SOURCE cseq.c
|
||||
SOURCE ctrans.c
|
||||
SOURCE dialog.c
|
||||
SOURCE msg.c
|
||||
SOURCE param.c
|
||||
SOURCE reply.c
|
||||
SOURCE request.c
|
||||
SOURCE sip.c
|
||||
SOURCE strans.c
|
||||
SOURCE transp.c
|
||||
SOURCE via.c
|
||||
|
||||
SOURCEPATH ..\..\src\sipreg
|
||||
SOURCE reg.c
|
||||
|
||||
USERINCLUDE . ..\..\include
|
||||
SYSTEMINCLUDE \epoc32\include
|
||||
SYSTEMINCLUDE \epoc32\include\libc
|
||||
SYSTEMINCLUDE ..\..\include
|
||||
#ifndef EKA2
|
||||
LIBRARY estlib.lib euser.lib
|
||||
LIBRARY esock.lib insock.lib
|
||||
#endif
|
||||
|
||||
EXPORTUNFROZEN
|
40
mk/symbian/resipsess.mmp
Normal file
40
mk/symbian/resipsess.mmp
Normal file
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* @file resipsess.mmp Symbian makefile for libre SIP Session
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
TARGET resipsess.lib
|
||||
TARGETTYPE lib
|
||||
TARGETPATH system\libs
|
||||
UID 0x10000fd3 0x2001130D
|
||||
|
||||
#ifdef EKA2
|
||||
VENDORID 0
|
||||
CAPABILITY NetworkServices
|
||||
#endif
|
||||
|
||||
SOURCEPATH .
|
||||
SOURCE dll.cpp
|
||||
|
||||
SOURCEPATH ..\..\src\sipsess
|
||||
SOURCE accept.c
|
||||
SOURCE ack.c
|
||||
SOURCE close.c
|
||||
SOURCE connect.c
|
||||
SOURCE info.c
|
||||
SOURCE listen.c
|
||||
SOURCE modify.c
|
||||
SOURCE reply.c
|
||||
SOURCE request.c
|
||||
SOURCE sess.c
|
||||
|
||||
USERINCLUDE . ..\..\include
|
||||
SYSTEMINCLUDE \epoc32\include
|
||||
SYSTEMINCLUDE \epoc32\include\libc
|
||||
SYSTEMINCLUDE ..\..\include
|
||||
#ifndef EKA2
|
||||
LIBRARY estlib.lib euser.lib
|
||||
LIBRARY esock.lib insock.lib
|
||||
#endif
|
||||
|
||||
EXPORTUNFROZEN
|
69
mk/symbian/restun.mmp
Normal file
69
mk/symbian/restun.mmp
Normal file
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
* @file restun.mmp Symbian makefile for libre STUN
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
TARGET restun.lib
|
||||
TARGETTYPE lib
|
||||
TARGETPATH system\libs
|
||||
UID 0x10000fd3 0x2001130B
|
||||
|
||||
#ifdef EKA2
|
||||
VENDORID 0
|
||||
CAPABILITY NetworkServices
|
||||
#endif
|
||||
|
||||
SOURCEPATH .
|
||||
SOURCE dll.cpp
|
||||
|
||||
SOURCEPATH ..\..\src\ice
|
||||
SOURCE cand.c
|
||||
SOURCE candpair.c
|
||||
SOURCE chklist.c
|
||||
SOURCE comp.c
|
||||
SOURCE connchk.c
|
||||
SOURCE gather.c
|
||||
SOURCE ice.c
|
||||
SOURCE icem.c
|
||||
SOURCE icesdp.c
|
||||
SOURCE icestr.c
|
||||
SOURCE stunsrv.c
|
||||
SOURCE triggq.c
|
||||
SOURCE util.c
|
||||
|
||||
SOURCEPATH ..\..\src\natbd
|
||||
SOURCE filtering.c
|
||||
SOURCE genalg.c
|
||||
SOURCE hairpinning.c
|
||||
SOURCE lifetime.c
|
||||
SOURCE mapping.c
|
||||
SOURCE natstr.c
|
||||
|
||||
SOURCEPATH ..\..\src\stun
|
||||
SOURCE addr.c
|
||||
SOURCE attr.c
|
||||
SOURCE ctrans.c
|
||||
SOURCE dnsdisc.c
|
||||
SOURCE hdr.c
|
||||
SOURCE ind.c
|
||||
SOURCE keepalive.c
|
||||
SOURCE msg.c
|
||||
SOURCE rep.c
|
||||
SOURCE req.c
|
||||
SOURCE stun.c
|
||||
|
||||
SOURCEPATH ..\..\src\turn
|
||||
SOURCE chan.c
|
||||
SOURCE perm.c
|
||||
SOURCE turnc.c
|
||||
|
||||
USERINCLUDE . ..\..\include
|
||||
SYSTEMINCLUDE \epoc32\include
|
||||
SYSTEMINCLUDE \epoc32\include\libc
|
||||
SYSTEMINCLUDE ..\..\include
|
||||
#ifndef EKA2
|
||||
LIBRARY estlib.lib euser.lib
|
||||
LIBRARY esock.lib insock.lib
|
||||
#endif
|
||||
|
||||
EXPORTUNFROZEN
|
815
mk/win32/re.vcproj
Normal file
815
mk/win32/re.vcproj
Normal file
|
@ -0,0 +1,815 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="re-win32"
|
||||
ProjectGUID="{40B28DF6-4B4A-411A-9EB7-8D80C2A29B9D}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="..\..\Win32\Debug"
|
||||
IntermediateDirectory="c:\tmp\re\Win32\Debug"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
InlineFunctionExpansion="0"
|
||||
AdditionalIncludeDirectories="..\..\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_SELECT;HAVE_IO_H;_CRT_SECURE_NO_DEPRECATE"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="4"
|
||||
DisableSpecificWarnings="4142"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
AdditionalOptions="Iphlpapi.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Win32\Release"
|
||||
IntermediateDirectory="Win32\Release"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_SELECT;HAVE_IO_H;_CRT_SECURE_NO_DEPRECATE"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4142"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<Filter
|
||||
Name="base64"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\base64\b64.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="conf"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\conf\conf.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="crc32"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\crc32\crc32.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="dbg"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\dbg\dbg.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="dns"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\dns\client.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dns\cstr.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dns\dname.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dns\hdr.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dns\ns.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dns\rr.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dns\rrlist.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\dns\win32\srv.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="fmt"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\fmt\ch.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\fmt\pl.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\fmt\print.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\fmt\prm.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\fmt\regex.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\fmt\str.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\fmt\time.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="g711"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\g711\g711.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="hash"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\hash\func.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\hash\hash.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="hmac"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\hmac\hmac_sha1.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="httpauth"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\httpauth\basic.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\httpauth\digest.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="ice"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\ice\cand.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ice\candpair.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ice\chklist.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ice\comp.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ice\connchk.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ice\gather.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ice\ice.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ice\icem.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ice\icesdp.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ice\icestr.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ice\stunsrv.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ice\triggq.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ice\util.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="jbuf"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\jbuf\jbuf.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\jbuf\mod.mk">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="list"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\list\list.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\list\mod.mk">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="lock"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\lock\win32\lock.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="main"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\main\init.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\main\main.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\main\main.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\main\method.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\main\mod.mk">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\main\symbian">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="mbuf"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\mbuf\mbuf.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="md5"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\md5\md5.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\md5\md5.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\md5\wrap.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="mem"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\mem\mem.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="mod"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\mod\win32\dll.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\mod\mod.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\mod\mod_internal.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="natbd"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\natbd\filtering.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\natbd\genalg.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\natbd\hairpinning.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\natbd\lifetime.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\natbd\mapping.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\natbd\natstr.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="net"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\net\if.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\net\net.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\net\netstr.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\net\rt.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\net\sock.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\net\sockopt.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\net\win32\wif.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="rtp"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\rtp\fb.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\rtp\member.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\rtp\ntp.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\rtp\pkt.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\rtp\rr.c">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\rtp\rtcp.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\rtp\rtp.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\rtp\sdes.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\rtp\sess.c">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\rtp\source.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="sa"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\sa\ntop.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sa\pton.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sa\sa.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sa\sa.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="sdp"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\sdp\attr.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sdp\format.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sdp\media.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sdp\msg.c">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)2.obj"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)2.obj"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sdp\session.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sdp\str.c">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="sha"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\sha\sha1.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="sip"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\sip\addr.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sip\auth.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sip\cseq.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sip\ctrans.c">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sip\dialog.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sip\msg.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sip\param.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sip\reply.c">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sip\request.c">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sip\sip.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sip\strans.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sip\transp.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sip\via.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="sipreg"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\sipreg\reg.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="sipsess"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\sipsess\accept.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sipsess\ack.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sipsess\close.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sipsess\connect.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sipsess\info.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sipsess\listen.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sipsess\modify.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sipsess\reply.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sipsess\request.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sipsess\sess.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="stun"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\stun\addr.c">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\stun\attr.c">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\stun\ctrans.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\stun\dnsdisc.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\stun\hdr.c">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\stun\ind.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\stun\keepalive.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\stun\msg.c">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\stun\rep.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\stun\req.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\stun\stun.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\stun\stunstr.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="sys"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\sys\daemon.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sys\endian.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sys\rand.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\sys\sys.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="tcp"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\tcp\tcp.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\tcp\tcp_high.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="tmr"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\tmr\tmr.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="turn"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\turn\chan.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\turn\perm.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\turn\turnc.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="udp"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\udp\udp.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="uri"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\uri\ucmp.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\uri\uri.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\uri\uric.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="telev"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\src\telev\telev.c">
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
61
rpm/re.spec
Normal file
61
rpm/re.spec
Normal file
|
@ -0,0 +1,61 @@
|
|||
%define name re
|
||||
%define ver 0.1.0
|
||||
%define rel 3
|
||||
|
||||
Summary: Generic library for real-time communications with async IO support
|
||||
Name: %name
|
||||
Version: %ver
|
||||
Release: %rel
|
||||
License: BSD
|
||||
Group: Applications/Devel
|
||||
Source0: file://%{name}-%{version}.tar.gz
|
||||
URL: http://www.creytiv.com/
|
||||
Vendor: Creytiv
|
||||
Packager: Alfred E. Heggestad <aeh@db.org>
|
||||
BuildRoot: /var/tmp/%{name}-build-root
|
||||
|
||||
%description
|
||||
Generic library for real-time communications with async IO support
|
||||
|
||||
%package devel
|
||||
Summary: libre development files
|
||||
Group: Development/Libraries
|
||||
Requires: %{name} = %{version}
|
||||
|
||||
%description devel
|
||||
libre development files.
|
||||
|
||||
%prep
|
||||
%setup
|
||||
|
||||
%build
|
||||
make RELEASE=1
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
make DESTDIR=$RPM_BUILD_ROOT install \
|
||||
%ifarch x86_64
|
||||
LIBDIR=/usr/lib64
|
||||
%endif
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%post -p /sbin/ldconfig
|
||||
%postun -p /sbin/ldconfig
|
||||
|
||||
%files
|
||||
%defattr(644,root,root,755)
|
||||
%attr(755,root,root) %{_libdir}/libre*.so*
|
||||
|
||||
%files devel
|
||||
%defattr(644,root,root,755)
|
||||
%{_includedir}/re/*.h
|
||||
/usr/share/re/re.mk
|
||||
%{_libdir}/libre*.a
|
||||
|
||||
|
||||
%changelog
|
||||
* Fri Nov 5 2010 Alfred E. Heggestad <aeh@db.org> -
|
||||
- Initial build.
|
||||
|
126
src/base64/b64.c
Normal file
126
src/base64/b64.c
Normal file
|
@ -0,0 +1,126 @@
|
|||
/**
|
||||
* @file b64.c Base64 encoding/decoding functions
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <re_types.h>
|
||||
#include <re_base64.h>
|
||||
|
||||
|
||||
static const char b64_table[65] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
|
||||
/**
|
||||
* Base-64 encode a buffer
|
||||
*
|
||||
* @param in Input buffer
|
||||
* @param ilen Length of input buffer
|
||||
* @param out Output buffer
|
||||
* @param olen Size of output buffer, actual written on return
|
||||
*
|
||||
* @return 0 if success, otherwise errorcode
|
||||
*/
|
||||
int base64_encode(const uint8_t *in, size_t ilen, char *out, size_t *olen)
|
||||
{
|
||||
const uint8_t *in_end = in + ilen;
|
||||
const char *o = out;
|
||||
|
||||
if (!in || !out || !olen)
|
||||
return EINVAL;
|
||||
|
||||
if (*olen < ilen*4/3)
|
||||
return EOVERFLOW;
|
||||
|
||||
for (; in < in_end; ) {
|
||||
uint32_t v;
|
||||
int pad = 0;
|
||||
|
||||
v = *in++ << 16;
|
||||
if (in < in_end) {
|
||||
v |= *in++ << 8;
|
||||
}
|
||||
else {
|
||||
++pad;
|
||||
}
|
||||
if (in < in_end) {
|
||||
v |= *in++ << 0;
|
||||
}
|
||||
else {
|
||||
++pad;
|
||||
}
|
||||
|
||||
*out++ = b64_table[v>>18 & 0x3f];
|
||||
*out++ = b64_table[v>>12 & 0x3f];
|
||||
*out++ = (pad >= 2) ? '=' : b64_table[v>>6 & 0x3f];
|
||||
*out++ = (pad >= 1) ? '=' : b64_table[v>>0 & 0x3f];
|
||||
}
|
||||
|
||||
*olen = out - o;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* convert char -> 6-bit value */
|
||||
static inline uint32_t b64val(char c)
|
||||
{
|
||||
if ('A' <= c && c <= 'Z')
|
||||
return c - 'A' + 0;
|
||||
else if ('a' <= c && c <= 'z')
|
||||
return c - 'a' + 26;
|
||||
else if ('0' <= c && c <= '9')
|
||||
return c - '0' + 52;
|
||||
else if ('+' == c)
|
||||
return 62;
|
||||
else if ('/' == c)
|
||||
return 63;
|
||||
else if ('=' == c)
|
||||
return 1<<24; /* special trick */
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decode a Base-64 encoded string
|
||||
*
|
||||
* @param in Input buffer
|
||||
* @param ilen Length of input buffer
|
||||
* @param out Output buffer
|
||||
* @param olen Size of output buffer, actual written on return
|
||||
*
|
||||
* @return 0 if success, otherwise errorcode
|
||||
*/
|
||||
int base64_decode(const char *in, size_t ilen, uint8_t *out, size_t *olen)
|
||||
{
|
||||
const char *in_end = in + ilen;
|
||||
const uint8_t *o = out;
|
||||
|
||||
if (!in || !out || !olen)
|
||||
return EINVAL;
|
||||
|
||||
if (*olen < ilen*3/4)
|
||||
return EOVERFLOW;
|
||||
|
||||
for (;in < in_end; ) {
|
||||
uint32_t v;
|
||||
|
||||
v = b64val(*in++) << 18;
|
||||
v |= b64val(*in++) << 12;
|
||||
v |= b64val(*in++) << 6;
|
||||
v |= b64val(*in++) << 0;
|
||||
|
||||
*out++ = v>>16;
|
||||
if (!(v & (1<<30)))
|
||||
*out++ = (v>>8) & 0xff;
|
||||
if (!(v & (1<<24)))
|
||||
*out++ = (v>>0) & 0xff;
|
||||
}
|
||||
|
||||
*olen = out - o;
|
||||
|
||||
return 0;
|
||||
}
|
5
src/base64/mod.mk
Normal file
5
src/base64/mod.mk
Normal file
|
@ -0,0 +1,5 @@
|
|||
#
|
||||
# mod.mk
|
||||
#
|
||||
|
||||
SRCS += base64/b64.c
|
199
src/conf/conf.c
Normal file
199
src/conf/conf.c
Normal file
|
@ -0,0 +1,199 @@
|
|||
/**
|
||||
* @file conf.c Configuration file parser
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_IO_H
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include <re_types.h>
|
||||
#include <re_fmt.h>
|
||||
#include <re_mem.h>
|
||||
#include <re_mbuf.h>
|
||||
#include <re_conf.h>
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#define open _open
|
||||
#define read _read
|
||||
#define close _close
|
||||
#endif
|
||||
|
||||
|
||||
struct conf {
|
||||
struct mbuf *mb;
|
||||
};
|
||||
|
||||
|
||||
static int load_file(struct mbuf *mb, const char *filename)
|
||||
{
|
||||
int err = 0, fd = open(filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return errno;
|
||||
|
||||
for (;;) {
|
||||
uint8_t buf[1024];
|
||||
|
||||
const ssize_t n = read(fd, (void *)buf, sizeof(buf));
|
||||
if (n < 0) {
|
||||
err = errno;
|
||||
break;
|
||||
}
|
||||
else if (n == 0)
|
||||
break;
|
||||
|
||||
err |= mbuf_write_mem(mb, buf, n);
|
||||
}
|
||||
|
||||
(void)close(fd);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static void conf_destructor(void *data)
|
||||
{
|
||||
struct conf *conf = data;
|
||||
|
||||
mem_deref(conf->mb);
|
||||
}
|
||||
|
||||
|
||||
int conf_alloc(struct conf **confp, const char *filename)
|
||||
{
|
||||
struct conf *conf;
|
||||
int err = 0;
|
||||
|
||||
if (!confp)
|
||||
return EINVAL;
|
||||
|
||||
conf = mem_zalloc(sizeof(*conf), conf_destructor);
|
||||
if (!conf)
|
||||
return ENOMEM;
|
||||
|
||||
conf->mb = mbuf_alloc(1024);
|
||||
if (!conf->mb) {
|
||||
err = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err |= mbuf_write_u8(conf->mb, '\n');
|
||||
if (filename)
|
||||
err |= load_file(conf->mb, filename);
|
||||
|
||||
out:
|
||||
if (err)
|
||||
mem_deref(conf);
|
||||
else
|
||||
*confp = conf;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int conf_alloc_buf(struct conf **confp, const uint8_t *buf, size_t sz)
|
||||
{
|
||||
struct conf *conf;
|
||||
int err;
|
||||
|
||||
err = conf_alloc(&conf, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mbuf_write_mem(conf->mb, buf, sz);
|
||||
|
||||
if (err)
|
||||
mem_deref(conf);
|
||||
else
|
||||
*confp = conf;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int conf_get(struct conf *conf, const char *name, struct pl *pl)
|
||||
{
|
||||
char expr[512];
|
||||
struct pl spl;
|
||||
|
||||
if (!conf || !name || !pl)
|
||||
return EINVAL;
|
||||
|
||||
spl.p = (const char *)conf->mb->buf;
|
||||
spl.l = conf->mb->end;
|
||||
|
||||
(void)re_snprintf(expr, sizeof(expr),
|
||||
"[\r\n]+[ \t]*%s[ \t]+[~ \t\r\n]+", name);
|
||||
|
||||
return re_regex(spl.p, spl.l, expr, NULL, NULL, NULL, pl);
|
||||
}
|
||||
|
||||
|
||||
int conf_get_str(struct conf *conf, const char *name, char *str,
|
||||
size_t size)
|
||||
{
|
||||
struct pl pl;
|
||||
int err;
|
||||
|
||||
if (!conf || !name || !str || !size)
|
||||
return EINVAL;
|
||||
|
||||
err = conf_get(conf, name, &pl);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return pl_strcpy(&pl, str, size);
|
||||
}
|
||||
|
||||
|
||||
int conf_get_u32(struct conf *conf, const char *name, uint32_t *num)
|
||||
{
|
||||
struct pl pl;
|
||||
int err;
|
||||
|
||||
if (!conf || !name || !num)
|
||||
return EINVAL;
|
||||
|
||||
err = conf_get(conf, name, &pl);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
*num = pl_u32(&pl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int conf_apply(struct conf *conf, const char *name, conf_h *ch, void *arg)
|
||||
{
|
||||
char expr[512];
|
||||
struct pl pl, val;
|
||||
int err = 0;
|
||||
|
||||
if (!conf || !name || !ch)
|
||||
return EINVAL;
|
||||
|
||||
pl.p = (const char *)conf->mb->buf;
|
||||
pl.l = conf->mb->end;
|
||||
|
||||
(void)re_snprintf(expr, sizeof(expr),
|
||||
"[\r\n]+[ \t]*%s[ \t]+[~ \t\r\n]+", name);
|
||||
|
||||
while (!re_regex(pl.p, pl.l, expr, NULL, NULL, NULL, &val)) {
|
||||
|
||||
err = ch(&val, arg);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
pl.l -= val.p + val.l - pl.p;
|
||||
pl.p = val.p + val.l;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
5
src/conf/mod.mk
Normal file
5
src/conf/mod.mk
Normal file
|
@ -0,0 +1,5 @@
|
|||
#
|
||||
# mod.mk
|
||||
#
|
||||
|
||||
SRCS += conf/conf.c
|
109
src/crc32/crc32.c
Normal file
109
src/crc32/crc32.c
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*-
|
||||
* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
|
||||
* code or tables extracted from it, as desired without restriction.
|
||||
*/
|
||||
|
||||
/*
|
||||
* First, the polynomial itself and its table of feedback terms. The
|
||||
* polynomial is
|
||||
* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
|
||||
*
|
||||
* Note that we take it "backwards" and put the highest-order term in
|
||||
* the lowest-order bit. The X^32 term is "implied"; the LSB is the
|
||||
* X^31 term, etc. The X^0 term (usually shown as "+1") results in
|
||||
* the MSB being 1
|
||||
*
|
||||
* Note that the usual hardware shift register implementation, which
|
||||
* is what we're using (we're merely optimizing it by doing eight-bit
|
||||
* chunks at a time) shifts bits into the lowest-order term. In our
|
||||
* implementation, that means shifting towards the right. Why do we
|
||||
* do it this way? Because the calculated CRC must be transmitted in
|
||||
* order from highest-order term to lowest-order term. UARTs transmit
|
||||
* characters in order from LSB to MSB. By storing the CRC this way
|
||||
* we hand it to the UART in the order low-byte to high-byte; the UART
|
||||
* sends each low-bit to hight-bit; and the result is transmission bit
|
||||
* by bit from highest- to lowest-order term without requiring any bit
|
||||
* shuffling on our part. Reception works similarly
|
||||
*
|
||||
* The feedback terms table consists of 256, 32-bit entries. Notes
|
||||
*
|
||||
* The table can be generated at runtime if desired; code to do so
|
||||
* is shown later. It might not be obvious, but the feedback
|
||||
* terms simply represent the results of eight shift/xor opera
|
||||
* tions for all combinations of data and CRC register values
|
||||
*
|
||||
* The values must be right-shifted by eight bits by the "updcrc
|
||||
* logic; the shift must be unsigned (bring in zeroes). On some
|
||||
* hardware you could probably optimize the shift in assembler by
|
||||
* using byte-swap instructions
|
||||
* polynomial $edb88320
|
||||
*
|
||||
*
|
||||
* CRC32 code derived from work by Gary S. Brown.
|
||||
*/
|
||||
#include <re_types.h>
|
||||
#include <re_crc32.h>
|
||||
|
||||
|
||||
static const uint32_t crc32_tab[] = {
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A function that calculates the CRC-32 based on the table above is
|
||||
* given below for documentation purposes. An equivalent implementation
|
||||
* of this function that's actually used in the kernel can be found
|
||||
* in sys/libkern.h, where it can be inlined.
|
||||
*/
|
||||
uint32_t crc32(uint32_t crc, const void *buf, uint32_t size)
|
||||
{
|
||||
const uint8_t *p = buf;
|
||||
|
||||
crc = ~crc;
|
||||
while (size--)
|
||||
crc = crc32_tab[(crc ^ *p++) & 0xff] ^ (crc >> 8);
|
||||
return crc ^ ~0U;
|
||||
}
|
7
src/crc32/mod.mk
Normal file
7
src/crc32/mod.mk
Normal file
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# mod.mk
|
||||
#
|
||||
|
||||
ifeq ($(USE_ZLIB),)
|
||||
SRCS += crc32/crc32.c
|
||||
endif
|
326
src/dbg/dbg.c
Normal file
326
src/dbg/dbg.c
Normal file
|
@ -0,0 +1,326 @@
|
|||
/**
|
||||
* @file dbg.c Debug printing
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_PTHREAD
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
#include <re_types.h>
|
||||
#include <re_fmt.h>
|
||||
#include <re_list.h>
|
||||
#include <re_tmr.h>
|
||||
|
||||
|
||||
#define DEBUG_MODULE "dbg"
|
||||
#define DEBUG_LEVEL 0
|
||||
#include <re_dbg.h>
|
||||
|
||||
|
||||
/** Debug configuration */
|
||||
static struct {
|
||||
uint64_t tick; /**< Init ticks */
|
||||
int level; /**< Current debug level */
|
||||
enum dbg_flags flags; /**< Debug flags */
|
||||
dbg_print_h *ph; /**< Optional print handler */
|
||||
void *arg; /**< Handler argument */
|
||||
FILE *f; /**< Logfile */
|
||||
#ifdef HAVE_PTHREAD
|
||||
pthread_mutex_t mutex; /**< Thread locking */
|
||||
#endif
|
||||
} dbg = {
|
||||
0,
|
||||
DBG_INFO,
|
||||
DBG_ANSI,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
#ifdef HAVE_PTHREAD
|
||||
PTHREAD_MUTEX_INITIALIZER,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#ifdef HAVE_PTHREAD
|
||||
static inline void dbg_lock(void)
|
||||
{
|
||||
pthread_mutex_lock(&dbg.mutex);
|
||||
}
|
||||
|
||||
|
||||
static inline void dbg_unlock(void)
|
||||
{
|
||||
pthread_mutex_unlock(&dbg.mutex);
|
||||
}
|
||||
#else
|
||||
#define dbg_lock() /**< Stub */
|
||||
#define dbg_unlock() /**< Stub */
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Initialise debug printing
|
||||
*
|
||||
* @param level Debug level
|
||||
* @param flags Debug flags
|
||||
*/
|
||||
void dbg_init(int level, enum dbg_flags flags)
|
||||
{
|
||||
dbg.tick = tmr_jiffies();
|
||||
dbg.level = level;
|
||||
dbg.flags = flags;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Close debugging
|
||||
*/
|
||||
void dbg_close(void)
|
||||
{
|
||||
if (dbg.f) {
|
||||
(void)fclose(dbg.f);
|
||||
dbg.f = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set debug logfile
|
||||
*
|
||||
* @param name Name of the logfile, NULL to close
|
||||
*
|
||||
* @return 0 if success, otherwise errorcode
|
||||
*/
|
||||
int dbg_logfile_set(const char *name)
|
||||
{
|
||||
time_t t;
|
||||
|
||||
dbg_close();
|
||||
|
||||
if (!name)
|
||||
return 0;
|
||||
|
||||
dbg.f = fopen(name, "a+");
|
||||
if (!dbg.f)
|
||||
return errno;
|
||||
|
||||
(void)time(&t);
|
||||
(void)re_fprintf(dbg.f, "\n===== Log Started: %s", ctime(&t));
|
||||
(void)fflush(dbg.f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set optional debug print handler
|
||||
*
|
||||
* @param ph Print handler
|
||||
* @param arg Handler argument
|
||||
*/
|
||||
void dbg_handler_set(dbg_print_h *ph, void *arg)
|
||||
{
|
||||
dbg.ph = ph;
|
||||
dbg.arg = arg;
|
||||
}
|
||||
|
||||
|
||||
/* NOTE: This function should not allocate memory */
|
||||
static void dbg_vprintf(int level, const char *fmt, va_list ap)
|
||||
{
|
||||
if (level > dbg.level)
|
||||
return;
|
||||
|
||||
/* Print handler? */
|
||||
if (dbg.ph)
|
||||
return;
|
||||
|
||||
dbg_lock();
|
||||
|
||||
if (dbg.flags & DBG_ANSI) {
|
||||
switch (level) {
|
||||
case DBG_WARNING:
|
||||
(void)re_fprintf(stderr, "\x1b[31m"); /* Red */
|
||||
break;
|
||||
|
||||
case DBG_NOTICE:
|
||||
(void)re_fprintf(stderr, "\x1b[33m"); /* Yellow */
|
||||
break;
|
||||
|
||||
case DBG_INFO:
|
||||
(void)re_fprintf(stderr, "\x1b[32m"); /* Green */
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dbg.flags & DBG_TIME) {
|
||||
const uint64_t ticks = tmr_jiffies();
|
||||
|
||||
if (0 == dbg.tick)
|
||||
dbg.tick = tmr_jiffies();
|
||||
|
||||
(void)re_fprintf(stderr, "[%09llu] ", ticks - dbg.tick);
|
||||
}
|
||||
|
||||
(void)re_vfprintf(stderr, fmt, ap);
|
||||
|
||||
if (dbg.flags & DBG_ANSI && level < DBG_DEBUG)
|
||||
(void)re_fprintf(stderr, "\x1b[;m");
|
||||
|
||||
dbg_unlock();
|
||||
}
|
||||
|
||||
|
||||
/* Formatted output to print handler and/or logfile */
|
||||
static void dbg_fmt_vprintf(int level, const char *fmt, va_list ap)
|
||||
{
|
||||
char buf[256];
|
||||
int len;
|
||||
|
||||
if (level > dbg.level)
|
||||
return;
|
||||
|
||||
if (!dbg.ph && !dbg.f)
|
||||
return;
|
||||
|
||||
dbg_lock();
|
||||
|
||||
len = re_vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
if (len <= 0)
|
||||
goto out;
|
||||
|
||||
/* Print handler? */
|
||||
if (dbg.ph) {
|
||||
dbg.ph(level, buf, len, dbg.arg);
|
||||
}
|
||||
|
||||
/* Output to file */
|
||||
if (dbg.f) {
|
||||
(void)fwrite(buf, 1, len, dbg.f);
|
||||
(void)fflush(dbg.f);
|
||||
}
|
||||
|
||||
out:
|
||||
dbg_unlock();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print a formatted debug message
|
||||
*
|
||||
* @param level Debug level
|
||||
* @param fmt Formatted string
|
||||
*/
|
||||
void dbg_printf(int level, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
dbg_vprintf(level, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
va_start(ap, fmt);
|
||||
dbg_fmt_vprintf(level, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print a formatted debug message to /dev/null
|
||||
*
|
||||
* @param fmt Formatted string
|
||||
*/
|
||||
void dbg_noprintf(const char *fmt, ...)
|
||||
{
|
||||
(void)fmt;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print a formatted warning message
|
||||
*
|
||||
* @param fmt Formatted string
|
||||
*/
|
||||
void dbg_warning(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
dbg_vprintf(DBG_WARNING, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
va_start(ap, fmt);
|
||||
dbg_fmt_vprintf(DBG_WARNING, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print a formatted notice message
|
||||
*
|
||||
* @param fmt Formatted string
|
||||
*/
|
||||
void dbg_notice(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
dbg_vprintf(DBG_NOTICE, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
va_start(ap, fmt);
|
||||
dbg_fmt_vprintf(DBG_NOTICE, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print a formatted info message
|
||||
*
|
||||
* @param fmt Formatted string
|
||||
*/
|
||||
void dbg_info(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
dbg_vprintf(DBG_INFO, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
va_start(ap, fmt);
|
||||
dbg_fmt_vprintf(DBG_INFO, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the name of the debug level
|
||||
*
|
||||
* @param level Debug level
|
||||
*
|
||||
* @return String with debug level name
|
||||
*/
|
||||
const char *dbg_level_str(int level)
|
||||
{
|
||||
switch (level) {
|
||||
|
||||
case DBG_EMERG: return "EMERGENCY";
|
||||
case DBG_ALERT: return "ALERT";
|
||||
case DBG_CRIT: return "CRITICAL";
|
||||
case DBG_ERR: return "ERROR";
|
||||
case DBG_WARNING: return "WARNING";
|
||||
case DBG_NOTICE: return "NOTICE";
|
||||
case DBG_INFO: return "INFO";
|
||||
case DBG_DEBUG: return "DEBUG";
|
||||
default: return "???";
|
||||
}
|
||||
}
|
6
src/dbg/mod.mk
Normal file
6
src/dbg/mod.mk
Normal file
|
@ -0,0 +1,6 @@
|
|||
#
|
||||
# mod.mk
|
||||
#
|
||||
|
||||
|
||||
SRCS += dbg/dbg.c
|
853
src/dns/client.c
Normal file
853
src/dns/client.c
Normal file
|
@ -0,0 +1,853 @@
|
|||
/**
|
||||
* @file client.c DNS Client
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <re_types.h>
|
||||
#include <re_fmt.h>
|
||||
#include <re_mem.h>
|
||||
#include <re_mbuf.h>
|
||||
#include <re_list.h>
|
||||
#include <re_hash.h>
|
||||
#include <re_tmr.h>
|
||||
#include <re_sa.h>
|
||||
#include <re_udp.h>
|
||||
#include <re_tcp.h>
|
||||
#include <re_sys.h>
|
||||
#include <re_dns.h>
|
||||
|
||||
|
||||
#define DEBUG_MODULE "dnsc"
|
||||
#define DEBUG_LEVEL 5
|
||||
#include <re_dbg.h>
|
||||
|
||||
|
||||
enum {
|
||||
NTX_MAX = 20,
|
||||
QUERY_HASH_SIZE = 16,
|
||||
TCP_HASH_SIZE = 2,
|
||||
CONN_TIMEOUT = 10 * 1000,
|
||||
IDLE_TIMEOUT = 30 * 1000,
|
||||
};
|
||||
|
||||
|
||||
struct tcpconn {
|
||||
struct le le;
|
||||
struct list ql;
|
||||
struct tmr tmr;
|
||||
struct sa srv;
|
||||
struct tcp_conn *conn;
|
||||
struct mbuf *mb;
|
||||
bool connected;
|
||||
uint16_t flen;
|
||||
struct dnsc *dnsc; /* parent */
|
||||
};
|
||||
|
||||
|
||||
struct dns_query {
|
||||
struct le le;
|
||||
struct le le_tc;
|
||||
struct tmr tmr;
|
||||
struct mbuf mb;
|
||||
struct list rrlv[3];
|
||||
char *name;
|
||||
const struct sa *srvv;
|
||||
const uint32_t *srvc;
|
||||
struct tcpconn *tc;
|
||||
struct dnsc *dnsc; /* parent */
|
||||
struct dns_query **qp; /* app ref */
|
||||
uint32_t ntx;
|
||||
uint16_t id;
|
||||
uint16_t type;
|
||||
uint16_t dnsclass;
|
||||
uint8_t opcode;
|
||||
dns_query_h *qh;
|
||||
void *arg;
|
||||
};
|
||||
|
||||
|
||||
struct dnsquery {
|
||||
struct dnshdr hdr;
|
||||
char *name;
|
||||
uint16_t type;
|
||||
uint16_t dnsclass;
|
||||
};
|
||||
|
||||
|
||||
struct dnsc {
|
||||
struct dnsc_conf conf;
|
||||
struct hash *ht_query;
|
||||
struct hash *ht_tcpconn;
|
||||
struct udp_sock *us;
|
||||
struct sa *srvv;
|
||||
uint32_t srvc;
|
||||
};
|
||||
|
||||
|
||||
static const struct dnsc_conf default_conf = {
|
||||
QUERY_HASH_SIZE,
|
||||
TCP_HASH_SIZE,
|
||||
CONN_TIMEOUT,
|
||||
IDLE_TIMEOUT,
|
||||
false
|
||||
};
|
||||
|
||||
|
||||
static void tcpconn_close(struct tcpconn *tc, int err);
|
||||
static int send_tcp(struct dns_query *q);
|
||||
static void udp_timeout_handler(void *arg);
|
||||
|
||||
|
||||
static bool rr_unlink_handler(struct le *le, void *arg)
|
||||
{
|
||||
struct dnsrr *rr = le->data;
|
||||
(void)arg;
|
||||
|
||||
list_unlink(&rr->le_priv);
|
||||
mem_deref(rr);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static void query_abort(struct dns_query *q)
|
||||
{
|
||||
if (q->tc) {
|
||||
list_unlink(&q->le_tc);
|
||||
q->tc = mem_deref(q->tc);
|
||||
}
|
||||
|
||||
tmr_cancel(&q->tmr);
|
||||
hash_unlink(&q->le);
|
||||
}
|
||||
|
||||
|
||||
static void query_destructor(void *data)
|
||||
{
|
||||
struct dns_query *q = data;
|
||||
uint32_t i;
|
||||
|
||||
query_abort(q);
|
||||
mbuf_reset(&q->mb);
|
||||
mem_deref(q->name);
|
||||
|
||||
for (i=0; i<ARRAY_SIZE(q->rrlv); i++)
|
||||
(void)list_apply(&q->rrlv[i], true, rr_unlink_handler, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void query_handler(struct dns_query *q, int err,
|
||||
const struct dnshdr *hdr, struct list *ansl,
|
||||
struct list *authl, struct list *addl)
|
||||
{
|
||||
/* deref here - before calling handler */
|
||||
if (q->qp)
|
||||
*q->qp = NULL;
|
||||
|
||||
/* The handler must only be called _once_ */
|
||||
if (q->qh) {
|
||||
q->qh(err, hdr, ansl, authl, addl, q->arg);
|
||||
q->qh = NULL;
|
||||
}
|
||||
|
||||
/* in case we have more (than one) q refs */
|
||||
query_abort(q);
|
||||
}
|
||||
|
||||
|
||||
static bool query_close_handler(struct le *le, void *arg)
|
||||
{
|
||||
struct dns_query *q = le->data;
|
||||
(void)arg;
|
||||
|
||||
query_handler(q, ECONNABORTED, NULL, NULL, NULL, NULL);
|
||||
mem_deref(q);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool query_cmp_handler(struct le *le, void *arg)
|
||||
{
|
||||
struct dns_query *q = le->data;
|
||||
struct dnsquery *dq = arg;
|
||||
|
||||
if (q->id != dq->hdr.id)
|
||||
return false;
|
||||
|
||||
if (q->opcode != dq->hdr.opcode)
|
||||
return false;
|
||||
|
||||
if (q->type != dq->type)
|
||||
return false;
|
||||
|
||||
if (q->dnsclass != dq->dnsclass)
|
||||
return false;
|
||||
|
||||
if (str_casecmp(q->name, dq->name))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static int reply_recv(struct dnsc *dnsc, struct mbuf *mb)
|
||||
{
|
||||
struct dns_query *q = NULL;
|
||||
uint32_t i, j, nv[3];
|
||||
struct dnsquery dq;
|
||||
int err = 0;
|
||||
|
||||
if (!dnsc || !mb)
|
||||
return EINVAL;
|
||||
|
||||
dq.name = NULL;
|
||||
|
||||
if (dns_hdr_decode(mb, &dq.hdr) || !dq.hdr.qr) {
|
||||
err = EBADMSG;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = dns_dname_decode(mb, &dq.name, 0);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
if (mbuf_get_left(mb) < 4) {
|
||||
err = EBADMSG;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dq.type = ntohs(mbuf_read_u16(mb));
|
||||
dq.dnsclass = ntohs(mbuf_read_u16(mb));
|
||||
|
||||
q = list_ledata(hash_lookup(dnsc->ht_query, hash_joaat_str_ci(dq.name),
|
||||
query_cmp_handler, &dq));
|
||||
if (!q) {
|
||||
err = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* try next server */
|
||||
if (dq.hdr.rcode == DNS_RCODE_SRV_FAIL && q->ntx < *q->srvc) {
|
||||
|
||||
if (!q->tc) /* try next UDP server immediately */
|
||||
tmr_start(&q->tmr, 0, udp_timeout_handler, q);
|
||||
|
||||
err = EPROTO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
nv[0] = dq.hdr.nans;
|
||||
nv[1] = dq.hdr.nauth;
|
||||
nv[2] = dq.hdr.nadd;
|
||||
|
||||
for (i=0; i<ARRAY_SIZE(nv); i++) {
|
||||
|
||||
for (j=0; j<nv[i]; j++) {
|
||||
|
||||
struct dnsrr *rr = NULL;
|
||||
|
||||
err = dns_rr_decode(mb, &rr, 0);
|
||||
if (err) {
|
||||
query_handler(q, err, NULL, NULL, NULL, NULL);
|
||||
mem_deref(q);
|
||||
goto out;
|
||||
}
|
||||
|
||||
list_append(&q->rrlv[i], &rr->le_priv, rr);
|
||||
}
|
||||
}
|
||||
|
||||
if (q->type == DNS_QTYPE_AXFR) {
|
||||
|
||||
struct dnsrr *rrh, *rrt;
|
||||
|
||||
rrh = list_ledata(list_head(&q->rrlv[0]));
|
||||
rrt = list_ledata(list_tail(&q->rrlv[0]));
|
||||
|
||||
/* Wait for last AXFR reply with terminating SOA record */
|
||||
if (dq.hdr.rcode == DNS_RCODE_OK && dq.hdr.nans > 0 &&
|
||||
(!rrt || rrt->type != DNS_TYPE_SOA || rrh == rrt)) {
|
||||
DEBUG_INFO("waiting for last SOA record in reply\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
query_handler(q, 0, &dq.hdr, &q->rrlv[0], &q->rrlv[1], &q->rrlv[2]);
|
||||
mem_deref(q);
|
||||
|
||||
out:
|
||||
mem_deref(dq.name);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static void udp_recv_handler(const struct sa *src, struct mbuf *mb, void *arg)
|
||||
{
|
||||
(void)src;
|
||||
(void)reply_recv(arg, mb);
|
||||
}
|
||||
|
||||
|
||||
static void tcp_recv_handler(struct mbuf *mbrx, void *arg)
|
||||
{
|
||||
struct tcpconn *tc = arg;
|
||||
struct mbuf *mb = tc->mb;
|
||||
int err = 0;
|
||||
size_t n;
|
||||
|
||||
next:
|
||||
/* frame length */
|
||||
if (!tc->flen) {
|
||||
|
||||
n = min(2 - mb->end, mbuf_get_left(mbrx));
|
||||
|
||||
err = mbuf_write_mem(mb, mbuf_buf(mbrx), n);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
mbrx->pos += n;
|
||||
|
||||
if (mb->end < 2)
|
||||
return;
|
||||
|
||||
mb->pos = 0;
|
||||
tc->flen = ntohs(mbuf_read_u16(mb));
|
||||
mb->pos = 0;
|
||||
mb->end = 0;
|
||||
}
|
||||
|
||||
/* content */
|
||||
n = min(tc->flen - mb->end, mbuf_get_left(mbrx));
|
||||
|
||||
err = mbuf_write_mem(mb, mbuf_buf(mbrx), n);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
mbrx->pos += n;
|
||||
|
||||
if (mb->end < tc->flen)
|
||||
return;
|
||||
|
||||
mb->pos = 0;
|
||||
|
||||
err = reply_recv(tc->dnsc, mb);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
/* reset tcp buffer */
|
||||
tc->flen = 0;
|
||||
mb->pos = 0;
|
||||
mb->end = 0;
|
||||
|
||||
/* more data ? */
|
||||
if (mbuf_get_left(mbrx) > 0) {
|
||||
DEBUG_INFO("%u bytes of tcp data left\n", mbuf_get_left(mbrx));
|
||||
goto next;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
tcpconn_close(tc, err);
|
||||
}
|
||||
|
||||
|
||||
static void tcpconn_timeout_handler(void *arg)
|
||||
{
|
||||
struct tcpconn *tc = arg;
|
||||
|
||||
DEBUG_NOTICE("tcp (%J) %s timeout \n", &tc->srv,
|
||||
tc->connected ? "idle" : "connect");
|
||||
|
||||
tcpconn_close(tc, ETIMEDOUT);
|
||||
}
|
||||
|
||||
|
||||
static void tcp_estab_handler(void *arg)
|
||||
{
|
||||
struct tcpconn *tc = arg;
|
||||
struct le *le = list_head(&tc->ql);
|
||||
int err = 0;
|
||||
|
||||
DEBUG_INFO("connection (%J) established\n", &tc->srv);
|
||||
|
||||
while (le) {
|
||||
struct dns_query *q = le->data;
|
||||
|
||||
le = le->next;
|
||||
|
||||
q->mb.pos = 0;
|
||||
err = tcp_send(tc->conn, &q->mb);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
DEBUG_INFO("tcp send %J\n", &tc->srv);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
tcpconn_close(tc, err);
|
||||
return;
|
||||
}
|
||||
|
||||
tmr_start(&tc->tmr, tc->dnsc->conf.idle_timeout,
|
||||
tcpconn_timeout_handler, tc);
|
||||
tc->connected = true;
|
||||
}
|
||||
|
||||
|
||||
static void tcp_close_handler(int err, void *arg)
|
||||
{
|
||||
struct tcpconn *tc = arg;
|
||||
|
||||
DEBUG_NOTICE("connection (%J) closed: %s\n", &tc->srv, strerror(err));
|
||||
tcpconn_close(tc, err);
|
||||
}
|
||||
|
||||
|
||||
static bool tcpconn_cmp_handler(struct le *le, void *arg)
|
||||
{
|
||||
const struct tcpconn *tc = le->data;
|
||||
|
||||
/* avoid trying this connection if dead */
|
||||
if (!tc->conn)
|
||||
return false;
|
||||
|
||||
return sa_cmp(&tc->srv, arg, SA_ALL);
|
||||
}
|
||||
|
||||
|
||||
static bool tcpconn_fail_handler(struct le *le, void *arg)
|
||||
{
|
||||
struct dns_query *q = le->data;
|
||||
int err = *((int *)arg);
|
||||
|
||||
list_unlink(&q->le_tc);
|
||||
q->tc = mem_deref(q->tc);
|
||||
|
||||
if (q->ntx >= *q->srvc) {
|
||||
DEBUG_WARNING("all servers failed, giving up!!\n");
|
||||
err = err ? err : ECONNREFUSED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* try next server(s) */
|
||||
err = send_tcp(q);
|
||||
if (err) {
|
||||
DEBUG_WARNING("all servers failed, giving up\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (err) {
|
||||
query_handler(q, err, NULL, NULL, NULL, NULL);
|
||||
mem_deref(q);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static void tcpconn_close(struct tcpconn *tc, int err)
|
||||
{
|
||||
if (!tc)
|
||||
return;
|
||||
|
||||
/* avoid trying this connection again (e.g. same address) */
|
||||
tc->conn = mem_deref(tc->conn);
|
||||
(void)list_apply(&tc->ql, true, tcpconn_fail_handler, &err);
|
||||
mem_deref(tc);
|
||||
}
|
||||
|
||||
|
||||
static void tcpconn_destructor(void *arg)
|
||||
{
|
||||
struct tcpconn *tc = arg;
|
||||
|
||||
hash_unlink(&tc->le);
|
||||
tmr_cancel(&tc->tmr);
|
||||
mem_deref(tc->conn);
|
||||
mem_deref(tc->mb);
|
||||
}
|
||||
|
||||
|
||||
static int tcpconn_alloc(struct tcpconn **tcpp, struct dnsc *dnsc,
|
||||
const struct sa *srv)
|
||||
{
|
||||
struct tcpconn *tc;
|
||||
int err = ENOMEM;
|
||||
|
||||
if (!tcpp || !dnsc || !srv)
|
||||
return EINVAL;
|
||||
|
||||
tc = mem_zalloc(sizeof(struct tcpconn), tcpconn_destructor);
|
||||
if (!tc)
|
||||
goto out;
|
||||
|
||||
hash_append(dnsc->ht_tcpconn, sa_hash(srv, SA_ALL), &tc->le, tc);
|
||||
tc->srv = *srv;
|
||||
tc->dnsc = dnsc;
|
||||
|
||||
tc->mb = mbuf_alloc(1500);
|
||||
if (!tc->mb)
|
||||
goto out;
|
||||
|
||||
err = tcp_connect(&tc->conn, srv, tcp_estab_handler,
|
||||
tcp_recv_handler, tcp_close_handler, tc);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
tmr_start(&tc->tmr, tc->dnsc->conf.conn_timeout,
|
||||
tcpconn_timeout_handler, tc);
|
||||
out:
|
||||
if (err)
|
||||
mem_deref(tc);
|
||||
else
|
||||
*tcpp = tc;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static int send_tcp(struct dns_query *q)
|
||||
{
|
||||
const struct sa *srv;
|
||||
struct tcpconn *tc;
|
||||
int err = 0;
|
||||
|
||||
if (!q)
|
||||
return EINVAL;
|
||||
|
||||
while (q->ntx < *q->srvc) {
|
||||
|
||||
srv = &q->srvv[q->ntx++];
|
||||
|
||||
DEBUG_NOTICE("trying tcp server#%u: %J\n", q->ntx-1, srv);
|
||||
|
||||
tc = list_ledata(hash_lookup(q->dnsc->ht_tcpconn,
|
||||
sa_hash(srv, SA_ALL),
|
||||
tcpconn_cmp_handler,
|
||||
(void *)srv));
|
||||
if (!tc) {
|
||||
err = tcpconn_alloc(&tc, q->dnsc, srv);
|
||||
if (err)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tc->connected) {
|
||||
q->mb.pos = 0;
|
||||
err = tcp_send(tc->conn, &q->mb);
|
||||
if (err) {
|
||||
tcpconn_close(tc, err);
|
||||
continue;
|
||||
}
|
||||
|
||||
tmr_start(&tc->tmr, tc->dnsc->conf.idle_timeout,
|
||||
tcpconn_timeout_handler, tc);
|
||||
DEBUG_NOTICE("tcp send %J\n", srv);
|
||||
}
|
||||
|
||||
list_append(&tc->ql, &q->le_tc, q);
|
||||
q->tc = mem_ref(tc);
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static void tcp_timeout_handler(void *arg)
|
||||
{
|
||||
struct dns_query *q = arg;
|
||||
|
||||
query_handler(q, ETIMEDOUT, NULL, NULL, NULL, NULL);
|
||||
mem_deref(q);
|
||||
}
|
||||
|
||||
|
||||
static int send_udp(struct dns_query *q)
|
||||
{
|
||||
const struct sa *srv;
|
||||
int err = ETIMEDOUT;
|
||||
uint32_t i;
|
||||
|
||||
if (!q)
|
||||
return EINVAL;
|
||||
|
||||
for (i=0; i<*q->srvc; i++) {
|
||||
|
||||
srv = &q->srvv[q->ntx++%*q->srvc];
|
||||
|
||||
DEBUG_INFO("trying udp server#%u: %J\n", i, srv);
|
||||
|
||||
q->mb.pos = 0;
|
||||
err = udp_send(q->dnsc->us, srv, &q->mb);
|
||||
if (!err)
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static void udp_timeout_handler(void *arg)
|
||||
{
|
||||
struct dns_query *q = arg;
|
||||
int err = ETIMEDOUT;
|
||||
|
||||
if (q->ntx >= NTX_MAX)
|
||||
goto out;
|
||||
|
||||
err = send_udp(q);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
tmr_start(&q->tmr, 1000<<MIN(2, q->ntx - 2),
|
||||
udp_timeout_handler, q);
|
||||
|
||||
out:
|
||||
if (err) {
|
||||
query_handler(q, err, NULL, NULL, NULL, NULL);
|
||||
mem_deref(q);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int query(struct dns_query **qp, struct dnsc *dnsc, uint8_t opcode,
|
||||
const char *name, uint16_t type, uint16_t dnsclass,
|
||||
const struct dnsrr *ans_rr, int proto,
|
||||
const struct sa *srvv, const uint32_t *srvc,
|
||||
bool aa, bool rd, dns_query_h *qh, void *arg)
|
||||
{
|
||||
struct dns_query *q = NULL;
|
||||
struct dnshdr hdr;
|
||||
int err = 0;
|
||||
uint32_t i;
|
||||
|
||||
if (!dnsc || !name || !srvv || !srvc || !(*srvc))
|
||||
return EINVAL;
|
||||
|
||||
if (DNS_QTYPE_AXFR == type)
|
||||
proto = IPPROTO_TCP;
|
||||
|
||||
q = mem_zalloc(sizeof(*q), query_destructor);
|
||||
if (!q)
|
||||
goto nmerr;
|
||||
|
||||
hash_append(dnsc->ht_query, hash_joaat_str_ci(name), &q->le, q);
|
||||
tmr_init(&q->tmr);
|
||||
mbuf_init(&q->mb);
|
||||
|
||||
for (i=0; i<ARRAY_SIZE(q->rrlv); i++)
|
||||
list_init(&q->rrlv[i]);
|
||||
|
||||
err = str_dup(&q->name, name);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
q->srvv = srvv;
|
||||
q->srvc = srvc;
|
||||
q->id = rand_u16();
|
||||
q->type = type;
|
||||
q->opcode = opcode;
|
||||
q->dnsclass = dnsclass;
|
||||
q->dnsc = dnsc;
|
||||
|
||||
memset(&hdr, 0, sizeof(hdr));
|
||||
|
||||
hdr.id = q->id;
|
||||
hdr.opcode = q->opcode;
|
||||
hdr.aa = aa;
|
||||
hdr.rd = rd;
|
||||
hdr.nq = 1;
|
||||
hdr.nans = ans_rr ? 1 : 0;
|
||||
|
||||
if (proto == IPPROTO_TCP)
|
||||
q->mb.pos += 2;
|
||||
|
||||
err = dns_hdr_encode(&q->mb, &hdr);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
err = dns_dname_encode(&q->mb, name, NULL, 0, false);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
err |= mbuf_write_u16(&q->mb, htons(type));
|
||||
err |= mbuf_write_u16(&q->mb, htons(dnsclass));
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
if (ans_rr) {
|
||||
err = dns_rr_encode(&q->mb, ans_rr, 0, NULL, 0);
|
||||
if (err)
|
||||
goto error;
|
||||
}
|
||||
|
||||
q->qh = qh;
|
||||
q->arg = arg;
|
||||
|
||||
switch (proto) {
|
||||
|
||||
case IPPROTO_TCP:
|
||||
q->mb.pos = 0;
|
||||
(void)mbuf_write_u16(&q->mb, htons(q->mb.end - 2));
|
||||
|
||||
err = send_tcp(q);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
tmr_start(&q->tmr, 60 * 1000, tcp_timeout_handler, q);
|
||||
break;
|
||||
|
||||
case IPPROTO_UDP:
|
||||
err = send_udp(q);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
tmr_start(&q->tmr, 500, udp_timeout_handler, q);
|
||||
break;
|
||||
|
||||
default:
|
||||
err = EPROTONOSUPPORT;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (qp) {
|
||||
q->qp = qp;
|
||||
*qp = q;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
nmerr:
|
||||
err = ENOMEM;
|
||||
error:
|
||||
mem_deref(q);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int dnsc_query(struct dns_query **qp, struct dnsc *dnsc, const char *name,
|
||||
uint16_t type, uint16_t dnsclass,
|
||||
bool rd, dns_query_h *qh, void *arg)
|
||||
{
|
||||
if (!dnsc)
|
||||
return EINVAL;
|
||||
|
||||
return query(qp, dnsc, DNS_OPCODE_QUERY, name, type, dnsclass, NULL,
|
||||
IPPROTO_UDP, dnsc->srvv, &dnsc->srvc, false, rd, qh, arg);
|
||||
}
|
||||
|
||||
|
||||
int dnsc_query_srv(struct dns_query **qp, struct dnsc *dnsc, const char *name,
|
||||
uint16_t type, uint16_t dnsclass, int proto,
|
||||
const struct sa *srvv, const uint32_t *srvc,
|
||||
bool rd, dns_query_h *qh, void *arg)
|
||||
{
|
||||
return query(qp, dnsc, DNS_OPCODE_QUERY, name, type, dnsclass,
|
||||
NULL, proto, srvv, srvc, false, rd, qh, arg);
|
||||
}
|
||||
|
||||
|
||||
int dnsc_notify(struct dns_query **qp, struct dnsc *dnsc, const char *name,
|
||||
uint16_t type, uint16_t dnsclass, const struct dnsrr *ans_rr,
|
||||
int proto, const struct sa *srvv, const uint32_t *srvc,
|
||||
dns_query_h *qh, void *arg)
|
||||
{
|
||||
return query(qp, dnsc, DNS_OPCODE_NOTIFY, name, type, dnsclass,
|
||||
ans_rr, proto, srvv, srvc, true, false, qh, arg);
|
||||
}
|
||||
|
||||
|
||||
static void dnsc_destructor(void *data)
|
||||
{
|
||||
struct dnsc *dnsc = data;
|
||||
|
||||
(void)hash_apply(dnsc->ht_query, query_close_handler, NULL);
|
||||
hash_flush(dnsc->ht_tcpconn);
|
||||
|
||||
mem_deref(dnsc->ht_tcpconn);
|
||||
mem_deref(dnsc->ht_query);
|
||||
mem_deref(dnsc->us);
|
||||
mem_deref(dnsc->srvv);
|
||||
}
|
||||
|
||||
|
||||
int dnsc_alloc(struct dnsc **dcpp, const struct dnsc_conf *conf,
|
||||
const struct sa *srvv, uint32_t srvc)
|
||||
{
|
||||
struct dnsc *dnsc;
|
||||
int err;
|
||||
|
||||
if (!dcpp)
|
||||
return EINVAL;
|
||||
|
||||
dnsc = mem_zalloc(sizeof(*dnsc), dnsc_destructor);
|
||||
if (!dnsc)
|
||||
return ENOMEM;
|
||||
|
||||
if (conf)
|
||||
dnsc->conf = *conf;
|
||||
else
|
||||
dnsc->conf = default_conf;
|
||||
|
||||
err = dnsc_srv_set(dnsc, srvv, srvc);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = udp_listen(&dnsc->us, NULL, udp_recv_handler, dnsc);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
/* Experimental code:
|
||||
* Connected UDP sockets will only work if we have one UDP socket
|
||||
* per UDP server. Connected UDP socket is used to get ICMP
|
||||
* messages for unreachable DNS Servers.
|
||||
*/
|
||||
if (dnsc->conf.udp_conn)
|
||||
udp_connect(dnsc->us, true);
|
||||
|
||||
err = hash_alloc(&dnsc->ht_query, dnsc->conf.query_hash_size);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = hash_alloc(&dnsc->ht_tcpconn, dnsc->conf.tcp_hash_size);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
out:
|
||||
if (err)
|
||||
mem_deref(dnsc);
|
||||
else
|
||||
*dcpp = dnsc;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int dnsc_srv_set(struct dnsc *dnsc, const struct sa *srvv, uint32_t srvc)
|
||||
{
|
||||
const size_t sz = srvc * sizeof(*srvv);
|
||||
struct sa *v = NULL;
|
||||
|
||||
if (!dnsc)
|
||||
return EINVAL;
|
||||
|
||||
if (srvv && srvc) {
|
||||
v = mem_alloc(sz, NULL);
|
||||
if (!v)
|
||||
return ENOMEM;
|
||||
|
||||
memcpy(v, srvv, sz);
|
||||
}
|
||||
|
||||
dnsc->srvv = mem_deref(dnsc->srvv);
|
||||
dnsc->srvv = v;
|
||||
dnsc->srvc = srvc;
|
||||
|
||||
return 0;
|
||||
}
|
45
src/dns/cstr.c
Normal file
45
src/dns/cstr.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* @file cstr.c DNS character strings encoding
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <re_types.h>
|
||||
#include <re_fmt.h>
|
||||
#include <re_list.h>
|
||||
#include <re_mem.h>
|
||||
#include <re_mbuf.h>
|
||||
#include <re_dns.h>
|
||||
|
||||
|
||||
int dns_cstr_encode(struct mbuf *mb, const char *str)
|
||||
{
|
||||
uint8_t len;
|
||||
int err = 0;
|
||||
|
||||
if (!mb || !str)
|
||||
return EINVAL;
|
||||
|
||||
len = (uint8_t)strlen(str);
|
||||
|
||||
err |= mbuf_write_u8(mb, len);
|
||||
err |= mbuf_write_mem(mb, (const uint8_t *)str, len);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int dns_cstr_decode(struct mbuf *mb, char **str)
|
||||
{
|
||||
uint8_t len;
|
||||
|
||||
if (!mb || !str || (mbuf_get_left(mb) < 1))
|
||||
return EINVAL;
|
||||
|
||||
len = mbuf_read_u8(mb);
|
||||
|
||||
if (mbuf_get_left(mb) < len)
|
||||
return EBADMSG;
|
||||
|
||||
return mbuf_strdup(mb, str, len);
|
||||
}
|
83
src/dns/darwin/srv.c
Normal file
83
src/dns/darwin/srv.c
Normal file
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
* @file darwin/srv.c Get DNS Server IP code for Mac OS X
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <re_types.h>
|
||||
#include <re_fmt.h>
|
||||
#include <re_mbuf.h>
|
||||
#include <re_list.h>
|
||||
#include <re_sa.h>
|
||||
#include <re_dns.h>
|
||||
#include "../dns.h"
|
||||
#define __CF_USE_FRAMEWORK_INCLUDES__
|
||||
#include <SystemConfiguration/SystemConfiguration.h>
|
||||
|
||||
|
||||
int get_darwin_dns(char *domain, size_t dsize, struct sa *nsv, uint32_t *n)
|
||||
{
|
||||
#if TARGET_OS_IPHONE
|
||||
(void)domain;
|
||||
(void)dsize;
|
||||
(void)nsv;
|
||||
(void)n;
|
||||
return ENOSYS;
|
||||
#else
|
||||
SCDynamicStoreContext context = {0, NULL, NULL, NULL, NULL};
|
||||
CFArrayRef addresses, domains;
|
||||
SCDynamicStoreRef store;
|
||||
CFStringRef key, dom;
|
||||
CFDictionaryRef dict;
|
||||
uint32_t c, i;
|
||||
int err = ENOENT;
|
||||
|
||||
if (!nsv || !n)
|
||||
return EINVAL;
|
||||
|
||||
store = SCDynamicStoreCreate(NULL, CFSTR("get_darwin_dns"),
|
||||
NULL, &context);
|
||||
if (!store)
|
||||
return ENOENT;
|
||||
|
||||
key = CFSTR("State:/Network/Global/DNS");
|
||||
dict = SCDynamicStoreCopyValue(store, key);
|
||||
if (!dict)
|
||||
goto out1;
|
||||
|
||||
addresses = CFDictionaryGetValue(dict, kSCPropNetDNSServerAddresses);
|
||||
if (!addresses)
|
||||
goto out;
|
||||
|
||||
c = (uint32_t)CFArrayGetCount(addresses);
|
||||
*n = min(*n, c);
|
||||
|
||||
for (i=0; i<*n; i++) {
|
||||
CFStringRef address = CFArrayGetValueAtIndex(addresses, i);
|
||||
char str[64];
|
||||
|
||||
CFStringGetCString(address, str, sizeof(str),
|
||||
kCFStringEncodingUTF8);
|
||||
|
||||
err = sa_set_str(&nsv[i], str, DNS_PORT);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
|
||||
domains = CFDictionaryGetValue(dict, kSCPropNetDNSSearchDomains);
|
||||
if (!domains)
|
||||
goto out;
|
||||
|
||||
if (CFArrayGetCount(domains) < 1)
|
||||
goto out;
|
||||
|
||||
dom = CFArrayGetValueAtIndex(domains, 0);
|
||||
CFStringGetCString(dom, domain, dsize, kCFStringEncodingUTF8);
|
||||
|
||||
out:
|
||||
CFRelease(dict);
|
||||
out1:
|
||||
CFRelease(store);
|
||||
|
||||
return err;
|
||||
#endif
|
||||
}
|
195
src/dns/dname.c
Normal file
195
src/dns/dname.c
Normal file
|
@ -0,0 +1,195 @@
|
|||
/**
|
||||
* @file dname.c DNS domain names
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <re_types.h>
|
||||
#include <re_fmt.h>
|
||||
#include <re_list.h>
|
||||
#include <re_hash.h>
|
||||
#include <re_mem.h>
|
||||
#include <re_mbuf.h>
|
||||
#include <re_net.h>
|
||||
#include <re_dns.h>
|
||||
|
||||
|
||||
#define COMP_MASK 0xc0
|
||||
#define OFFSET_MASK 0x3fff
|
||||
|
||||
|
||||
struct dname {
|
||||
struct le he;
|
||||
size_t pos;
|
||||
char *name;
|
||||
};
|
||||
|
||||
|
||||
static void destructor(void *arg)
|
||||
{
|
||||
struct dname *dn = arg;
|
||||
|
||||
hash_unlink(&dn->he);
|
||||
mem_deref(dn->name);
|
||||
}
|
||||
|
||||
|
||||
static void dname_append(struct hash *ht_dname, const char *name, size_t pos)
|
||||
{
|
||||
struct dname *dn;
|
||||
|
||||
if (!ht_dname || pos > OFFSET_MASK || !*name)
|
||||
return;
|
||||
|
||||
dn = mem_zalloc(sizeof(*dn), destructor);
|
||||
if (!dn)
|
||||
return;
|
||||
|
||||
if (str_dup(&dn->name, name)) {
|
||||
mem_deref(dn);
|
||||
return;
|
||||
}
|
||||
|
||||
hash_append(ht_dname, hash_joaat_str_ci(name), &dn->he, dn);
|
||||
dn->pos = pos;
|
||||
}
|
||||
|
||||
|
||||
static bool lookup_handler(struct le *le, void *arg)
|
||||
{
|
||||
struct dname *dn = le->data;
|
||||
|
||||
return 0 == str_casecmp(dn->name, arg);
|
||||
}
|
||||
|
||||
|
||||
static inline struct dname *dname_lookup(struct hash *ht_dname,
|
||||
const char *name)
|
||||
{
|
||||
return list_ledata(hash_lookup(ht_dname, hash_joaat_str_ci(name),
|
||||
lookup_handler, (void *)name));
|
||||
}
|
||||
|
||||
|
||||
static inline int dname_encode_pointer(struct mbuf *mb, size_t pos)
|
||||
{
|
||||
return mbuf_write_u16(mb, htons(pos | (COMP_MASK<<8)));
|
||||
}
|
||||
|
||||
|
||||
int dns_dname_encode(struct mbuf *mb, const char *name,
|
||||
struct hash *ht_dname, size_t start, bool comp)
|
||||
{
|
||||
struct dname *dn;
|
||||
size_t pos;
|
||||
int err;
|
||||
|
||||
if (!mb || !name)
|
||||
return EINVAL;
|
||||
|
||||
dn = dname_lookup(ht_dname, name);
|
||||
if (dn && comp)
|
||||
return dname_encode_pointer(mb, dn->pos);
|
||||
|
||||
pos = mb->pos;
|
||||
if (!dn)
|
||||
dname_append(ht_dname, name, pos - start);
|
||||
err = mbuf_write_u8(mb, 0);
|
||||
|
||||
if ('.' == name[0] && '\0' == name[1])
|
||||
return err;
|
||||
|
||||
while (err == 0) {
|
||||
|
||||
const size_t lablen = mb->pos - pos - 1;
|
||||
|
||||
if ('\0' == *name) {
|
||||
if (!lablen)
|
||||
break;
|
||||
|
||||
mb->buf[pos] = lablen;
|
||||
err |= mbuf_write_u8(mb, 0);
|
||||
break;
|
||||
}
|
||||
else if ('.' == *name) {
|
||||
if (!lablen)
|
||||
return EINVAL;
|
||||
|
||||
mb->buf[pos] = lablen;
|
||||
|
||||
dn = dname_lookup(ht_dname, name + 1);
|
||||
if (dn && comp) {
|
||||
err |= dname_encode_pointer(mb, dn->pos);
|
||||
break;
|
||||
}
|
||||
|
||||
pos = mb->pos;
|
||||
if (!dn)
|
||||
dname_append(ht_dname, name + 1, pos - start);
|
||||
err |= mbuf_write_u8(mb, 0);
|
||||
}
|
||||
else {
|
||||
err |= mbuf_write_u8(mb, *name);
|
||||
}
|
||||
|
||||
++name;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int dns_dname_decode(struct mbuf *mb, char **name, size_t start)
|
||||
{
|
||||
bool comp = false;
|
||||
size_t pos = 0;
|
||||
char buf[256];
|
||||
uint32_t i = 0;
|
||||
|
||||
if (!mb || !name)
|
||||
return EINVAL;
|
||||
|
||||
while (mbuf_get_left(mb)) {
|
||||
|
||||
uint8_t len = mb->buf[mb->pos++];
|
||||
if (!len) {
|
||||
if (comp)
|
||||
mb->pos = pos;
|
||||
|
||||
buf[i++] = '\0';
|
||||
|
||||
*name = mem_alloc(i, NULL);
|
||||
if (!*name)
|
||||
return ENOMEM;
|
||||
|
||||
str_ncpy(*name, buf, i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else if ((len & COMP_MASK) == COMP_MASK) {
|
||||
uint16_t offset;
|
||||
|
||||
--mb->pos;
|
||||
|
||||
offset = ntohs(mbuf_read_u16(mb)) & OFFSET_MASK;
|
||||
if (!comp) {
|
||||
pos = mb->pos;
|
||||
comp = true;
|
||||
}
|
||||
|
||||
mb->pos = offset + start;
|
||||
continue;
|
||||
}
|
||||
else if (len > mbuf_get_left(mb))
|
||||
break;
|
||||
else if (len > sizeof(buf) - i - 2)
|
||||
break;
|
||||
|
||||
if (i > 0)
|
||||
buf[i++] = '.';
|
||||
|
||||
while (len--)
|
||||
buf[i++] = mb->buf[mb->pos++];
|
||||
}
|
||||
|
||||
return EINVAL;
|
||||
}
|
16
src/dns/dns.h
Normal file
16
src/dns/dns.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* @file dns.h Internal DNS header file
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_LIBRESOLV
|
||||
int get_resolv_dns(char *domain, size_t dsize, struct sa *nsv, uint32_t *n);
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
int get_windns(char *domain, size_t dsize, struct sa *nav, uint32_t *n);
|
||||
#endif
|
||||
#ifdef DARWIN
|
||||
int get_darwin_dns(char *domain, size_t dsize, struct sa *nsv, uint32_t *n);
|
||||
#endif
|
107
src/dns/hdr.c
Normal file
107
src/dns/hdr.c
Normal file
|
@ -0,0 +1,107 @@
|
|||
/**
|
||||
* @file dns/hdr.c DNS header encoding
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <re_types.h>
|
||||
#include <re_fmt.h>
|
||||
#include <re_list.h>
|
||||
#include <re_mbuf.h>
|
||||
#include <re_net.h>
|
||||
#include <re_dns.h>
|
||||
|
||||
|
||||
enum {
|
||||
QUERY_RESPONSE = 15,
|
||||
OPCODE = 11,
|
||||
AUTH_ANSWER = 10,
|
||||
TRUNCATED = 9,
|
||||
RECURSION_DESIRED = 8,
|
||||
RECURSION_AVAILABLE = 7,
|
||||
ZERO = 4
|
||||
};
|
||||
|
||||
|
||||
int dns_hdr_encode(struct mbuf *mb, const struct dnshdr *hdr)
|
||||
{
|
||||
uint16_t flags = 0;
|
||||
int err = 0;
|
||||
|
||||
if (!mb || !hdr)
|
||||
return EINVAL;
|
||||
|
||||
flags |= hdr->qr <<QUERY_RESPONSE;
|
||||
flags |= hdr->opcode <<OPCODE;
|
||||
flags |= hdr->aa <<AUTH_ANSWER;
|
||||
flags |= hdr->tc <<TRUNCATED;
|
||||
flags |= hdr->rd <<RECURSION_DESIRED;
|
||||
flags |= hdr->ra <<RECURSION_AVAILABLE;
|
||||
flags |= hdr->z <<ZERO;
|
||||
flags |= hdr->rcode;
|
||||
|
||||
err |= mbuf_write_u16(mb, htons(hdr->id));
|
||||
err |= mbuf_write_u16(mb, htons(flags));
|
||||
err |= mbuf_write_u16(mb, htons(hdr->nq));
|
||||
err |= mbuf_write_u16(mb, htons(hdr->nans));
|
||||
err |= mbuf_write_u16(mb, htons(hdr->nauth));
|
||||
err |= mbuf_write_u16(mb, htons(hdr->nadd));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int dns_hdr_decode(struct mbuf *mb, struct dnshdr *hdr)
|
||||
{
|
||||
uint16_t flags = 0;
|
||||
|
||||
if (!mb || !hdr || (mbuf_get_left(mb) < DNS_HEADER_SIZE))
|
||||
return EINVAL;
|
||||
|
||||
hdr->id = ntohs(mbuf_read_u16(mb));
|
||||
flags = ntohs(mbuf_read_u16(mb));
|
||||
|
||||
hdr->qr = 0x1 & (flags >> QUERY_RESPONSE);
|
||||
hdr->opcode = 0xf & (flags >> OPCODE);
|
||||
hdr->aa = 0x1 & (flags >> AUTH_ANSWER);
|
||||
hdr->tc = 0x1 & (flags >> TRUNCATED);
|
||||
hdr->rd = 0x1 & (flags >> RECURSION_DESIRED);
|
||||
hdr->ra = 0x1 & (flags >> RECURSION_AVAILABLE);
|
||||
hdr->z = 0x7 & (flags >> ZERO);
|
||||
hdr->rcode = 0xf & (flags >> 0);
|
||||
|
||||
hdr->nq = ntohs(mbuf_read_u16(mb));
|
||||
hdr->nans = ntohs(mbuf_read_u16(mb));
|
||||
hdr->nauth = ntohs(mbuf_read_u16(mb));
|
||||
hdr->nadd = ntohs(mbuf_read_u16(mb));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const char *dns_hdr_opcodename(uint8_t opcode)
|
||||
{
|
||||
switch (opcode) {
|
||||
|
||||
case DNS_OPCODE_QUERY: return "QUERY";
|
||||
case DNS_OPCODE_IQUERY: return "IQUERY";
|
||||
case DNS_OPCODE_STATUS: return "STATUS";
|
||||
case DNS_OPCODE_NOTIFY: return "NOTIFY";
|
||||
default: return "??";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char *dns_hdr_rcodename(uint8_t rcode)
|
||||
{
|
||||
switch (rcode) {
|
||||
|
||||
case DNS_RCODE_OK: return "OK";
|
||||
case DNS_RCODE_FMT_ERR: return "Format Error";
|
||||
case DNS_RCODE_SRV_FAIL: return "Server Failure";
|
||||
case DNS_RCODE_NAME_ERR: return "Name Error";
|
||||
case DNS_RCODE_NOT_IMPL: return "Not Implemented";
|
||||
case DNS_RCODE_REFUSED: return "Refused";
|
||||
case DNS_RCODE_NOT_AUTH: return "Server Not Authoritative for zone";
|
||||
default: return "??";
|
||||
}
|
||||
}
|
26
src/dns/mod.mk
Normal file
26
src/dns/mod.mk
Normal file
|
@ -0,0 +1,26 @@
|
|||
#
|
||||
# mod.mk
|
||||
#
|
||||
|
||||
|
||||
SRCS += dns/client.c
|
||||
SRCS += dns/cstr.c
|
||||
SRCS += dns/dname.c
|
||||
SRCS += dns/hdr.c
|
||||
SRCS += dns/ns.c
|
||||
SRCS += dns/rr.c
|
||||
SRCS += dns/rrlist.c
|
||||
|
||||
ifneq ($(HAVE_LIBRESOLV),)
|
||||
SRCS += dns/res.c
|
||||
endif
|
||||
|
||||
ifeq ($(OS),win32)
|
||||
SRCS += dns/win32/srv.c
|
||||
endif
|
||||
|
||||
ifeq ($(OS),darwin)
|
||||
SRCS += dns/darwin/srv.c
|
||||
# add libraries for darwin dns servers
|
||||
LFLAGS += -framework SystemConfiguration -framework CoreFoundation
|
||||
endif
|
117
src/dns/ns.c
Normal file
117
src/dns/ns.c
Normal file
|
@ -0,0 +1,117 @@
|
|||
/**
|
||||
* @file ns.c DNS Nameserver configuration
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <re_types.h>
|
||||
#include <re_fmt.h>
|
||||
#include <re_mbuf.h>
|
||||
#include <re_list.h>
|
||||
#include <re_sa.h>
|
||||
#include <re_dns.h>
|
||||
#include "dns.h"
|
||||
|
||||
|
||||
#define DEBUG_MODULE "ns"
|
||||
#define DEBUG_LEVEL 5
|
||||
#include <re_dbg.h>
|
||||
|
||||
|
||||
#ifdef __SYMBIAN32__
|
||||
extern int get_symbiandns(struct sa *nsv, uint32_t *n);
|
||||
#endif
|
||||
|
||||
|
||||
static int parse_resolv_conf(char *domain, size_t dsize,
|
||||
struct sa *srvv, uint32_t *n)
|
||||
{
|
||||
FILE *f;
|
||||
struct pl dom = pl_null;
|
||||
uint32_t i = 0;
|
||||
int err = 0;
|
||||
|
||||
if (!srvv || !n || !*n)
|
||||
return EINVAL;
|
||||
|
||||
f = fopen("/etc/resolv.conf", "r");
|
||||
if (!f)
|
||||
return errno;
|
||||
|
||||
for (;;) {
|
||||
char line[128];
|
||||
struct pl srv;
|
||||
size_t len;
|
||||
|
||||
if (1 != fscanf(f, "%127[^\n]\n", line))
|
||||
break;
|
||||
|
||||
if ('#' == line[0])
|
||||
continue;
|
||||
|
||||
len = str_len(line);
|
||||
|
||||
/* Set domain if not already set */
|
||||
if (!pl_isset(&dom)) {
|
||||
if (0 == re_regex(line, len, "domain [^ ]+", &dom)) {
|
||||
(void)pl_strcpy(&dom, domain, dsize);
|
||||
}
|
||||
|
||||
if (0 == re_regex(line, len, "search [^ ]+", &dom)) {
|
||||
(void)pl_strcpy(&dom, domain, dsize);
|
||||
}
|
||||
}
|
||||
|
||||
/* Use the first entry */
|
||||
if (i < *n && 0 == re_regex(line, len, "nameserver [^\n]+",
|
||||
&srv)) {
|
||||
err = sa_set(&srvv[i], &srv, DNS_PORT);
|
||||
if (err) {
|
||||
DEBUG_WARNING("sa_set: %r (%s)\n",
|
||||
&srv, strerror(err));
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
*n = i;
|
||||
|
||||
(void)fclose(f);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int dns_srv_get(char *domain, size_t dsize, struct sa *srvv, uint32_t *n)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Try them all in prioritized order */
|
||||
|
||||
#ifdef HAVE_LIBRESOLV
|
||||
err = get_resolv_dns(domain, dsize, srvv, n);
|
||||
if (!err)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#ifdef DARWIN
|
||||
err = get_darwin_dns(domain, dsize, srvv, n);
|
||||
if (!err)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
err = parse_resolv_conf(domain, dsize, srvv, n);
|
||||
if (!err)
|
||||
return 0;
|
||||
|
||||
#ifdef WIN32
|
||||
err = get_windns(domain, dsize, srvv, n);
|
||||
#endif
|
||||
|
||||
#ifdef __SYMBIAN32__
|
||||
err = get_symbiandns(srvv, n);
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
56
src/dns/res.c
Normal file
56
src/dns/res.c
Normal file
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
* @file res.c Get DNS Server IP using libresolv
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#define _BSD_SOURCE 1
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
#include <re_types.h>
|
||||
#include <re_fmt.h>
|
||||
#include <re_mbuf.h>
|
||||
#include <re_list.h>
|
||||
#include <re_sa.h>
|
||||
#include <re_dns.h>
|
||||
#include "dns.h"
|
||||
|
||||
|
||||
/**
|
||||
* Generic way of fetching Nameserver IP-addresses, using libresolv
|
||||
*
|
||||
* @note we could use res_getservers() but it is not available on Linux
|
||||
* @note only IPv4 is supported
|
||||
*/
|
||||
int get_resolv_dns(char *domain, size_t dsize, struct sa *nsv, uint32_t *n)
|
||||
{
|
||||
uint32_t i;
|
||||
int ret, err;
|
||||
|
||||
ret = res_init();
|
||||
if (0 != ret)
|
||||
return ENOENT;
|
||||
|
||||
if (_res.dnsrch[0])
|
||||
str_ncpy(domain, _res.dnsrch[0], dsize);
|
||||
else if (_res.defdname)
|
||||
str_ncpy(domain, _res.defdname, dsize);
|
||||
|
||||
*n = min(*n, (uint32_t)_res.nscount);
|
||||
if (!*n) {
|
||||
err = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
for (i=0; i<*n && !err; i++) {
|
||||
struct sockaddr_in *addr = &_res.nsaddr_list[i];
|
||||
err |= sa_set_sa(&nsv[i], (struct sockaddr *)addr);
|
||||
}
|
||||
|
||||
out:
|
||||
res_close();
|
||||
|
||||
return err;
|
||||
}
|
574
src/dns/rr.c
Normal file
574
src/dns/rr.c
Normal file
|
@ -0,0 +1,574 @@
|
|||
/**
|
||||
* @file dns/rr.c DNS Resource Records
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <re_types.h>
|
||||
#include <re_fmt.h>
|
||||
#include <re_list.h>
|
||||
#include <re_mem.h>
|
||||
#include <re_mbuf.h>
|
||||
#include <re_net.h>
|
||||
#include <re_sa.h>
|
||||
#include <re_dns.h>
|
||||
|
||||
|
||||
static void rr_destructor(void *data)
|
||||
{
|
||||
struct dnsrr *rr = data;
|
||||
|
||||
mem_deref(rr->name);
|
||||
|
||||
switch (rr->type) {
|
||||
|
||||
case DNS_TYPE_NS:
|
||||
mem_deref(rr->rdata.ns.nsdname);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_CNAME:
|
||||
mem_deref(rr->rdata.cname.cname);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_SOA:
|
||||
mem_deref(rr->rdata.soa.mname);
|
||||
mem_deref(rr->rdata.soa.rname);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_PTR:
|
||||
mem_deref(rr->rdata.ptr.ptrdname);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_MX:
|
||||
mem_deref(rr->rdata.mx.exchange);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_SRV:
|
||||
mem_deref(rr->rdata.srv.target);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_NAPTR:
|
||||
mem_deref(rr->rdata.naptr.flags);
|
||||
mem_deref(rr->rdata.naptr.services);
|
||||
mem_deref(rr->rdata.naptr.regexp);
|
||||
mem_deref(rr->rdata.naptr.replace);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct dnsrr *dns_rr_alloc(void)
|
||||
{
|
||||
return mem_zalloc(sizeof(struct dnsrr), rr_destructor);
|
||||
}
|
||||
|
||||
|
||||
int dns_rr_encode(struct mbuf *mb, const struct dnsrr *rr, int64_t ttl_offs,
|
||||
struct hash *ht_dname, size_t start)
|
||||
{
|
||||
uint32_t ttl;
|
||||
uint16_t len;
|
||||
size_t start_rdata;
|
||||
int err = 0;
|
||||
|
||||
if (!mb || !rr)
|
||||
return EINVAL;
|
||||
|
||||
ttl = (uint32_t)((rr->ttl > ttl_offs) ? (rr->ttl - ttl_offs) : 0);
|
||||
|
||||
err |= dns_dname_encode(mb, rr->name, ht_dname, start, true);
|
||||
err |= mbuf_write_u16(mb, htons(rr->type));
|
||||
err |= mbuf_write_u16(mb, htons(rr->dnsclass));
|
||||
err |= mbuf_write_u32(mb, htonl(ttl));
|
||||
err |= mbuf_write_u16(mb, htons(rr->rdlen));
|
||||
|
||||
start_rdata = mb->pos;
|
||||
|
||||
switch (rr->type) {
|
||||
|
||||
case DNS_TYPE_A:
|
||||
err |= mbuf_write_u32(mb, htonl(rr->rdata.a.addr));
|
||||
break;
|
||||
|
||||
case DNS_TYPE_NS:
|
||||
err |= dns_dname_encode(mb, rr->rdata.ns.nsdname,
|
||||
ht_dname, start, true);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_CNAME:
|
||||
err |= dns_dname_encode(mb, rr->rdata.cname.cname,
|
||||
ht_dname, start, true);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_SOA:
|
||||
err |= dns_dname_encode(mb, rr->rdata.soa.mname,
|
||||
ht_dname, start, true);
|
||||
err |= dns_dname_encode(mb, rr->rdata.soa.rname,
|
||||
ht_dname, start, true);
|
||||
err |= mbuf_write_u32(mb, htonl(rr->rdata.soa.serial));
|
||||
err |= mbuf_write_u32(mb, htonl(rr->rdata.soa.refresh));
|
||||
err |= mbuf_write_u32(mb, htonl(rr->rdata.soa.retry));
|
||||
err |= mbuf_write_u32(mb, htonl(rr->rdata.soa.expire));
|
||||
err |= mbuf_write_u32(mb, htonl(rr->rdata.soa.ttlmin));
|
||||
break;
|
||||
|
||||
case DNS_TYPE_PTR:
|
||||
err |= dns_dname_encode(mb, rr->rdata.ptr.ptrdname,
|
||||
ht_dname, start, true);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_MX:
|
||||
err |= mbuf_write_u16(mb, htons(rr->rdata.mx.pref));
|
||||
err |= dns_dname_encode(mb, rr->rdata.mx.exchange,
|
||||
ht_dname, start, true);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_AAAA:
|
||||
err |= mbuf_write_mem(mb, rr->rdata.aaaa.addr, 16);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_SRV:
|
||||
err |= mbuf_write_u16(mb, htons(rr->rdata.srv.pri));
|
||||
err |= mbuf_write_u16(mb, htons(rr->rdata.srv.weight));
|
||||
err |= mbuf_write_u16(mb, htons(rr->rdata.srv.port));
|
||||
err |= dns_dname_encode(mb, rr->rdata.srv.target,
|
||||
ht_dname, start, false);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_NAPTR:
|
||||
err |= mbuf_write_u16(mb, htons(rr->rdata.naptr.order));
|
||||
err |= mbuf_write_u16(mb, htons(rr->rdata.naptr.pref));
|
||||
err |= dns_cstr_encode(mb, rr->rdata.naptr.flags);
|
||||
err |= dns_cstr_encode(mb, rr->rdata.naptr.services);
|
||||
err |= dns_cstr_encode(mb, rr->rdata.naptr.regexp);
|
||||
err |= dns_dname_encode(mb, rr->rdata.naptr.replace,
|
||||
ht_dname, start, false);
|
||||
break;
|
||||
|
||||
default:
|
||||
err = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
len = mb->pos - start_rdata;
|
||||
mb->pos = start_rdata - 2;
|
||||
err |= mbuf_write_u16(mb, htons(len));
|
||||
mb->pos += len;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int dns_rr_decode(struct mbuf *mb, struct dnsrr **rr, size_t start)
|
||||
{
|
||||
int err = 0;
|
||||
struct dnsrr *lrr;
|
||||
|
||||
if (!mb || !rr)
|
||||
return EINVAL;
|
||||
|
||||
lrr = dns_rr_alloc();
|
||||
if (!lrr)
|
||||
return ENOMEM;
|
||||
|
||||
err = dns_dname_decode(mb, &lrr->name, start);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
if (mbuf_get_left(mb) < 10)
|
||||
goto fmerr;
|
||||
|
||||
lrr->type = ntohs(mbuf_read_u16(mb));
|
||||
lrr->dnsclass = ntohs(mbuf_read_u16(mb));
|
||||
lrr->ttl = ntohl(mbuf_read_u32(mb));
|
||||
lrr->rdlen = ntohs(mbuf_read_u16(mb));
|
||||
|
||||
if (mbuf_get_left(mb) < lrr->rdlen)
|
||||
goto fmerr;
|
||||
|
||||
switch (lrr->type) {
|
||||
|
||||
case DNS_TYPE_A:
|
||||
if (lrr->rdlen != 4)
|
||||
goto fmerr;
|
||||
|
||||
lrr->rdata.a.addr = ntohl(mbuf_read_u32(mb));
|
||||
break;
|
||||
|
||||
case DNS_TYPE_NS:
|
||||
err = dns_dname_decode(mb, &lrr->rdata.ns.nsdname, start);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
break;
|
||||
|
||||
case DNS_TYPE_CNAME:
|
||||
err = dns_dname_decode(mb, &lrr->rdata.cname.cname, start);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
break;
|
||||
|
||||
case DNS_TYPE_SOA:
|
||||
err = dns_dname_decode(mb, &lrr->rdata.soa.mname, start);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
err = dns_dname_decode(mb, &lrr->rdata.soa.rname, start);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
if (mbuf_get_left(mb) < 20)
|
||||
goto fmerr;
|
||||
|
||||
lrr->rdata.soa.serial = ntohl(mbuf_read_u32(mb));
|
||||
lrr->rdata.soa.refresh = ntohl(mbuf_read_u32(mb));
|
||||
lrr->rdata.soa.retry = ntohl(mbuf_read_u32(mb));
|
||||
lrr->rdata.soa.expire = ntohl(mbuf_read_u32(mb));
|
||||
lrr->rdata.soa.ttlmin = ntohl(mbuf_read_u32(mb));
|
||||
break;
|
||||
|
||||
case DNS_TYPE_PTR:
|
||||
err = dns_dname_decode(mb, &lrr->rdata.ptr.ptrdname, start);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
break;
|
||||
|
||||
case DNS_TYPE_MX:
|
||||
if (mbuf_get_left(mb) < 2)
|
||||
goto fmerr;
|
||||
|
||||
lrr->rdata.mx.pref = ntohs(mbuf_read_u16(mb));
|
||||
|
||||
err = dns_dname_decode(mb, &lrr->rdata.mx.exchange, start);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
break;
|
||||
|
||||
case DNS_TYPE_AAAA:
|
||||
if (lrr->rdlen != 16)
|
||||
goto fmerr;
|
||||
|
||||
err = mbuf_read_mem(mb, lrr->rdata.aaaa.addr, 16);
|
||||
if (err)
|
||||
goto error;
|
||||
break;
|
||||
|
||||
case DNS_TYPE_SRV:
|
||||
if (mbuf_get_left(mb) < 6)
|
||||
goto fmerr;
|
||||
|
||||
lrr->rdata.srv.pri = ntohs(mbuf_read_u16(mb));
|
||||
lrr->rdata.srv.weight = ntohs(mbuf_read_u16(mb));
|
||||
lrr->rdata.srv.port = ntohs(mbuf_read_u16(mb));
|
||||
|
||||
err = dns_dname_decode(mb, &lrr->rdata.srv.target, start);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
break;
|
||||
|
||||
case DNS_TYPE_NAPTR:
|
||||
if (mbuf_get_left(mb) < 4)
|
||||
goto fmerr;
|
||||
|
||||
lrr->rdata.naptr.order = ntohs(mbuf_read_u16(mb));
|
||||
lrr->rdata.naptr.pref = ntohs(mbuf_read_u16(mb));
|
||||
|
||||
err = dns_cstr_decode(mb, &lrr->rdata.naptr.flags);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
err = dns_cstr_decode(mb, &lrr->rdata.naptr.services);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
err = dns_cstr_decode(mb, &lrr->rdata.naptr.regexp);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
err = dns_dname_decode(mb, &lrr->rdata.naptr.replace, start);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
mb->pos += lrr->rdlen;
|
||||
break;
|
||||
}
|
||||
|
||||
*rr = lrr;
|
||||
|
||||
return 0;
|
||||
|
||||
fmerr:
|
||||
err = EINVAL;
|
||||
error:
|
||||
mem_deref(lrr);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
bool dns_rr_cmp(const struct dnsrr *rr1, const struct dnsrr *rr2, bool rdata)
|
||||
{
|
||||
if (!rr1 || !rr2)
|
||||
return false;
|
||||
|
||||
if (rr1 == rr2)
|
||||
return true;
|
||||
|
||||
if (rr1->type != rr2->type)
|
||||
return false;
|
||||
|
||||
if (rr1->dnsclass != rr2->dnsclass)
|
||||
return false;
|
||||
|
||||
if (str_casecmp(rr1->name, rr2->name))
|
||||
return false;
|
||||
|
||||
if (!rdata)
|
||||
return true;
|
||||
|
||||
switch (rr1->type) {
|
||||
|
||||
case DNS_TYPE_A:
|
||||
if (rr1->rdata.a.addr != rr2->rdata.a.addr)
|
||||
return false;
|
||||
|
||||
break;
|
||||
|
||||
case DNS_TYPE_NS:
|
||||
if (str_casecmp(rr1->rdata.ns.nsdname, rr2->rdata.ns.nsdname))
|
||||
return false;
|
||||
|
||||
break;
|
||||
|
||||
case DNS_TYPE_CNAME:
|
||||
if (str_casecmp(rr1->rdata.cname.cname,
|
||||
rr2->rdata.cname.cname))
|
||||
return false;
|
||||
|
||||
break;
|
||||
|
||||
case DNS_TYPE_SOA:
|
||||
if (str_casecmp(rr1->rdata.soa.mname, rr2->rdata.soa.mname))
|
||||
return false;
|
||||
|
||||
if (str_casecmp(rr1->rdata.soa.rname, rr2->rdata.soa.rname))
|
||||
return false;
|
||||
|
||||
if (rr1->rdata.soa.serial != rr2->rdata.soa.serial)
|
||||
return false;
|
||||
|
||||
if (rr1->rdata.soa.refresh != rr2->rdata.soa.refresh)
|
||||
return false;
|
||||
|
||||
if (rr1->rdata.soa.retry != rr2->rdata.soa.retry)
|
||||
return false;
|
||||
|
||||
if (rr1->rdata.soa.expire != rr2->rdata.soa.expire)
|
||||
return false;
|
||||
|
||||
if (rr1->rdata.soa.ttlmin != rr2->rdata.soa.ttlmin)
|
||||
return false;
|
||||
|
||||
break;
|
||||
|
||||
case DNS_TYPE_PTR:
|
||||
if (str_casecmp(rr1->rdata.ptr.ptrdname,
|
||||
rr2->rdata.ptr.ptrdname))
|
||||
return false;
|
||||
|
||||
break;
|
||||
|
||||
case DNS_TYPE_MX:
|
||||
if (rr1->rdata.mx.pref != rr2->rdata.mx.pref)
|
||||
return false;
|
||||
|
||||
if (str_casecmp(rr1->rdata.mx.exchange,
|
||||
rr2->rdata.mx.exchange))
|
||||
return false;
|
||||
|
||||
break;
|
||||
|
||||
case DNS_TYPE_AAAA:
|
||||
if (memcmp(rr1->rdata.aaaa.addr, rr2->rdata.aaaa.addr, 16))
|
||||
return false;
|
||||
|
||||
break;
|
||||
|
||||
case DNS_TYPE_SRV:
|
||||
if (rr1->rdata.srv.pri != rr2->rdata.srv.pri)
|
||||
return false;
|
||||
|
||||
if (rr1->rdata.srv.weight != rr2->rdata.srv.weight)
|
||||
return false;
|
||||
|
||||
if (rr1->rdata.srv.port != rr2->rdata.srv.port)
|
||||
return false;
|
||||
|
||||
if (str_casecmp(rr1->rdata.srv.target, rr2->rdata.srv.target))
|
||||
return false;
|
||||
|
||||
break;
|
||||
|
||||
case DNS_TYPE_NAPTR:
|
||||
if (rr1->rdata.naptr.order != rr2->rdata.naptr.order)
|
||||
return false;
|
||||
|
||||
if (rr1->rdata.naptr.pref != rr2->rdata.naptr.pref)
|
||||
return false;
|
||||
|
||||
/* todo check case sensitiveness */
|
||||
if (str_casecmp(rr1->rdata.naptr.flags,
|
||||
rr2->rdata.naptr.flags))
|
||||
return false;
|
||||
|
||||
/* todo check case sensitiveness */
|
||||
if (str_casecmp(rr1->rdata.naptr.services,
|
||||
rr2->rdata.naptr.services))
|
||||
return false;
|
||||
|
||||
/* todo check case sensitiveness */
|
||||
if (str_casecmp(rr1->rdata.naptr.regexp,
|
||||
rr2->rdata.naptr.regexp))
|
||||
return false;
|
||||
|
||||
/* todo check case sensitiveness */
|
||||
if (str_casecmp(rr1->rdata.naptr.replace,
|
||||
rr2->rdata.naptr.replace))
|
||||
return false;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const char *dns_rr_typename(uint16_t type)
|
||||
{
|
||||
switch (type) {
|
||||
|
||||
case DNS_TYPE_A: return "A";
|
||||
case DNS_TYPE_NS: return "NS";
|
||||
case DNS_TYPE_CNAME: return "CNAME";
|
||||
case DNS_TYPE_SOA: return "SOA";
|
||||
case DNS_TYPE_PTR: return "PTR";
|
||||
case DNS_TYPE_MX: return "MX";
|
||||
case DNS_TYPE_AAAA: return "AAAA";
|
||||
case DNS_TYPE_SRV: return "SRV";
|
||||
case DNS_TYPE_NAPTR: return "NAPTR";
|
||||
case DNS_QTYPE_IXFR: return "IXFR";
|
||||
case DNS_QTYPE_AXFR: return "AXFR";
|
||||
case DNS_QTYPE_ANY: return "ANY";
|
||||
default: return "??";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char *dns_rr_classname(uint16_t dnsclass)
|
||||
{
|
||||
switch (dnsclass) {
|
||||
|
||||
case DNS_CLASS_IN: return "IN";
|
||||
case DNS_QCLASS_ANY: return "ANY";
|
||||
default: return "??";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int dns_rr_print(struct re_printf *pf, const struct dnsrr *rr)
|
||||
{
|
||||
static const size_t w = 24;
|
||||
struct sa sa;
|
||||
size_t n, l;
|
||||
int err;
|
||||
|
||||
if (!pf || !rr)
|
||||
return EINVAL;
|
||||
|
||||
l = str_len(rr->name);
|
||||
n = (w > l) ? w - l : 0;
|
||||
|
||||
err = re_hprintf(pf, "%s.", rr->name);
|
||||
while (n--)
|
||||
err |= pf->vph(" ", 1, pf->arg);
|
||||
|
||||
err |= re_hprintf(pf, " %10lld %-4s %-7s ",
|
||||
rr->ttl,
|
||||
dns_rr_classname(rr->dnsclass),
|
||||
dns_rr_typename(rr->type));
|
||||
|
||||
switch (rr->type) {
|
||||
|
||||
case DNS_TYPE_A:
|
||||
sa_set_in(&sa, rr->rdata.a.addr, 0);
|
||||
err |= re_hprintf(pf, "%j", &sa);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_NS:
|
||||
err |= re_hprintf(pf, "%s.", rr->rdata.ns.nsdname);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_CNAME:
|
||||
err |= re_hprintf(pf, "%s.", rr->rdata.cname.cname);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_SOA:
|
||||
err |= re_hprintf(pf, "%s. %s. %u %u %u %u %u",
|
||||
rr->rdata.soa.mname,
|
||||
rr->rdata.soa.rname,
|
||||
rr->rdata.soa.serial,
|
||||
rr->rdata.soa.refresh,
|
||||
rr->rdata.soa.retry,
|
||||
rr->rdata.soa.expire,
|
||||
rr->rdata.soa.ttlmin);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_PTR:
|
||||
err |= re_hprintf(pf, "%s.", rr->rdata.ptr.ptrdname);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_MX:
|
||||
err |= re_hprintf(pf, "%3u %s.", rr->rdata.mx.pref,
|
||||
rr->rdata.mx.exchange);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_AAAA:
|
||||
sa_set_in6(&sa, rr->rdata.aaaa.addr, 0);
|
||||
err |= re_hprintf(pf, "%j", &sa);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_SRV:
|
||||
err |= re_hprintf(pf, "%3u %3u %u %s.",
|
||||
rr->rdata.srv.pri,
|
||||
rr->rdata.srv.weight,
|
||||
rr->rdata.srv.port,
|
||||
rr->rdata.srv.target);
|
||||
break;
|
||||
|
||||
case DNS_TYPE_NAPTR:
|
||||
err |= re_hprintf(pf, "%3u %3u \"%s\" \"%s\" \"%s\" %s.",
|
||||
rr->rdata.naptr.order,
|
||||
rr->rdata.naptr.pref,
|
||||
rr->rdata.naptr.flags,
|
||||
rr->rdata.naptr.services,
|
||||
rr->rdata.naptr.regexp,
|
||||
rr->rdata.naptr.replace);
|
||||
break;
|
||||
|
||||
default:
|
||||
err |= re_hprintf(pf, "?");
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
146
src/dns/rrlist.c
Normal file
146
src/dns/rrlist.c
Normal file
|
@ -0,0 +1,146 @@
|
|||
/**
|
||||
* @file rrlist.c DNS Resource Records list
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <re_types.h>
|
||||
#include <re_list.h>
|
||||
#include <re_mbuf.h>
|
||||
#include <re_fmt.h>
|
||||
#include <re_dns.h>
|
||||
|
||||
|
||||
enum {
|
||||
CNAME_RECURSE_MAX = 16,
|
||||
};
|
||||
|
||||
|
||||
static bool std_sort_handler(struct le *le1, struct le *le2, void *arg)
|
||||
{
|
||||
struct dnsrr *rr1 = le1->data;
|
||||
struct dnsrr *rr2 = le2->data;
|
||||
const uint16_t type = *(uint16_t *)arg;
|
||||
|
||||
if (type != rr1->type)
|
||||
return type != rr2->type;
|
||||
|
||||
if (type != rr2->type)
|
||||
return true;
|
||||
|
||||
switch (type) {
|
||||
|
||||
case DNS_TYPE_MX:
|
||||
return rr1->rdata.mx.pref <= rr2->rdata.mx.pref;
|
||||
|
||||
case DNS_TYPE_SRV:
|
||||
if (rr1->rdata.srv.pri == rr2->rdata.srv.pri) {
|
||||
|
||||
if (rr1->rdata.srv.weight)
|
||||
return 0 != rr2->rdata.srv.weight;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return rr1->rdata.srv.pri < rr2->rdata.srv.pri;
|
||||
|
||||
case DNS_TYPE_NAPTR:
|
||||
if (rr1->rdata.naptr.order == rr2->rdata.naptr.order)
|
||||
return rr1->rdata.naptr.pref <= rr2->rdata.naptr.pref;
|
||||
|
||||
return rr1->rdata.naptr.order < rr2->rdata.naptr.order;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void dns_rrlist_sort(struct list *rrl, uint16_t type)
|
||||
{
|
||||
list_sort(rrl, std_sort_handler, &type);
|
||||
/* todo add SRV postprocessing for weighted load balancing. */
|
||||
}
|
||||
|
||||
|
||||
static struct dnsrr *rrlist_apply(struct list *rrl, const char *name,
|
||||
uint16_t type1, uint16_t type2,
|
||||
uint16_t dnsclass,
|
||||
bool recurse, uint32_t depth,
|
||||
dns_rrlist_h *rrlh, void *arg)
|
||||
{
|
||||
struct le *le = list_head(rrl);
|
||||
|
||||
if (depth > CNAME_RECURSE_MAX)
|
||||
return NULL;
|
||||
|
||||
while (le) {
|
||||
|
||||
struct dnsrr *rr = le->data;
|
||||
|
||||
le = le->next;
|
||||
|
||||
if (name && str_casecmp(name, rr->name))
|
||||
continue;
|
||||
|
||||
if (type1 != DNS_QTYPE_ANY && type2 != DNS_QTYPE_ANY &&
|
||||
rr->type != type1 && rr->type != type2 &&
|
||||
(rr->type != DNS_TYPE_CNAME || !recurse))
|
||||
continue;
|
||||
|
||||
if (dnsclass != DNS_QCLASS_ANY && rr->dnsclass != dnsclass)
|
||||
continue;
|
||||
|
||||
if (!rrlh || rrlh(rr, arg))
|
||||
return rr;
|
||||
|
||||
if (recurse &&
|
||||
DNS_QTYPE_ANY != type1 && DNS_QTYPE_ANY != type2 &&
|
||||
DNS_TYPE_CNAME != type1 && DNS_TYPE_CNAME != type2 &&
|
||||
DNS_TYPE_CNAME == rr->type) {
|
||||
rr = rrlist_apply(rrl, rr->rdata.cname.cname, type1,
|
||||
type2, dnsclass, recurse, ++depth,
|
||||
rrlh, arg);
|
||||
if (rr)
|
||||
return rr;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
struct dnsrr *dns_rrlist_apply(struct list *rrl, const char *name,
|
||||
uint16_t type, uint16_t dnsclass,
|
||||
bool recurse, dns_rrlist_h *rrlh, void *arg)
|
||||
{
|
||||
return rrlist_apply(rrl, name, type, type, dnsclass,
|
||||
recurse, 0, rrlh, arg);
|
||||
}
|
||||
|
||||
|
||||
struct dnsrr *dns_rrlist_apply2(struct list *rrl, const char *name,
|
||||
uint16_t type1, uint16_t type2,
|
||||
uint16_t dnsclass, bool recurse,
|
||||
dns_rrlist_h *rrlh, void *arg)
|
||||
{
|
||||
return rrlist_apply(rrl, name, type1, type2, dnsclass,
|
||||
recurse, 0, rrlh, arg);
|
||||
}
|
||||
|
||||
|
||||
static bool find_handler(struct dnsrr *rr, void *arg)
|
||||
{
|
||||
uint16_t type = *(uint16_t *)arg;
|
||||
|
||||
return rr->type == type;
|
||||
}
|
||||
|
||||
|
||||
struct dnsrr *dns_rrlist_find(struct list *rrl, const char *name,
|
||||
uint16_t type, uint16_t dnsclass, bool recurse)
|
||||
{
|
||||
return rrlist_apply(rrl, name, type, type, dnsclass,
|
||||
recurse, 0, find_handler, &type);
|
||||
}
|
82
src/dns/symbian/srv.cpp
Normal file
82
src/dns/symbian/srv.cpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* @file srv.cpp Get DNS Server IP code for Symbian OS
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <es_sock.h>
|
||||
#include <in_sock.h>
|
||||
|
||||
|
||||
extern "C" {
|
||||
#include <re_types.h>
|
||||
#include <re_fmt.h>
|
||||
#include <re_list.h>
|
||||
#include <re_sa.h>
|
||||
#include <re_net.h>
|
||||
#include <re_dns.h>
|
||||
extern int get_symbiandns(struct sa *nsv, uint32_t *n);
|
||||
}
|
||||
|
||||
|
||||
int get_symbiandns(struct sa *nsv, uint32_t *n)
|
||||
{
|
||||
RSocketServ serv;
|
||||
RSocket sock;
|
||||
uint32_t i = 0;
|
||||
int ret;
|
||||
|
||||
if (!nsv || !n || !*n)
|
||||
return EINVAL;
|
||||
|
||||
ret = serv.Connect();
|
||||
if (KErrNone != ret)
|
||||
return kerr2errno(ret);
|
||||
ret = sock.Open(serv, KAfInet, KSockStream, KProtocolInetTcp);
|
||||
if (KErrNone != ret) {
|
||||
serv.Close();
|
||||
return kerr2errno(ret);
|
||||
}
|
||||
sock.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl);
|
||||
|
||||
TPckgBuf<TSoInetInterfaceInfo> ifinfo;
|
||||
while (sock.GetOpt(KSoInetNextInterface, KSolInetIfCtrl,
|
||||
ifinfo)==KErrNone) {
|
||||
struct sa sa;
|
||||
|
||||
if (EIfUp != ifinfo().iState)
|
||||
continue;
|
||||
|
||||
sa_set_in(&sa, ifinfo().iAddress.Address(), 0);
|
||||
|
||||
if (sa_is_loopback(&sa))
|
||||
continue;
|
||||
|
||||
if (sa_is_linklocal(&sa))
|
||||
continue;
|
||||
|
||||
if (ifinfo().iNameSer1.Address()) {
|
||||
sa_set_in(&nsv[i], ifinfo().iNameSer1.Address(),
|
||||
DNS_PORT);
|
||||
++i;
|
||||
}
|
||||
|
||||
if (i >= *n)
|
||||
break;
|
||||
|
||||
if (ifinfo().iNameSer2.Address()) {
|
||||
sa_set_in(&nsv[i], ifinfo().iNameSer2.Address(),
|
||||
DNS_PORT);
|
||||
++i;
|
||||
}
|
||||
|
||||
if (i >= *n)
|
||||
break;
|
||||
}
|
||||
|
||||
sock.Close();
|
||||
serv.Close();
|
||||
|
||||
*n = i;
|
||||
|
||||
return 0;
|
||||
}
|
101
src/dns/win32/srv.c
Normal file
101
src/dns/win32/srv.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
/**
|
||||
* @file win32/srv.c Get DNS Server IP code for Windows
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <winsock2.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <io.h>
|
||||
#include <re_types.h>
|
||||
#include <re_fmt.h>
|
||||
#include <re_mbuf.h>
|
||||
#include <re_list.h>
|
||||
#include <re_sa.h>
|
||||
#include <re_dns.h>
|
||||
#include "../dns.h"
|
||||
|
||||
|
||||
#define DEBUG_MODULE "win32/srv"
|
||||
#define DEBUG_LEVEL 5
|
||||
#include <re_dbg.h>
|
||||
|
||||
|
||||
int get_windns(char *domain, size_t dsize, struct sa *srvv, uint32_t *n)
|
||||
{
|
||||
FIXED_INFO * FixedInfo = NULL;
|
||||
ULONG ulOutBufLen;
|
||||
DWORD dwRetVal;
|
||||
IP_ADDR_STRING * pIPAddr;
|
||||
HANDLE hLib;
|
||||
union {
|
||||
FARPROC proc;
|
||||
DWORD (WINAPI *_GetNetworkParams)(FIXED_INFO*, DWORD*);
|
||||
} u;
|
||||
uint32_t i;
|
||||
int err;
|
||||
|
||||
if (!srvv || !n || !*n)
|
||||
return EINVAL;
|
||||
|
||||
hLib = LoadLibrary(TEXT("iphlpapi.dll"));
|
||||
if (!hLib)
|
||||
return ENOSYS;
|
||||
|
||||
u.proc = GetProcAddress(hLib, TEXT("GetNetworkParams"));
|
||||
if (!u.proc) {
|
||||
err = ENOSYS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof( FIXED_INFO ));
|
||||
ulOutBufLen = sizeof( FIXED_INFO );
|
||||
|
||||
if (ERROR_BUFFER_OVERFLOW == (*u._GetNetworkParams)(FixedInfo,
|
||||
&ulOutBufLen)) {
|
||||
GlobalFree( FixedInfo );
|
||||
FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, ulOutBufLen);
|
||||
}
|
||||
|
||||
if ((dwRetVal = (*u._GetNetworkParams)( FixedInfo, &ulOutBufLen ))) {
|
||||
DEBUG_WARNING("couldn't get network params (%d)\n", dwRetVal);
|
||||
err = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
str_ncpy(domain, FixedInfo->DomainName, dsize);
|
||||
|
||||
#if 0
|
||||
printf( "Host Name: %s\n", FixedInfo->HostName);
|
||||
printf( "Domain Name: %s\n", FixedInfo->DomainName);
|
||||
printf( "DNS Servers:\n" );
|
||||
printf( "\t%s\n", FixedInfo->DnsServerList.IpAddress.String );
|
||||
#endif
|
||||
|
||||
i = 0;
|
||||
pIPAddr = &FixedInfo->DnsServerList;
|
||||
while (pIPAddr && strlen(pIPAddr->IpAddress.String) > 0) {
|
||||
err = sa_set_str(&srvv[i], pIPAddr->IpAddress.String,
|
||||
DNS_PORT);
|
||||
if (err) {
|
||||
DEBUG_WARNING("sa_set_str: %s (%s)\n",
|
||||
pIPAddr->IpAddress.String,
|
||||
strerror(err));
|
||||
}
|
||||
DEBUG_INFO("dns ip %u: %j\n", i, &srvv[i]);
|
||||
++i;
|
||||
pIPAddr = pIPAddr ->Next;
|
||||
|
||||
if (i >= *n)
|
||||
break;
|
||||
}
|
||||
|
||||
*n = i;
|
||||
DEBUG_INFO("got %u nameservers\n", i);
|
||||
err = i>0 ? 0 : ENOENT;
|
||||
|
||||
out:
|
||||
if (FixedInfo)
|
||||
GlobalFree(FixedInfo);
|
||||
FreeLibrary(hLib);
|
||||
return err;
|
||||
}
|
29
src/fmt/ch.c
Normal file
29
src/fmt/ch.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* @file ch.c Character format functions
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <re_types.h>
|
||||
#include <re_fmt.h>
|
||||
|
||||
|
||||
/**
|
||||
* Convert a ascii hex character to binary format
|
||||
*
|
||||
* @param ch Ascii hex character
|
||||
*
|
||||
* @return Binary value
|
||||
*/
|
||||
uint8_t ch_hex(char ch)
|
||||
{
|
||||
if ('0' <= ch && ch <= '9')
|
||||
return ch - '0';
|
||||
|
||||
else if ('A' <= ch && ch <= 'F')
|
||||
return ch - 'A' + 10;
|
||||
|
||||
else if ('a' <= ch && ch <= 'f')
|
||||
return ch - 'a' + 10;
|
||||
|
||||
return 0;
|
||||
}
|
57
src/fmt/hexdump.c
Normal file
57
src/fmt/hexdump.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* @file hexdump.c Hexadecimal dumping
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <re_types.h>
|
||||
#include <re_fmt.h>
|
||||
|
||||
|
||||
/**
|
||||
* Hexadecimal dump of binary buffer. Similar output to HEXDUMP(1)
|
||||
*
|
||||
* @param f File stream for output (e.g. stderr, stdout)
|
||||
* @param p Pointer to data
|
||||
* @param len Number of bytes
|
||||
*/
|
||||
void hexdump(FILE *f, const void *p, size_t len)
|
||||
{
|
||||
const uint8_t *buf = p;
|
||||
uint32_t j;
|
||||
size_t i;
|
||||
|
||||
if (!f || !buf)
|
||||
return;
|
||||
|
||||
for (i=0; i < len; i += 16) {
|
||||
|
||||
(void)re_fprintf(f, "%08x ", i);
|
||||
|
||||
for (j=0; j<16; j++) {
|
||||
const size_t pos = i+j;
|
||||
if (pos < len)
|
||||
(void)re_fprintf(f, " %02x", buf[pos]);
|
||||
else
|
||||
(void)re_fprintf(f, " ");
|
||||
|
||||
if (j == 7)
|
||||
(void)re_fprintf(f, " ");
|
||||
}
|
||||
|
||||
(void)re_fprintf(f, " |");
|
||||
|
||||
for (j=0; j<16; j++) {
|
||||
const size_t pos = i+j;
|
||||
uint8_t v;
|
||||
if (pos >= len)
|
||||
break;
|
||||
v = buf[pos];
|
||||
(void)re_fprintf(f, "%c", isprint(v) ? v : '.');
|
||||
if (j == 7)
|
||||
(void)re_fprintf(f, " ");
|
||||
}
|
||||
|
||||
(void)re_fprintf(f, "|\n");
|
||||
}
|
||||
}
|
13
src/fmt/mod.mk
Normal file
13
src/fmt/mod.mk
Normal file
|
@ -0,0 +1,13 @@
|
|||
#
|
||||
# mod.mk
|
||||
#
|
||||
|
||||
|
||||
SRCS += fmt/ch.c
|
||||
SRCS += fmt/hexdump.c
|
||||
SRCS += fmt/pl.c
|
||||
SRCS += fmt/print.c
|
||||
SRCS += fmt/prm.c
|
||||
SRCS += fmt/regex.c
|
||||
SRCS += fmt/str.c
|
||||
SRCS += fmt/time.c
|
419
src/fmt/pl.c
Normal file
419
src/fmt/pl.c
Normal file
|
@ -0,0 +1,419 @@
|
|||
/**
|
||||
* @file pl.c Pointer-length functions
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#define __EXTENSIONS__ 1
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <re_types.h>
|
||||
#include <re_mem.h>
|
||||
#include <re_mbuf.h>
|
||||
#include <re_fmt.h>
|
||||
|
||||
|
||||
/** Pointer-length NULL initialiser */
|
||||
const struct pl pl_null = {NULL, 0};
|
||||
|
||||
|
||||
/**
|
||||
* Initialise a pointer-length object from a NULL-terminated string
|
||||
*
|
||||
* @param pl Pointer-length object to be initialised
|
||||
* @param str NULL-terminated string
|
||||
*/
|
||||
void pl_set_str(struct pl *pl, const char *str)
|
||||
{
|
||||
if (!pl || !str)
|
||||
return;
|
||||
|
||||
pl->p = str;
|
||||
pl->l = strlen(str);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialise a pointer-length object from current position and
|
||||
* length of a memory buffer
|
||||
*
|
||||
* @param pl Pointer-length object to be initialised
|
||||
* @param mb Memory buffer
|
||||
*/
|
||||
void pl_set_mbuf(struct pl *pl, const struct mbuf *mb)
|
||||
{
|
||||
if (!pl || !mb)
|
||||
return;
|
||||
|
||||
pl->p = (char *)mbuf_buf(mb);
|
||||
pl->l = mbuf_get_left(mb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a pointer-length object to a numeric 32-bit value
|
||||
*
|
||||
* @param pl Pointer-length object
|
||||
*
|
||||
* @return 32-bit value
|
||||
*/
|
||||
uint32_t pl_u32(const struct pl *pl)
|
||||
{
|
||||
uint32_t v=0, mul=1;
|
||||
const char *p;
|
||||
|
||||
if (!pl || !pl->p)
|
||||
return 0;
|
||||
|
||||
p = &pl->p[pl->l];
|
||||
while (p > pl->p) {
|
||||
const uint8_t c = *--p - '0';
|
||||
if (c > 9)
|
||||
return 0;
|
||||
v += mul * c;
|
||||
mul *= 10;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a hex pointer-length object to a numeric 32-bit value
|
||||
*
|
||||
* @param pl Pointer-length object
|
||||
*
|
||||
* @return 32-bit value
|
||||
*/
|
||||
uint32_t pl_x32(const struct pl *pl)
|
||||
{
|
||||
uint32_t v=0, mul=1;
|
||||
const char *p;
|
||||
|
||||
if (!pl || !pl->p)
|
||||
return 0;
|
||||
|
||||
p = &pl->p[pl->l];
|
||||
while (p > pl->p) {
|
||||
|
||||
const char ch = *--p;
|
||||
uint8_t c;
|
||||
|
||||
if ('0' <= ch && ch <= '9')
|
||||
c = ch - '0';
|
||||
else if ('A' <= ch && ch <= 'F')
|
||||
c = ch - 'A' + 10;
|
||||
else if ('a' <= ch && ch <= 'f')
|
||||
c = ch - 'a' + 10;
|
||||
else
|
||||
return 0;
|
||||
|
||||
v += mul * c;
|
||||
mul *= 16;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a pointer-length object to a numeric 64-bit value
|
||||
*
|
||||
* @param pl Pointer-length object
|
||||
*
|
||||
* @return 64-bit value
|
||||
*/
|
||||
uint64_t pl_u64(const struct pl *pl)
|
||||
{
|
||||
uint64_t v=0, mul=1;
|
||||
const char *p;
|
||||
|
||||
if (!pl || !pl->p)
|
||||
return 0;
|
||||
|
||||
p = &pl->p[pl->l];
|
||||
while (p > pl->p) {
|
||||
const uint8_t c = *--p - '0';
|
||||
if (c > 9)
|
||||
return 0;
|
||||
v += mul * c;
|
||||
mul *= 10;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if pointer-length object is set
|
||||
*
|
||||
* @param pl Pointer-length object
|
||||
*
|
||||
* @return true if set, false if not set
|
||||
*/
|
||||
bool pl_isset(const struct pl *pl)
|
||||
{
|
||||
return pl ? pl->p && pl->l : false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy a pointer-length object to a NULL-terminated string
|
||||
*
|
||||
* @param pl Pointer-length object
|
||||
* @param str Buffer for NULL-terminated string
|
||||
* @param size Size of buffer
|
||||
*
|
||||
* @return 0 if success, otherwise errorcode
|
||||
*/
|
||||
int pl_strcpy(const struct pl *pl, char *str, size_t size)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if (!pl || !pl->p || !str || !size)
|
||||
return EINVAL;
|
||||
|
||||
len = min(pl->l, size-1);
|
||||
|
||||
memcpy(str, pl->p, len);
|
||||
str[len] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Duplicate a pointer-length object to a NULL-terminated string
|
||||
*
|
||||
* @param dst Pointer to destination string (set on return)
|
||||
* @param src Source pointer-length object
|
||||
*
|
||||
* @return 0 if success, otherwise errorcode
|
||||
*/
|
||||
int pl_strdup(char **dst, const struct pl *src)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (!dst || !src || !src->p)
|
||||
return EINVAL;
|
||||
|
||||
p = mem_alloc(src->l+1, NULL);
|
||||
if (!p)
|
||||
return ENOMEM;
|
||||
|
||||
memcpy(p, src->p, src->l);
|
||||
p[src->l] = '\0';
|
||||
|
||||
*dst = p;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Duplicate a pointer-length object to a new pointer-length object
|
||||
*
|
||||
* @param dst Destination pointer-length object (set on return)
|
||||
* @param src Source pointer-length object
|
||||
*
|
||||
* @return 0 if success, otherwise errorcode
|
||||
*/
|
||||
int pl_dup(struct pl *dst, const struct pl *src)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (!dst || !src || !src->p)
|
||||
return EINVAL;
|
||||
|
||||
p = mem_alloc(src->l, NULL);
|
||||
if (!p)
|
||||
return ENOMEM;
|
||||
|
||||
memcpy(p, src->p, src->l);
|
||||
|
||||
dst->p = p;
|
||||
dst->l = src->l;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare a pointer-length object with a NULL-terminated string
|
||||
* (case-sensitive)
|
||||
*
|
||||
* @param pl Pointer-length object
|
||||
* @param str NULL-terminated string
|
||||
*
|
||||
* @return 0 if match, otherwise errorcode
|
||||
*/
|
||||
int pl_strcmp(const struct pl *pl, const char *str)
|
||||
{
|
||||
struct pl s;
|
||||
|
||||
if (!pl || !str)
|
||||
return EINVAL;
|
||||
|
||||
pl_set_str(&s, str);
|
||||
|
||||
return pl_cmp(pl, &s);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare a pointer-length object with a NULL-terminated string
|
||||
* (case-insensitive)
|
||||
*
|
||||
* @param pl Pointer-length object
|
||||
* @param str NULL-terminated string
|
||||
*
|
||||
* @return 0 if match, otherwise errorcode
|
||||
*/
|
||||
int pl_strcasecmp(const struct pl *pl, const char *str)
|
||||
{
|
||||
struct pl s;
|
||||
|
||||
if (!pl || !str)
|
||||
return EINVAL;
|
||||
|
||||
pl_set_str(&s, str);
|
||||
|
||||
return pl_casecmp(pl, &s);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare two pointer-length objects (case-sensitive)
|
||||
*
|
||||
* @param pl1 First pointer-length object
|
||||
* @param pl2 Second pointer-length object
|
||||
*
|
||||
* @return 0 if match, otherwise errorcode
|
||||
*/
|
||||
int pl_cmp(const struct pl *pl1, const struct pl *pl2)
|
||||
{
|
||||
if (!pl1 || !pl2)
|
||||
return EINVAL;
|
||||
|
||||
/* Different length -> no match */
|
||||
if (pl1->l != pl2->l)
|
||||
return EINVAL;
|
||||
|
||||
/*
|
||||
* ~35% speed increase for fmt/pl test
|
||||
*/
|
||||
|
||||
/* The two pl's are the same */
|
||||
if (pl1 == pl2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Two different pl's pointing to same string */
|
||||
if (pl1->p == pl2->p && pl1->l == pl2->l) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0 == memcmp(pl1->p, pl2->p, pl1->l) ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
|
||||
#ifndef HAVE_STRINGS_H
|
||||
static int casecmp(const struct pl *pl, const char *str)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
#define LOWER(d) ((d) | 0x20202020)
|
||||
const uint32_t *p1 = (uint32_t *)pl->p;
|
||||
const uint32_t *p2 = (uint32_t *)str;
|
||||
const size_t len = pl->l & ~0x3;
|
||||
|
||||
/* Skip any unaligned pointers */
|
||||
if (((size_t)pl->p) & (sizeof(void *) - 1))
|
||||
goto next;
|
||||
if (((size_t)str) & (sizeof(void *) - 1))
|
||||
goto next;
|
||||
|
||||
/* Compare word-wise */
|
||||
for (; i<len; i+=4) {
|
||||
if (LOWER(*p1++) != LOWER(*p2++))
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
next:
|
||||
/* Compare byte-wise */
|
||||
for (; i<pl->l; i++) {
|
||||
if (tolower(pl->p[i]) != tolower(str[i]))
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Compare two pointer-length objects (case-insensitive)
|
||||
*
|
||||
* @param pl1 First pointer-length object
|
||||
* @param pl2 Second pointer-length object
|
||||
*
|
||||
* @return 0 if match, otherwise errorcode
|
||||
*/
|
||||
int pl_casecmp(const struct pl *pl1, const struct pl *pl2)
|
||||
{
|
||||
if (!pl1 || !pl2)
|
||||
return EINVAL;
|
||||
|
||||
/* Different length -> no match */
|
||||
if (pl1->l != pl2->l)
|
||||
return EINVAL;
|
||||
|
||||
/*
|
||||
* ~35% speed increase for fmt/pl test
|
||||
*/
|
||||
|
||||
/* The two pl's are the same */
|
||||
if (pl1 == pl2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Two different pl's pointing to same string */
|
||||
if (pl1->p == pl2->p && pl1->l == pl2->l) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_STRINGS_H
|
||||
return 0 == strncasecmp(pl1->p, pl2->p, pl1->l) ? 0 : EINVAL;
|
||||
#else
|
||||
return casecmp(pl1, pl2->p);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Locate character in pointer-length string
|
||||
*
|
||||
* @param pl Pointer-length string
|
||||
* @param c Character to locate
|
||||
*
|
||||
* @return Pointer to first char if found, otherwise NULL
|
||||
*/
|
||||
const char *pl_strchr(const struct pl *pl, char c)
|
||||
{
|
||||
const char *p, *end;
|
||||
|
||||
if (!pl)
|
||||
return NULL;
|
||||
|
||||
end = pl->p + pl->l;
|
||||
for (p = pl->p; p < end; p++) {
|
||||
if (*p == c)
|
||||
return p;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
759
src/fmt/print.c
Normal file
759
src/fmt/print.c
Normal file
|
@ -0,0 +1,759 @@
|
|||
/**
|
||||
* @file print.c Formatted printing
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <re_types.h>
|
||||
#include <re_sa.h>
|
||||
#include <re_fmt.h>
|
||||
#include <re_mem.h>
|
||||
#include <math.h>
|
||||
#ifdef _MSC_VER
|
||||
#include <float.h>
|
||||
#define isinf(d) (!_finite(d))
|
||||
#define isnan(d) _isnan(d)
|
||||
#endif
|
||||
#ifdef SOLARIS
|
||||
#include <ieeefp.h>
|
||||
#undef isinf
|
||||
#define isinf(a) (fpclass((a)) == FP_NINF || fpclass((a)) == FP_PINF)
|
||||
#undef isnan
|
||||
#define isnan(a) isnand((a))
|
||||
#endif
|
||||
|
||||
|
||||
enum length_modifier {
|
||||
LENMOD_NONE = 0,
|
||||
LENMOD_LONG = 1,
|
||||
LENMOD_LONG_LONG = 2,
|
||||
LENMOD_SIZE = 42,
|
||||
};
|
||||
|
||||
enum {
|
||||
DEC_SIZE = 42,
|
||||
NUM_SIZE = 64
|
||||
};
|
||||
|
||||
static const char prfx_neg[] = "-";
|
||||
static const char prfx_hex[] = "0x";
|
||||
static const char str_nil[] = "(nil)";
|
||||
|
||||
|
||||
static int write_padded(const char *p, size_t sz, size_t pad, char pch,
|
||||
bool plr, const char *prfx, re_vprintf_h *vph,
|
||||
void *arg)
|
||||
{
|
||||
const size_t prfx_len = str_len(prfx);
|
||||
int err = 0;
|
||||
|
||||
pad -= MIN(pad, prfx_len);
|
||||
|
||||
if (prfx && pch == '0')
|
||||
err |= vph(prfx, prfx_len, arg);
|
||||
|
||||
while (!plr && (pad-- > sz))
|
||||
err |= vph(&pch, 1, arg);
|
||||
|
||||
if (prfx && pch != '0')
|
||||
err |= vph(prfx, prfx_len, arg);
|
||||
|
||||
if (p && sz)
|
||||
err |= vph(p, sz, arg);
|
||||
|
||||
while (plr && pad-- > sz)
|
||||
err |= vph(&pch, 1, arg);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t local_itoa(char *buf, uint64_t n, uint8_t base, bool uc)
|
||||
{
|
||||
char c, *p = buf + NUM_SIZE;
|
||||
uint32_t len = 1;
|
||||
const char a = uc ? 'A' : 'a';
|
||||
|
||||
*--p = '\0';
|
||||
do {
|
||||
const uint64_t dv = n / base;
|
||||
const uint64_t mul = dv * base;
|
||||
|
||||
c = (char)(n - mul);
|
||||
|
||||
if (c < 10)
|
||||
*--p = '0' + c;
|
||||
else
|
||||
*--p = a + (c - 10);
|
||||
|
||||
n = dv;
|
||||
++len;
|
||||
|
||||
} while (n != 0);
|
||||
|
||||
memmove(buf, p, len);
|
||||
|
||||
return len - 1;
|
||||
}
|
||||
|
||||
|
||||
static size_t local_ftoa(char *buf, double n, size_t dp)
|
||||
{
|
||||
char *p = buf;
|
||||
long long a = (long long)n;
|
||||
double b = n - (double)a;
|
||||
|
||||
b = (b < 0) ? -b : b;
|
||||
|
||||
/* integral part */
|
||||
p += local_itoa(p, (a < 0) ? -a : a, 10, false);
|
||||
|
||||
*p++ = '.';
|
||||
|
||||
/* decimal digits */
|
||||
while (dp--) {
|
||||
char v;
|
||||
|
||||
b *= 10;
|
||||
v = (char)b;
|
||||
b -= v;
|
||||
|
||||
*p++ = '0' + (char)v;
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
|
||||
return p - buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print a formatted string
|
||||
*
|
||||
* Extensions:
|
||||
*
|
||||
* %b (char *, size_t) Buffer string with pointer and length
|
||||
* %r (struct pl) Pointer-length object
|
||||
* %w (uint8_t *, size_t) Binary buffer to hexadecimal format
|
||||
* %j (struct sa *) Socket address - address part only
|
||||
* %J (struct sa *) Socket address and port - like 1.2.3.4:1234
|
||||
* %H (re_printf_h *, void *) Print handler with argument
|
||||
* %v (char *fmt, va_list *) Variable argument list
|
||||
*
|
||||
* Reserved for the future:
|
||||
*
|
||||
* %k
|
||||
* %y
|
||||
*
|
||||
*/
|
||||
int re_vhprintf(const char *fmt, va_list ap, re_vprintf_h *vph, void *arg)
|
||||
{
|
||||
uint8_t base, *bptr;
|
||||
char pch, ch, num[NUM_SIZE], addr[64];
|
||||
enum length_modifier lenmod = LENMOD_NONE;
|
||||
struct re_printf pf;
|
||||
bool fm = false, plr = false;
|
||||
const struct pl *pl;
|
||||
size_t pad = 0, fpad = -1, len, i;
|
||||
const char *str, *p = fmt, *p0 = fmt;
|
||||
const struct sa *sa;
|
||||
re_printf_h *ph;
|
||||
void *ph_arg;
|
||||
va_list *apl;
|
||||
int err = 0;
|
||||
void *ptr;
|
||||
uint64_t n;
|
||||
int64_t sn;
|
||||
bool uc = false;
|
||||
double dbl;
|
||||
|
||||
if (!fmt || !vph)
|
||||
return EINVAL;
|
||||
|
||||
pf.vph = vph;
|
||||
pf.arg = arg;
|
||||
|
||||
for (;*p && !err; p++) {
|
||||
|
||||
if (!fm) {
|
||||
if (*p != '%')
|
||||
continue;
|
||||
|
||||
pch = ' ';
|
||||
plr = false;
|
||||
pad = 0;
|
||||
fpad = -1;
|
||||
lenmod = LENMOD_NONE;
|
||||
uc = false;
|
||||
|
||||
if (p > p0)
|
||||
err |= vph(p0, p - p0, arg);
|
||||
|
||||
fm = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
fm = false;
|
||||
base = 10;
|
||||
|
||||
switch (*p) {
|
||||
|
||||
case '-':
|
||||
plr = true;
|
||||
fm = true;
|
||||
break;
|
||||
|
||||
case '.':
|
||||
fpad = pad;
|
||||
pad = 0;
|
||||
fm = true;
|
||||
break;
|
||||
|
||||
case '%':
|
||||
ch = '%';
|
||||
|
||||
err |= vph(&ch, 1, arg);
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
str = va_arg(ap, const char *);
|
||||
len = va_arg(ap, size_t);
|
||||
|
||||
err |= write_padded(str, str ? len : 0, pad, ' ',
|
||||
plr, NULL, vph, arg);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
ch = va_arg(ap, int);
|
||||
|
||||
err |= write_padded(&ch, 1, pad, ' ', plr, NULL,
|
||||
vph, arg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'i':
|
||||
switch (lenmod) {
|
||||
|
||||
case LENMOD_SIZE:
|
||||
sn = va_arg(ap, ssize_t);
|
||||
break;
|
||||
|
||||
default:
|
||||
case LENMOD_LONG_LONG:
|
||||
sn = va_arg(ap, signed long long);
|
||||
break;
|
||||
|
||||
case LENMOD_LONG:
|
||||
sn = va_arg(ap, signed long);
|
||||
break;
|
||||
|
||||
case LENMOD_NONE:
|
||||
sn = va_arg(ap, signed);
|
||||
break;
|
||||
}
|
||||
|
||||
len = local_itoa(num, (sn < 0) ? -sn : sn, base,
|
||||
false);
|
||||
|
||||
err |= write_padded(num, len, pad,
|
||||
plr ? ' ' : pch, plr,
|
||||
(sn < 0) ? prfx_neg : NULL,
|
||||
vph, arg);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
case 'F':
|
||||
dbl = va_arg(ap, double);
|
||||
|
||||
if (fpad == (size_t)-1) {
|
||||
fpad = pad;
|
||||
pad = 0;
|
||||
}
|
||||
|
||||
if (isinf(dbl)) {
|
||||
err |= write_padded("inf", 3, fpad,
|
||||
' ', plr, NULL, vph, arg);
|
||||
}
|
||||
else if (isnan(dbl)) {
|
||||
err |= write_padded("nan", 3, fpad,
|
||||
' ', plr, NULL, vph, arg);
|
||||
}
|
||||
else {
|
||||
len = local_ftoa(num, dbl,
|
||||
pad ? min(pad, DEC_SIZE) : 6);
|
||||
|
||||
err |= write_padded(num, len, fpad,
|
||||
plr ? ' ' : pch, plr,
|
||||
(dbl<0) ? prfx_neg : NULL,
|
||||
vph, arg);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
ph = va_arg(ap, re_printf_h *);
|
||||
ph_arg = va_arg(ap, void *);
|
||||
|
||||
if (ph)
|
||||
err |= ph(&pf, ph_arg);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
++lenmod;
|
||||
fm = true;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
ptr = va_arg(ap, void *);
|
||||
|
||||
if (ptr) {
|
||||
len = local_itoa(num, (unsigned long int)ptr,
|
||||
16, false);
|
||||
err |= write_padded(num, len, pad,
|
||||
plr ? ' ' : pch, plr,
|
||||
prfx_hex, vph, arg);
|
||||
}
|
||||
else {
|
||||
err |= write_padded(str_nil,
|
||||
sizeof(str_nil) - 1,
|
||||
pad, ' ', plr, NULL,
|
||||
vph, arg);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
pl = va_arg(ap, const struct pl *);
|
||||
|
||||
err |= write_padded(pl ? pl->p : NULL,
|
||||
(pl && pl->p) ? pl->l : 0,
|
||||
pad, ' ', plr, NULL, vph, arg);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
str = va_arg(ap, const char *);
|
||||
err |= write_padded(str, str_len(str), pad,
|
||||
' ', plr, NULL, vph, arg);
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
uc = true;
|
||||
/*@fallthrough@*/
|
||||
case 'x':
|
||||
base = 16;
|
||||
/*@fallthrough@*/
|
||||
case 'u':
|
||||
switch (lenmod) {
|
||||
|
||||
case LENMOD_SIZE:
|
||||
n = va_arg(ap, size_t);
|
||||
break;
|
||||
|
||||
default:
|
||||
case LENMOD_LONG_LONG:
|
||||
n = va_arg(ap, unsigned long long);
|
||||
break;
|
||||
|
||||
case LENMOD_LONG:
|
||||
n = va_arg(ap, unsigned long);
|
||||
break;
|
||||
|
||||
case LENMOD_NONE:
|
||||
n = va_arg(ap, unsigned);
|
||||
break;
|
||||
}
|
||||
|
||||
len = local_itoa(num, n, base, uc);
|
||||
|
||||
err |= write_padded(num, len, pad,
|
||||
plr ? ' ' : pch, plr, NULL,
|
||||
vph, arg);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
str = va_arg(ap, char *);
|
||||
apl = va_arg(ap, va_list *);
|
||||
|
||||
if (!str || !apl)
|
||||
break;
|
||||
|
||||
err |= re_vhprintf(str, *apl, vph, arg);
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
uc = true;
|
||||
/*@fallthrough@*/
|
||||
case 'w':
|
||||
bptr = va_arg(ap, uint8_t *);
|
||||
len = va_arg(ap, size_t);
|
||||
|
||||
len = bptr ? len : 0;
|
||||
pch = plr ? ' ' : pch;
|
||||
|
||||
while (!plr && pad-- > (len * 2))
|
||||
err |= vph(&pch, 1, arg);
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
const uint8_t v = *bptr++;
|
||||
uint32_t l = local_itoa(num, v, 16, uc);
|
||||
err |= write_padded(num, l, 2, '0',
|
||||
false, NULL, vph, arg);
|
||||
}
|
||||
|
||||
while (plr && pad-- > (len * 2))
|
||||
err |= vph(&pch, 1, arg);
|
||||
|
||||
break;
|
||||
|
||||
case 'z':
|
||||
lenmod = LENMOD_SIZE;
|
||||
fm = true;
|
||||
break;
|
||||
|
||||
case 'j':
|
||||
sa = va_arg(ap, struct sa *);
|
||||
if (!sa)
|
||||
break;
|
||||
if (sa_ntop(sa, addr, sizeof(addr))) {
|
||||
err |= write_padded("?", 1, pad, ' ',
|
||||
plr, NULL, vph, arg);
|
||||
break;
|
||||
}
|
||||
err |= write_padded(addr, strlen(addr), pad, ' ',
|
||||
plr, NULL, vph, arg);
|
||||
break;
|
||||
|
||||
|
||||
case 'J':
|
||||
sa = va_arg(ap, struct sa *);
|
||||
if (!sa)
|
||||
break;
|
||||
if (sa_ntop(sa, addr, sizeof(addr))) {
|
||||
err |= write_padded("?", 1, pad, ' ',
|
||||
plr, NULL, vph, arg);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef HAVE_INET6
|
||||
if (AF_INET6 == sa_af(sa)) {
|
||||
ch = '[';
|
||||
err |= vph(&ch, 1, arg);
|
||||
}
|
||||
#endif
|
||||
err |= write_padded(addr, strlen(addr), pad, ' ',
|
||||
plr, NULL, vph, arg);
|
||||
#ifdef HAVE_INET6
|
||||
if (AF_INET6 == sa_af(sa)) {
|
||||
ch = ']';
|
||||
err |= vph(&ch, 1, arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
ch = ':';
|
||||
err |= vph(&ch, 1, arg);
|
||||
len = local_itoa(num, sa_port(sa), 10, false);
|
||||
err |= write_padded(num, len, pad,
|
||||
plr ? ' ' : pch, plr, NULL,
|
||||
vph, arg);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if (('0' <= *p) && (*p <= '9')) {
|
||||
if (!pad && ('0' == *p)) {
|
||||
pch = '0';
|
||||
}
|
||||
else {
|
||||
pad *= 10;
|
||||
pad += *p - '0';
|
||||
}
|
||||
fm = true;
|
||||
break;
|
||||
}
|
||||
|
||||
ch = '?';
|
||||
|
||||
err |= vph(&ch, 1, arg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!fm)
|
||||
p0 = p + 1;
|
||||
}
|
||||
|
||||
if (!fm && p > p0)
|
||||
err |= vph(p0, p - p0, arg);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static int print_handler(const char *p, size_t size, void *arg)
|
||||
{
|
||||
struct pl *pl = arg;
|
||||
|
||||
if (size > pl->l)
|
||||
return ENOMEM;
|
||||
|
||||
memcpy((void *)pl->p, p, size);
|
||||
|
||||
pl_advance(pl, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct dyn_print {
|
||||
char *str;
|
||||
char *p;
|
||||
size_t l;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
|
||||
static int print_handler_dyn(const char *p, size_t size, void *arg)
|
||||
{
|
||||
struct dyn_print *dp = arg;
|
||||
|
||||
if (size > dp->l - 1) {
|
||||
const size_t new_size = MAX(dp->size + size, dp->size * 2);
|
||||
char *str = mem_realloc(dp->str, new_size);
|
||||
if (!str)
|
||||
return ENOMEM;
|
||||
|
||||
dp->str = str;
|
||||
dp->l += new_size - dp->size;
|
||||
dp->p = dp->str + new_size - dp->l;
|
||||
dp->size = new_size;
|
||||
}
|
||||
|
||||
memcpy(dp->p, p, size);
|
||||
|
||||
dp->p += size;
|
||||
dp->l -= size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print a formatted string to a file stream, using va_list
|
||||
*
|
||||
* @param stream File stream for the output
|
||||
* @param fmt Formatted string
|
||||
* @param ap Variable-arguments list
|
||||
*
|
||||
* @return The number of characters printed, or -1 if error
|
||||
*/
|
||||
int re_vfprintf(FILE *stream, const char *fmt, va_list ap)
|
||||
{
|
||||
char buf[4096]; /* TODO: avoid static, use print_handler_dyn ? */
|
||||
struct pl pl;
|
||||
size_t n;
|
||||
|
||||
if (!stream)
|
||||
return -1;
|
||||
|
||||
pl.p = buf;
|
||||
pl.l = sizeof(buf);
|
||||
|
||||
if (0 != re_vhprintf(fmt, ap, print_handler, &pl))
|
||||
return -1;
|
||||
|
||||
n = sizeof(buf) - pl.l;
|
||||
|
||||
if (1 != fwrite(buf, n, 1, stream))
|
||||
return -1;
|
||||
|
||||
return (int)n;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print a formatted string to stdout, using va_list
|
||||
*
|
||||
* @param fmt Formatted string
|
||||
* @param ap Variable-arguments list
|
||||
*
|
||||
* @return The number of characters printed, or -1 if error
|
||||
*/
|
||||
int re_vprintf(const char *fmt, va_list ap)
|
||||
{
|
||||
return re_vfprintf(stdout, fmt, ap);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print a formatted string to a buffer, using va_list
|
||||
*
|
||||
* @param str Buffer for output string
|
||||
* @param size Size of buffer
|
||||
* @param fmt Formatted string
|
||||
* @param ap Variable-arguments list
|
||||
*
|
||||
* @return The number of characters printed, or -1 if error
|
||||
*/
|
||||
int re_vsnprintf(char *str, size_t size, const char *fmt, va_list ap)
|
||||
{
|
||||
struct pl pl;
|
||||
int err;
|
||||
|
||||
if (!str || !size)
|
||||
return -1;
|
||||
|
||||
pl.p = str;
|
||||
pl.l = size - 1;
|
||||
|
||||
err = re_vhprintf(fmt, ap, print_handler, &pl);
|
||||
|
||||
str[size - pl.l - 1] = '\0';
|
||||
|
||||
return err ? -1 : (int)(size - pl.l - 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print a formatted string to a dynamically allocated buffer, using va_list
|
||||
*
|
||||
* @param strp Pointer for output string
|
||||
* @param fmt Formatted string
|
||||
* @param ap Variable-arguments list
|
||||
*
|
||||
* @return 0 if success, otherwise errorcode
|
||||
*/
|
||||
int re_vsdprintf(char **strp, const char *fmt, va_list ap)
|
||||
{
|
||||
struct dyn_print dp;
|
||||
int err;
|
||||
|
||||
if (!strp)
|
||||
return EINVAL;
|
||||
|
||||
dp.size = 16;
|
||||
dp.str = mem_alloc(dp.size, NULL);
|
||||
if (!dp.str)
|
||||
return ENOMEM;
|
||||
|
||||
dp.p = dp.str;
|
||||
dp.l = dp.size;
|
||||
|
||||
err = re_vhprintf(fmt, ap, print_handler_dyn, &dp);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
*dp.p = '\0';
|
||||
|
||||
out:
|
||||
if (err)
|
||||
mem_deref(dp.str);
|
||||
else
|
||||
*strp = dp.str;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print a formatted string
|
||||
*
|
||||
* @param pf Print backend
|
||||
* @param fmt Formatted string
|
||||
*
|
||||
* @return 0 if success, otherwise errorcode
|
||||
*/
|
||||
int re_hprintf(struct re_printf *pf, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int err;
|
||||
|
||||
if (!pf)
|
||||
return EINVAL;
|
||||
|
||||
va_start(ap, fmt);
|
||||
err = re_vhprintf(fmt, ap, pf->vph, pf->arg);
|
||||
va_end(ap);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print a formatted string to a file stream
|
||||
*
|
||||
* @param stream File stream for output
|
||||
* @param fmt Formatted string
|
||||
*
|
||||
* @return The number of characters printed, or -1 if error
|
||||
*/
|
||||
int re_fprintf(FILE *stream, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int n;
|
||||
|
||||
va_start(ap, fmt);
|
||||
n = re_vfprintf(stream, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print a formatted string to stdout
|
||||
*
|
||||
* @param fmt Formatted string
|
||||
*
|
||||
* @return The number of characters printed, or -1 if error
|
||||
*/
|
||||
int re_printf(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int n;
|
||||
|
||||
va_start(ap, fmt);
|
||||
n = re_vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print a formatted string to a buffer
|
||||
*
|
||||
* @param str Buffer for output string
|
||||
* @param size Size of buffer
|
||||
* @param fmt Formatted string
|
||||
*
|
||||
* @return The number of characters printed, or -1 if error
|
||||
*/
|
||||
int re_snprintf(char *str, size_t size, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int n;
|
||||
|
||||
va_start(ap, fmt);
|
||||
n = re_vsnprintf(str, size, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print a formatted string to a buffer
|
||||
*
|
||||
* @param strp Buffer pointer for output string
|
||||
* @param fmt Formatted string
|
||||
*
|
||||
* @return 0 if success, otherwise errorcode
|
||||
*/
|
||||
int re_sdprintf(char **strp, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int err;
|
||||
|
||||
va_start(ap, fmt);
|
||||
err = re_vsdprintf(strp, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return err;
|
||||
}
|
42
src/fmt/prm.c
Normal file
42
src/fmt/prm.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* @file prm.c Generic parameter decoding
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <re_types.h>
|
||||
#include <re_fmt.h>
|
||||
|
||||
|
||||
bool fmt_param_get(const struct pl *pl, const char *pname, struct pl *val)
|
||||
{
|
||||
char expr[128];
|
||||
|
||||
if (!pl)
|
||||
return false;
|
||||
|
||||
(void)re_snprintf(expr, sizeof(expr), "%s[=]*[^;]*", pname);
|
||||
|
||||
return 0 == re_regex(pl->p, pl->l, expr, NULL, val);
|
||||
}
|
||||
|
||||
|
||||
void fmt_param_apply(const struct pl *pl, fmt_param_h *ph, void *arg)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (!pl || !ph)
|
||||
return;
|
||||
|
||||
for (i=0; i<pl->l; ) {
|
||||
struct pl lws, name, eq, val, s;
|
||||
|
||||
lws.l = eq.l = s.l = val.l = 0;
|
||||
if (re_regex(&pl->p[i], pl->l - i, "[ ]*[^;=]+[=]*[^;]*[;]*",
|
||||
&lws, &name, &eq, &val, &s))
|
||||
break;
|
||||
|
||||
ph(&name, &val, arg);
|
||||
|
||||
i += (lws.l + name.l + eq.l + val.l + s.l);
|
||||
}
|
||||
}
|
254
src/fmt/regex.c
Normal file
254
src/fmt/regex.c
Normal file
|
@ -0,0 +1,254 @@
|
|||
/**
|
||||
* @file regex.c Implements basic regular expressions
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <re_types.h>
|
||||
#include <re_fmt.h>
|
||||
|
||||
|
||||
/** Defines a character range */
|
||||
struct chr {
|
||||
uint8_t min; /**< Minimum value */
|
||||
uint8_t max; /**< Maximum value */
|
||||
};
|
||||
|
||||
|
||||
static bool expr_match(const struct chr *chrv, uint32_t n, uint8_t c,
|
||||
bool neg)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i=0; i<n; i++) {
|
||||
|
||||
if (c < chrv[i].min)
|
||||
continue;
|
||||
|
||||
if (c > chrv[i].max)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return neg ? (i == n) : (i != n);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a string using basic regular expressions. Any number of matching
|
||||
* expressions can be given, and each match will be stored in a "struct pl"
|
||||
* pointer-length type.
|
||||
*
|
||||
* @param ptr String to parse
|
||||
* @param len Length of string
|
||||
* @param expr Regular expressions string
|
||||
*
|
||||
* @return 0 if success, otherwise errorcode
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* We parse the buffer for any numerical values, to get a match we must have
|
||||
* 1 or more occurences of the digits 0-9. The result is stored in 'num',
|
||||
* which is of pointer-length type and will point to the first location in
|
||||
* the buffer that contains "42".
|
||||
*
|
||||
* <pre>
|
||||
const char buf[] = "foo 42 bar";
|
||||
struct pl num;
|
||||
int err = re_regex(buf, strlen(buf), "[0-9]+", &num);
|
||||
|
||||
here num contains a pointer to '42'
|
||||
* </pre>
|
||||
*/
|
||||
int re_regex(const char *ptr, size_t len, const char *expr, ...)
|
||||
{
|
||||
struct chr chrv[64];
|
||||
const char *p, *ep;
|
||||
bool fm, range = false, ec = false, neg = false, qesc = false;
|
||||
uint32_t n = 0;
|
||||
va_list ap;
|
||||
bool eesc;
|
||||
size_t l;
|
||||
|
||||
if (!ptr || !expr)
|
||||
return EINVAL;
|
||||
|
||||
again:
|
||||
eesc = false;
|
||||
fm = false;
|
||||
l = len--;
|
||||
p = ptr++;
|
||||
ep = expr;
|
||||
|
||||
va_start(ap, expr);
|
||||
|
||||
if (!l)
|
||||
goto out;
|
||||
|
||||
for (; *ep; ep++) {
|
||||
|
||||
if ('\\' == *ep && !eesc) {
|
||||
eesc = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!fm) {
|
||||
|
||||
/* Start of character class */
|
||||
if ('[' == *ep && !eesc) {
|
||||
n = 0;
|
||||
fm = true;
|
||||
ec = false;
|
||||
neg = false;
|
||||
range = false;
|
||||
qesc = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!l)
|
||||
break;
|
||||
|
||||
if (tolower(*ep) != tolower(*p))
|
||||
goto again;
|
||||
|
||||
eesc = false;
|
||||
++p;
|
||||
--l;
|
||||
continue;
|
||||
}
|
||||
/* End of character class */
|
||||
else if (ec) {
|
||||
|
||||
uint32_t nm, nmin, nmax;
|
||||
struct pl lpl, *pl = va_arg(ap, struct pl *);
|
||||
bool quote = false, esc = false;
|
||||
|
||||
/* Match 0 or more times */
|
||||
if ('*' == *ep) {
|
||||
nmin = 0;
|
||||
nmax = -1;
|
||||
}
|
||||
/* Match 1 or more times */
|
||||
else if ('+' == *ep) {
|
||||
nmin = 1;
|
||||
nmax = -1;
|
||||
}
|
||||
/* Match exactly n times */
|
||||
else if ('1' <= *ep && *ep <= '9') {
|
||||
nmin = *ep - '0';
|
||||
nmax = *ep - '0';
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
fm = false;
|
||||
|
||||
lpl.p = p;
|
||||
lpl.l = 0;
|
||||
|
||||
for (nm = 0; l && nm < nmax; nm++, p++, l--, lpl.l++) {
|
||||
|
||||
if (qesc) {
|
||||
|
||||
if (esc) {
|
||||
esc = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (*p) {
|
||||
|
||||
case '\\':
|
||||
esc = true;
|
||||
continue;
|
||||
|
||||
case '"':
|
||||
quote = !quote;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (quote)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!expr_match(chrv, n, tolower(*p), neg))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Strip quotes */
|
||||
if (qesc && lpl.l > 1 &&
|
||||
lpl.p[0] == '"' && lpl.p[lpl.l - 1] == '"') {
|
||||
|
||||
lpl.p += 1;
|
||||
lpl.l -= 2;
|
||||
nm -= 2;
|
||||
}
|
||||
|
||||
if ((nm < nmin) || (nm > nmax))
|
||||
goto again;
|
||||
|
||||
if (pl)
|
||||
*pl = lpl;
|
||||
|
||||
eesc = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (eesc) {
|
||||
eesc = false;
|
||||
goto chr;
|
||||
}
|
||||
|
||||
switch (*ep) {
|
||||
|
||||
/* End of character class */
|
||||
case ']':
|
||||
ec = true;
|
||||
continue;
|
||||
|
||||
/* Negate with quote escape */
|
||||
case '~':
|
||||
if (n)
|
||||
break;
|
||||
|
||||
qesc = true;
|
||||
neg = true;
|
||||
continue;
|
||||
|
||||
/* Negate */
|
||||
case '^':
|
||||
if (n)
|
||||
break;
|
||||
|
||||
neg = true;
|
||||
continue;
|
||||
|
||||
/* Range */
|
||||
case '-':
|
||||
if (!n || range)
|
||||
break;
|
||||
|
||||
range = true;
|
||||
--n;
|
||||
continue;
|
||||
}
|
||||
|
||||
chr:
|
||||
chrv[n].max = tolower(*ep);
|
||||
|
||||
if (range)
|
||||
range = false;
|
||||
else
|
||||
chrv[n].min = tolower(*ep);
|
||||
|
||||
if (++n > ARRAY_SIZE(chrv))
|
||||
break;
|
||||
}
|
||||
out:
|
||||
va_end(ap);
|
||||
|
||||
if (fm)
|
||||
return EINVAL;
|
||||
|
||||
return *ep ? ENOENT : 0;
|
||||
}
|
124
src/fmt/str.c
Normal file
124
src/fmt/str.c
Normal file
|
@ -0,0 +1,124 @@
|
|||
/**
|
||||
* @file fmt/str.c String format functions
|
||||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#undef __STRICT_ANSI__ /* for mingw32 */
|
||||
#include <string.h>
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#include <re_types.h>
|
||||
#include <re_mem.h>
|
||||
#include <re_fmt.h>
|
||||
|
||||
|
||||
/**
|
||||
* Convert a ascii hex string to binary format
|
||||
*
|
||||
* @param hex Destinatin binary buffer
|
||||
* @param len Length of binary buffer
|
||||
* @param str Source ascii string
|
||||
*
|
||||
* @return 0 if success, otherwise errorcode
|
||||
*/
|
||||
int str_hex(uint8_t *hex, size_t len, const char *str)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (!hex || !str || (strlen(str) != (2 * len)))
|
||||
return EINVAL;
|
||||
|
||||
for (i=0; i<len*2; i+=2) {
|
||||
hex[i/2] = ch_hex(str[i]) << 4;
|
||||
hex[i/2] += ch_hex(str[i+1]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy a 0-terminated string with maximum length
|
||||
*
|
||||
* @param dst Destinatin string
|
||||
* @param src Source string
|
||||
* @param n Maximum size of destination, including 0-terminator
|
||||
*/
|
||||
void str_ncpy(char *dst, const char *src, size_t n)
|
||||
{
|
||||
if (!dst || !src || !n)
|
||||
return;
|
||||
|
||||
(void)strncpy(dst, src, n-1);
|
||||
dst[n-1] = '\0'; /* strncpy does not null terminate if overflow */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Duplicate a 0-terminated string
|
||||
*
|
||||
* @param dst Pointer to destination string (set on return)
|
||||
* @param src Source string
|
||||
*
|
||||
* @return 0 if success, otherwise errorcode
|
||||
*/
|
||||
int str_dup(char **dst, const char *src)
|
||||
{
|
||||
char *p;
|
||||
size_t sz;
|
||||
|
||||
if (!dst || !src)
|
||||
return EINVAL;
|
||||
|
||||
sz = strlen(src) + 1;
|
||||
|
||||
p = mem_alloc(sz, NULL);
|
||||
if (!p)
|
||||
return ENOMEM;
|
||||
|
||||
memcpy(p, src, sz);
|
||||
|
||||
*dst = p;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare two 0-terminated strings
|
||||
*
|
||||
* @param s1 First string
|
||||
* @param s2 Second string
|
||||
*
|
||||
* @return an integer less than, equal to, or greater than zero if s1 is found
|
||||
* respectively, to be less than, to match, or be greater than s2
|
||||
*/
|
||||
int str_casecmp(const char *s1, const char *s2)
|
||||
{
|
||||
/* Same strings -> equal */
|
||||
if (s1 == s2)
|
||||
return 0;
|
||||
|
||||
if (!s1 || !s2)
|
||||
return 1;
|
||||
|
||||
#ifdef WIN32
|
||||
return _stricmp(s1, s2);
|
||||
#else
|
||||
return strcasecmp(s1, s2);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the length of a string, safe version.
|
||||
*
|
||||
* @param s String
|
||||
*
|
||||
* @return Length of the string
|
||||
*/
|
||||
size_t str_len(const char *s)
|
||||
{
|
||||
return s ? strlen(s) : 0;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue