summaryrefslogtreecommitdiffstats
path: root/third_party
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2010-10-27 21:32:02 +0100
committerKristian Monsen <kristianm@google.com>2010-10-27 21:32:02 +0100
commit1391b24619d56bae6ce14bb54ed0fb16a945e853 (patch)
treefbd465b79fe889aa53ee313b2a2b280b37a497d8 /third_party
parentc77745f79a9f73c4e2d409f8ebc8b031fce6ca75 (diff)
downloadexternal_chromium-1391b24619d56bae6ce14bb54ed0fb16a945e853.zip
external_chromium-1391b24619d56bae6ce14bb54ed0fb16a945e853.tar.gz
external_chromium-1391b24619d56bae6ce14bb54ed0fb16a945e853.tar.bz2
Final fixing of ANDROID guards
Verified that we now are in sync with chromium revision 61029 Change-Id: I49834ac6c0c422ab0d9a82caa02bdc63f456eadd
Diffstat (limited to 'third_party')
-rw-r--r--third_party/libjingle/libjingle.Makefile6
-rw-r--r--third_party/libjingle/libjingle.target.mk243
-rw-r--r--third_party/libjingle/libjingle_p2p.target.mk190
-rw-r--r--third_party/libjingle/source/talk/base/asyncfile.cc38
-rw-r--r--third_party/libjingle/source/talk/base/asyncsocket.cc61
-rw-r--r--third_party/libjingle/source/talk/base/socketaddresspair.cc58
-rw-r--r--third_party/libjingle/source/talk/base/socketaddresspair.h58
-rw-r--r--third_party/libjingle/source/talk/base/socketstream.cc138
-rw-r--r--third_party/libjingle/source/talk/p2p/base/relayserver.cc746
-rw-r--r--third_party/libjingle/source/talk/p2p/base/relayserver.h241
-rw-r--r--third_party/libjingle/source/talk/p2p/base/relayserver_main.cc80
-rw-r--r--third_party/libjingle/source/talk/p2p/base/sessiondescription.cc62
-rw-r--r--third_party/libjingle/source/talk/p2p/base/stunserver.cc159
-rw-r--r--third_party/libjingle/source/talk/p2p/base/stunserver.h77
-rw-r--r--third_party/libjingle/source/talk/p2p/base/stunserver_main.cc69
-rw-r--r--third_party/libjingle/source/talk/session/phone/devicemanager_mac.mm68
-rw-r--r--third_party/libjingle/source/talk/session/phone/videocommon.h161
17 files changed, 2016 insertions, 439 deletions
diff --git a/third_party/libjingle/libjingle.Makefile b/third_party/libjingle/libjingle.Makefile
deleted file mode 100644
index a934ecb..0000000
--- a/third_party/libjingle/libjingle.Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# This file is generated by gyp; do not edit.
-
-export builddir_name ?= /usr/local/google/src/chromium/src/third_party/libjingle/out
-.PHONY: all
-all:
- $(MAKE) -C ../.. libjingle libjingle_p2p
diff --git a/third_party/libjingle/libjingle.target.mk b/third_party/libjingle/libjingle.target.mk
deleted file mode 100644
index 13d0672..0000000
--- a/third_party/libjingle/libjingle.target.mk
+++ /dev/null
@@ -1,243 +0,0 @@
-# This file is generated by gyp; do not edit.
-
-TOOLSET := target
-TARGET := libjingle
-DEFS_Debug := '-DFEATURE_ENABLE_SSL' \
- '-DFEATURE_ENABLE_VOICEMAIL' \
- '-D_USE_32BIT_TIME_T' \
- '-DSAFE_TO_DEFINE_TALK_BASE_LOGGING_MACROS' \
- '-DEXPAT_RELATIVE_PATH' \
- '-DNO_HEAPCHECKER' \
- '-DLINUX' \
- '-DPOSIX' \
- '-DCHROMIUM_BUILD' \
- '-DENABLE_REMOTING=1' \
- '-DENABLE_GPU=1' \
- '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
- '-D_DEBUG'
-
-# Flags passed to both C and C++ files.
-CFLAGS_Debug := -pthread \
- -fno-exceptions \
- -Wno-unused-parameter \
- -Wno-missing-field-initializers \
- -D_FILE_OFFSET_BITS=64 \
- -fvisibility=hidden \
- -pipe \
- -fno-strict-aliasing \
- -pthread \
- -D_REENTRANT \
- -I/usr/include/gtk-2.0 \
- -I/usr/lib/gtk-2.0/include \
- -I/usr/include/atk-1.0 \
- -I/usr/include/cairo \
- -I/usr/include/pango-1.0 \
- -I/usr/include/gio-unix-2.0/ \
- -I/usr/include/glib-2.0 \
- -I/usr/lib/glib-2.0/include \
- -I/usr/include/pixman-1 \
- -I/usr/include/freetype2 \
- -I/usr/include/directfb \
- -I/usr/include/libpng12 \
- -O0 \
- -g
-
-# Flags passed to only C (and not C++) files.
-CFLAGS_C_Debug :=
-
-# Flags passed to only C++ (and not C) files.
-CFLAGS_CC_Debug := -fno-rtti \
- -fno-threadsafe-statics \
- -fvisibility-inlines-hidden
-
-INCS_Debug := -Ithird_party/libjingle/overrides \
- -Ithird_party/libjingle/source \
- -Ithird_party/expat/files \
- -I.
-
-DEFS_Release := '-DFEATURE_ENABLE_SSL' \
- '-DFEATURE_ENABLE_VOICEMAIL' \
- '-D_USE_32BIT_TIME_T' \
- '-DSAFE_TO_DEFINE_TALK_BASE_LOGGING_MACROS' \
- '-DEXPAT_RELATIVE_PATH' \
- '-DNO_HEAPCHECKER' \
- '-DLINUX' \
- '-DPOSIX' \
- '-DCHROMIUM_BUILD' \
- '-DENABLE_REMOTING=1' \
- '-DENABLE_GPU=1' \
- '-DNDEBUG' \
- '-DNVALGRIND' \
- '-DDYNAMIC_ANNOTATIONS_ENABLED=0'
-
-# Flags passed to both C and C++ files.
-CFLAGS_Release := -pthread \
- -fno-exceptions \
- -Wno-unused-parameter \
- -Wno-missing-field-initializers \
- -D_FILE_OFFSET_BITS=64 \
- -fvisibility=hidden \
- -pipe \
- -fno-strict-aliasing \
- -pthread \
- -D_REENTRANT \
- -I/usr/include/gtk-2.0 \
- -I/usr/lib/gtk-2.0/include \
- -I/usr/include/atk-1.0 \
- -I/usr/include/cairo \
- -I/usr/include/pango-1.0 \
- -I/usr/include/gio-unix-2.0/ \
- -I/usr/include/glib-2.0 \
- -I/usr/lib/glib-2.0/include \
- -I/usr/include/pixman-1 \
- -I/usr/include/freetype2 \
- -I/usr/include/directfb \
- -I/usr/include/libpng12 \
- -O2 \
- -fno-ident \
- -fdata-sections \
- -ffunction-sections
-
-# Flags passed to only C (and not C++) files.
-CFLAGS_C_Release :=
-
-# Flags passed to only C++ (and not C) files.
-CFLAGS_CC_Release := -fno-rtti \
- -fno-threadsafe-statics \
- -fvisibility-inlines-hidden
-
-INCS_Release := -Ithird_party/libjingle/overrides \
- -Ithird_party/libjingle/source \
- -Ithird_party/expat/files \
- -I.
-
-OBJS := $(obj).target/$(TARGET)/third_party/libjingle/overrides/talk/xmllite/qname.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/asyncfile.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/asynchttprequest.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/asyncpacketsocket.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/asyncsocket.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/asynctcpsocket.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/asyncudpsocket.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/autodetectproxy.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/base64.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/bytebuffer.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/checks.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/common.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/diskcache.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/event.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/fileutils.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/firewallsocketserver.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/flags.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/helpers.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/host.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/httpbase.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/httpclient.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/httpcommon.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/httprequest.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/logging.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/md5c.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/messagehandler.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/messagequeue.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/nethelpers.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/network.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/pathutils.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/physicalsocketserver.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/proxydetect.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/proxyinfo.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/signalthread.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/socketadapters.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/socketaddress.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/socketaddresspair.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/socketpool.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/socketstream.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/ssladapter.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/sslsocketfactory.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/stream.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/stringdigest.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/stringencode.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/stringutils.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/task.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/taskparent.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/taskrunner.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/thread.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/time.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/urlencode.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/xmllite/xmlbuilder.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/xmllite/xmlconstants.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/xmllite/xmlelement.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/xmllite/xmlnsstack.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/xmllite/xmlparser.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/xmllite/xmlprinter.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/xmpp/constants.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/xmpp/jid.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/xmpp/ratelimitmanager.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/xmpp/saslmechanism.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/xmpp/xmppclient.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/xmpp/xmppengineimpl.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/xmpp/xmppengineimpl_iq.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/xmpp/xmpplogintask.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/xmpp/xmppstanzaparser.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/xmpp/xmpptask.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/sslstreamadapter.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/unixfilesystem.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/base/linux.o
-
-# Add to the list of files we specially track dependencies for.
-all_deps += $(OBJS)
-
-# CFLAGS et al overrides must be target-local.
-# See "Target-specific Variable Values" in the GNU Make manual.
-$(OBJS): TOOLSET := $(TOOLSET)
-$(OBJS): GYP_CFLAGS := $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE))
-$(OBJS): GYP_CXXFLAGS := $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE))
-
-# Suffix rules, putting all outputs into $(obj).
-
-$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD
- @$(call do_cmd,cxx,1)
-
-$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
- @$(call do_cmd,cc,1)
-
-# Try building from generated source, too.
-
-$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD
- @$(call do_cmd,cxx,1)
-
-$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
- @$(call do_cmd,cc,1)
-
-$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD
- @$(call do_cmd,cxx,1)
-
-$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
- @$(call do_cmd,cc,1)
-
-# End of this set of suffix rules
-### Rules for final target.
-LDFLAGS_Debug := -pthread \
- -Wl,-z,noexecstack
-
-LDFLAGS_Release := -pthread \
- -Wl,-z,noexecstack \
- -Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
-
-LIBS :=
-
-$(obj).target/third_party/libjingle/libjingle.a: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))
-$(obj).target/third_party/libjingle/libjingle.a: LIBS := $(LIBS)
-$(obj).target/third_party/libjingle/libjingle.a: TOOLSET := $(TOOLSET)
-$(obj).target/third_party/libjingle/libjingle.a: $(OBJS) FORCE_DO_CMD
- $(call do_cmd,alink)
-
-all_deps += $(obj).target/third_party/libjingle/libjingle.a
-# Add target alias
-.PHONY: libjingle
-libjingle: $(obj).target/third_party/libjingle/libjingle.a
-
-# Add target alias to "all" target.
-.PHONY: all
-all: libjingle
-
diff --git a/third_party/libjingle/libjingle_p2p.target.mk b/third_party/libjingle/libjingle_p2p.target.mk
deleted file mode 100644
index 734bd2d..0000000
--- a/third_party/libjingle/libjingle_p2p.target.mk
+++ /dev/null
@@ -1,190 +0,0 @@
-# This file is generated by gyp; do not edit.
-
-TOOLSET := target
-TARGET := libjingle_p2p
-DEFS_Debug := '-DFEATURE_ENABLE_SSL' \
- '-DFEATURE_ENABLE_VOICEMAIL' \
- '-D_USE_32BIT_TIME_T' \
- '-DSAFE_TO_DEFINE_TALK_BASE_LOGGING_MACROS' \
- '-DEXPAT_RELATIVE_PATH' \
- '-DNO_HEAPCHECKER' \
- '-DLINUX' \
- '-DPOSIX' \
- '-DCHROMIUM_BUILD' \
- '-DENABLE_REMOTING=1' \
- '-DENABLE_GPU=1' \
- '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
- '-D_DEBUG'
-
-# Flags passed to both C and C++ files.
-CFLAGS_Debug := -pthread \
- -fno-exceptions \
- -Wno-unused-parameter \
- -Wno-missing-field-initializers \
- -D_FILE_OFFSET_BITS=64 \
- -fvisibility=hidden \
- -pipe \
- -fno-strict-aliasing \
- -pthread \
- -D_REENTRANT \
- -I/usr/include/gtk-2.0 \
- -I/usr/lib/gtk-2.0/include \
- -I/usr/include/atk-1.0 \
- -I/usr/include/cairo \
- -I/usr/include/pango-1.0 \
- -I/usr/include/gio-unix-2.0/ \
- -I/usr/include/glib-2.0 \
- -I/usr/lib/glib-2.0/include \
- -I/usr/include/pixman-1 \
- -I/usr/include/freetype2 \
- -I/usr/include/directfb \
- -I/usr/include/libpng12 \
- -O0 \
- -g
-
-# Flags passed to only C (and not C++) files.
-CFLAGS_C_Debug :=
-
-# Flags passed to only C++ (and not C) files.
-CFLAGS_CC_Debug := -fno-rtti \
- -fno-threadsafe-statics \
- -fvisibility-inlines-hidden
-
-INCS_Debug := -Ithird_party/libjingle/overrides \
- -Ithird_party/libjingle/source \
- -Ithird_party/expat/files \
- -I.
-
-DEFS_Release := '-DFEATURE_ENABLE_SSL' \
- '-DFEATURE_ENABLE_VOICEMAIL' \
- '-D_USE_32BIT_TIME_T' \
- '-DSAFE_TO_DEFINE_TALK_BASE_LOGGING_MACROS' \
- '-DEXPAT_RELATIVE_PATH' \
- '-DNO_HEAPCHECKER' \
- '-DLINUX' \
- '-DPOSIX' \
- '-DCHROMIUM_BUILD' \
- '-DENABLE_REMOTING=1' \
- '-DENABLE_GPU=1' \
- '-DNDEBUG' \
- '-DNVALGRIND' \
- '-DDYNAMIC_ANNOTATIONS_ENABLED=0'
-
-# Flags passed to both C and C++ files.
-CFLAGS_Release := -pthread \
- -fno-exceptions \
- -Wno-unused-parameter \
- -Wno-missing-field-initializers \
- -D_FILE_OFFSET_BITS=64 \
- -fvisibility=hidden \
- -pipe \
- -fno-strict-aliasing \
- -pthread \
- -D_REENTRANT \
- -I/usr/include/gtk-2.0 \
- -I/usr/lib/gtk-2.0/include \
- -I/usr/include/atk-1.0 \
- -I/usr/include/cairo \
- -I/usr/include/pango-1.0 \
- -I/usr/include/gio-unix-2.0/ \
- -I/usr/include/glib-2.0 \
- -I/usr/lib/glib-2.0/include \
- -I/usr/include/pixman-1 \
- -I/usr/include/freetype2 \
- -I/usr/include/directfb \
- -I/usr/include/libpng12 \
- -O2 \
- -fno-ident \
- -fdata-sections \
- -ffunction-sections
-
-# Flags passed to only C (and not C++) files.
-CFLAGS_C_Release :=
-
-# Flags passed to only C++ (and not C) files.
-CFLAGS_CC_Release := -fno-rtti \
- -fno-threadsafe-statics \
- -fvisibility-inlines-hidden
-
-INCS_Release := -Ithird_party/libjingle/overrides \
- -Ithird_party/libjingle/source \
- -Ithird_party/expat/files \
- -I.
-
-OBJS := $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/constants.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/p2ptransport.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/p2ptransportchannel.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/port.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/pseudotcp.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/rawtransport.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/rawtransportchannel.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/relayport.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/session.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/sessiondescription.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/sessionmanager.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/sessionmessages.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/parsing.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/stun.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/stunport.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/stunrequest.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/tcpport.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/transport.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/transportchannel.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/transportchannelproxy.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/base/udpport.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/client/basicportallocator.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/client/httpportallocator.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/p2p/client/socketmonitor.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.o \
- $(obj).target/$(TARGET)/third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.o
-
-# Add to the list of files we specially track dependencies for.
-all_deps += $(OBJS)
-
-# CFLAGS et al overrides must be target-local.
-# See "Target-specific Variable Values" in the GNU Make manual.
-$(OBJS): TOOLSET := $(TOOLSET)
-$(OBJS): GYP_CFLAGS := $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE))
-$(OBJS): GYP_CXXFLAGS := $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE))
-
-# Suffix rules, putting all outputs into $(obj).
-
-$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD
- @$(call do_cmd,cxx,1)
-
-# Try building from generated source, too.
-
-$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD
- @$(call do_cmd,cxx,1)
-
-$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD
- @$(call do_cmd,cxx,1)
-
-# End of this set of suffix rules
-### Rules for final target.
-LDFLAGS_Debug := -pthread \
- -Wl,-z,noexecstack
-
-LDFLAGS_Release := -pthread \
- -Wl,-z,noexecstack \
- -Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
-
-LIBS :=
-
-$(obj).target/third_party/libjingle/libjingle_p2p.a: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))
-$(obj).target/third_party/libjingle/libjingle_p2p.a: LIBS := $(LIBS)
-$(obj).target/third_party/libjingle/libjingle_p2p.a: TOOLSET := $(TOOLSET)
-$(obj).target/third_party/libjingle/libjingle_p2p.a: $(OBJS) FORCE_DO_CMD
- $(call do_cmd,alink)
-
-all_deps += $(obj).target/third_party/libjingle/libjingle_p2p.a
-# Add target alias
-.PHONY: libjingle_p2p
-libjingle_p2p: $(obj).target/third_party/libjingle/libjingle_p2p.a
-
-# Add target alias to "all" target.
-.PHONY: all
-all: libjingle_p2p
-
diff --git a/third_party/libjingle/source/talk/base/asyncfile.cc b/third_party/libjingle/source/talk/base/asyncfile.cc
new file mode 100644
index 0000000..5c6e11d
--- /dev/null
+++ b/third_party/libjingle/source/talk/base/asyncfile.cc
@@ -0,0 +1,38 @@
+/*
+ * libjingle
+ * Copyright 2010, Google Inc.
+ *
+ * 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. The name of the author may not 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.
+ */
+
+#include "talk/base/asyncfile.h"
+
+namespace talk_base {
+
+AsyncFile::AsyncFile() {
+}
+
+AsyncFile::~AsyncFile() {
+}
+
+} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/asyncsocket.cc b/third_party/libjingle/source/talk/base/asyncsocket.cc
new file mode 100644
index 0000000..d9ed94c
--- /dev/null
+++ b/third_party/libjingle/source/talk/base/asyncsocket.cc
@@ -0,0 +1,61 @@
+/*
+ * libjingle
+ * Copyright 2010, Google Inc.
+ *
+ * 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. The name of the author may not 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.
+ */
+
+#include "talk/base/asyncsocket.h"
+
+namespace talk_base {
+
+AsyncSocket::AsyncSocket() {
+}
+
+AsyncSocket::~AsyncSocket() {
+}
+
+AsyncSocketAdapter::AsyncSocketAdapter(AsyncSocket* socket) : socket_(NULL) {
+ Attach(socket);
+}
+
+AsyncSocketAdapter::~AsyncSocketAdapter() {
+ delete socket_;
+}
+
+void AsyncSocketAdapter::Attach(AsyncSocket* socket) {
+ ASSERT(!socket_);
+ socket_ = socket;
+ if (socket_) {
+ socket_->SignalConnectEvent.connect(this,
+ &AsyncSocketAdapter::OnConnectEvent);
+ socket_->SignalReadEvent.connect(this,
+ &AsyncSocketAdapter::OnReadEvent);
+ socket_->SignalWriteEvent.connect(this,
+ &AsyncSocketAdapter::OnWriteEvent);
+ socket_->SignalCloseEvent.connect(this,
+ &AsyncSocketAdapter::OnCloseEvent);
+ }
+}
+
+} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/socketaddresspair.cc b/third_party/libjingle/source/talk/base/socketaddresspair.cc
new file mode 100644
index 0000000..7f190a9
--- /dev/null
+++ b/third_party/libjingle/source/talk/base/socketaddresspair.cc
@@ -0,0 +1,58 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * 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. The name of the author may not 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.
+ */
+
+#include "talk/base/socketaddresspair.h"
+
+namespace talk_base {
+
+SocketAddressPair::SocketAddressPair(
+ const SocketAddress& src, const SocketAddress& dest)
+ : src_(src), dest_(dest) {
+}
+
+
+bool SocketAddressPair::operator ==(const SocketAddressPair& p) const {
+ return (src_ == p.src_) && (dest_ == p.dest_);
+}
+
+bool SocketAddressPair::operator <(const SocketAddressPair& p) const {
+ if (src_ < p.src_)
+ return true;
+ if (p.src_ < src_)
+ return false;
+ if (dest_ < p.dest_)
+ return true;
+ if (p.dest_ < dest_)
+ return false;
+ return false;
+}
+
+size_t SocketAddressPair::Hash() const {
+ return src_.Hash() ^ dest_.Hash();
+}
+
+} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/socketaddresspair.h b/third_party/libjingle/source/talk/base/socketaddresspair.h
new file mode 100644
index 0000000..10f5d30
--- /dev/null
+++ b/third_party/libjingle/source/talk/base/socketaddresspair.h
@@ -0,0 +1,58 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * 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. The name of the author may not 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.
+ */
+
+#ifndef TALK_BASE_SOCKETADDRESSPAIR_H__
+#define TALK_BASE_SOCKETADDRESSPAIR_H__
+
+#include "talk/base/socketaddress.h"
+
+namespace talk_base {
+
+// Records a pair (source,destination) of socket addresses. The two addresses
+// identify a connection between two machines. (For UDP, this "connection" is
+// not maintained explicitly in a socket.)
+class SocketAddressPair {
+public:
+ SocketAddressPair() {}
+ SocketAddressPair(const SocketAddress& srs, const SocketAddress& dest);
+
+ const SocketAddress& source() const { return src_; }
+ const SocketAddress& destination() const { return dest_; }
+
+ bool operator ==(const SocketAddressPair& r) const;
+ bool operator <(const SocketAddressPair& r) const;
+
+ size_t Hash() const;
+
+private:
+ SocketAddress src_;
+ SocketAddress dest_;
+};
+
+} // namespace talk_base
+
+#endif // TALK_BASE_SOCKETADDRESSPAIR_H__
diff --git a/third_party/libjingle/source/talk/base/socketstream.cc b/third_party/libjingle/source/talk/base/socketstream.cc
new file mode 100644
index 0000000..3dc5a95
--- /dev/null
+++ b/third_party/libjingle/source/talk/base/socketstream.cc
@@ -0,0 +1,138 @@
+/*
+ * libjingle
+ * Copyright 2010, Google Inc.
+ *
+ * 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. The name of the author may not 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.
+ */
+
+#include "talk/base/socketstream.h"
+
+namespace talk_base {
+
+SocketStream::SocketStream(AsyncSocket* socket) : socket_(NULL) {
+ Attach(socket);
+}
+
+SocketStream::~SocketStream() {
+ delete socket_;
+}
+
+void SocketStream::Attach(AsyncSocket* socket) {
+ if (socket_)
+ delete socket_;
+ socket_ = socket;
+ if (socket_) {
+ socket_->SignalConnectEvent.connect(this, &SocketStream::OnConnectEvent);
+ socket_->SignalReadEvent.connect(this, &SocketStream::OnReadEvent);
+ socket_->SignalWriteEvent.connect(this, &SocketStream::OnWriteEvent);
+ socket_->SignalCloseEvent.connect(this, &SocketStream::OnCloseEvent);
+ }
+}
+
+AsyncSocket* SocketStream::Detach() {
+ AsyncSocket* socket = socket_;
+ if (socket_) {
+ socket_->SignalConnectEvent.disconnect(this);
+ socket_->SignalReadEvent.disconnect(this);
+ socket_->SignalWriteEvent.disconnect(this);
+ socket_->SignalCloseEvent.disconnect(this);
+ socket_ = NULL;
+ }
+ return socket;
+}
+
+StreamState SocketStream::GetState() const {
+ ASSERT(socket_ != NULL);
+ switch (socket_->GetState()) {
+ case Socket::CS_CONNECTED:
+ return SS_OPEN;
+ case Socket::CS_CONNECTING:
+ return SS_OPENING;
+ case Socket::CS_CLOSED:
+ default:
+ return SS_CLOSED;
+ }
+}
+
+StreamResult SocketStream::Read(void* buffer, size_t buffer_len,
+ size_t* read, int* error) {
+ ASSERT(socket_ != NULL);
+ int result = socket_->Recv(buffer, buffer_len);
+ if (result < 0) {
+ if (socket_->IsBlocking())
+ return SR_BLOCK;
+ if (error)
+ *error = socket_->GetError();
+ return SR_ERROR;
+ }
+ if ((result > 0) || (buffer_len == 0)) {
+ if (read)
+ *read = result;
+ return SR_SUCCESS;
+ }
+ return SR_EOS;
+}
+
+StreamResult SocketStream::Write(const void* data, size_t data_len,
+ size_t* written, int* error) {
+ ASSERT(socket_ != NULL);
+ int result = socket_->Send(data, data_len);
+ if (result < 0) {
+ if (socket_->IsBlocking())
+ return SR_BLOCK;
+ if (error)
+ *error = socket_->GetError();
+ return SR_ERROR;
+ }
+ if (written)
+ *written = result;
+ return SR_SUCCESS;
+}
+
+void SocketStream::Close() {
+ ASSERT(socket_ != NULL);
+ socket_->Close();
+}
+
+void SocketStream::OnConnectEvent(AsyncSocket* socket) {
+ ASSERT(socket == socket_);
+ SignalEvent(this, SE_OPEN | SE_READ | SE_WRITE, 0);
+}
+
+void SocketStream::OnReadEvent(AsyncSocket* socket) {
+ ASSERT(socket == socket_);
+ SignalEvent(this, SE_READ, 0);
+}
+
+void SocketStream::OnWriteEvent(AsyncSocket* socket) {
+ ASSERT(socket == socket_);
+ SignalEvent(this, SE_WRITE, 0);
+}
+
+void SocketStream::OnCloseEvent(AsyncSocket* socket, int err) {
+ ASSERT(socket == socket_);
+ SignalEvent(this, SE_CLOSE, err);
+}
+
+
+} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/p2p/base/relayserver.cc b/third_party/libjingle/source/talk/p2p/base/relayserver.cc
new file mode 100644
index 0000000..6ff0861
--- /dev/null
+++ b/third_party/libjingle/source/talk/p2p/base/relayserver.cc
@@ -0,0 +1,746 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * 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. The name of the author may not 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.
+ */
+
+#include "talk/p2p/base/relayserver.h"
+
+#ifdef POSIX
+#include <errno.h>
+#endif // POSIX
+
+#include <algorithm>
+
+#include "talk/base/asynctcpsocket.h"
+#include "talk/base/helpers.h"
+#include "talk/base/logging.h"
+#include "talk/base/socketadapters.h"
+
+namespace cricket {
+
+// By default, we require a ping every 90 seconds.
+const int MAX_LIFETIME = 15 * 60 * 1000;
+
+// The number of bytes in each of the usernames we use.
+const uint32 USERNAME_LENGTH = 16;
+
+static const uint32 kMessageAcceptConnection = 1;
+
+// Calls SendTo on the given socket and logs any bad results.
+void Send(talk_base::AsyncPacketSocket* socket, const char* bytes, size_t size,
+ const talk_base::SocketAddress& addr) {
+ int result = socket->SendTo(bytes, size, addr);
+ if (result < static_cast<int>(size)) {
+ LOG(LS_ERROR) << "SendTo wrote only " << result << " of " << size
+ << " bytes";
+ } else if (result < 0) {
+ LOG_ERR(LS_ERROR) << "SendTo";
+ }
+}
+
+// Sends the given STUN message on the given socket.
+void SendStun(const StunMessage& msg,
+ talk_base::AsyncPacketSocket* socket,
+ const talk_base::SocketAddress& addr) {
+ talk_base::ByteBuffer buf;
+ msg.Write(&buf);
+ Send(socket, buf.Data(), buf.Length(), addr);
+}
+
+// Constructs a STUN error response and sends it on the given socket.
+void SendStunError(const StunMessage& msg, talk_base::AsyncPacketSocket* socket,
+ const talk_base::SocketAddress& remote_addr, int error_code,
+ const char* error_desc, const std::string& magic_cookie) {
+ StunMessage err_msg;
+ err_msg.SetType(GetStunErrorResponseType(msg.type()));
+ err_msg.SetTransactionID(msg.transaction_id());
+
+ StunByteStringAttribute* magic_cookie_attr =
+ StunAttribute::CreateByteString(cricket::STUN_ATTR_MAGIC_COOKIE);
+ if (magic_cookie.size() == 0)
+ magic_cookie_attr->CopyBytes(cricket::STUN_MAGIC_COOKIE_VALUE, 4);
+ else
+ magic_cookie_attr->CopyBytes(magic_cookie.c_str(), magic_cookie.size());
+ err_msg.AddAttribute(magic_cookie_attr);
+
+ StunErrorCodeAttribute* err_code = StunAttribute::CreateErrorCode();
+ err_code->SetErrorClass(error_code / 100);
+ err_code->SetNumber(error_code % 100);
+ err_code->SetReason(error_desc);
+ err_msg.AddAttribute(err_code);
+
+ SendStun(err_msg, socket, remote_addr);
+}
+
+RelayServer::RelayServer(talk_base::Thread* thread)
+ : thread_(thread), log_bindings_(true) {
+}
+
+RelayServer::~RelayServer() {
+ // Deleting the binding will cause it to be removed from the map.
+ while (!bindings_.empty())
+ delete bindings_.begin()->second;
+ for (size_t i = 0; i < internal_sockets_.size(); ++i)
+ delete internal_sockets_[i];
+ for (size_t i = 0; i < external_sockets_.size(); ++i)
+ delete external_sockets_[i];
+ while (!server_sockets_.empty()) {
+ talk_base::AsyncSocket* socket = server_sockets_.begin()->first;
+ server_sockets_.erase(server_sockets_.begin()->first);
+ delete socket;
+ }
+}
+
+void RelayServer::AddInternalSocket(talk_base::AsyncPacketSocket* socket) {
+ ASSERT(internal_sockets_.end() ==
+ std::find(internal_sockets_.begin(), internal_sockets_.end(), socket));
+ internal_sockets_.push_back(socket);
+ socket->SignalReadPacket.connect(this, &RelayServer::OnInternalPacket);
+}
+
+void RelayServer::RemoveInternalSocket(talk_base::AsyncPacketSocket* socket) {
+ SocketList::iterator iter =
+ std::find(internal_sockets_.begin(), internal_sockets_.end(), socket);
+ ASSERT(iter != internal_sockets_.end());
+ internal_sockets_.erase(iter);
+ socket->SignalReadPacket.disconnect(this);
+}
+
+void RelayServer::AddExternalSocket(talk_base::AsyncPacketSocket* socket) {
+ ASSERT(external_sockets_.end() ==
+ std::find(external_sockets_.begin(), external_sockets_.end(), socket));
+ external_sockets_.push_back(socket);
+ socket->SignalReadPacket.connect(this, &RelayServer::OnExternalPacket);
+}
+
+void RelayServer::RemoveExternalSocket(talk_base::AsyncPacketSocket* socket) {
+ SocketList::iterator iter =
+ std::find(external_sockets_.begin(), external_sockets_.end(), socket);
+ ASSERT(iter != external_sockets_.end());
+ external_sockets_.erase(iter);
+ socket->SignalReadPacket.disconnect(this);
+}
+
+void RelayServer::AddInternalServerSocket(talk_base::AsyncSocket* socket,
+ cricket::ProtocolType proto) {
+ ASSERT(server_sockets_.end() ==
+ server_sockets_.find(socket));
+ server_sockets_[socket] = proto;
+ socket->SignalReadEvent.connect(this, &RelayServer::OnReadEvent);
+}
+
+void RelayServer::RemoveInternalServerSocket(
+ talk_base::AsyncSocket* socket) {
+ ServerSocketMap::iterator iter = server_sockets_.find(socket);
+ ASSERT(iter != server_sockets_.end());
+ server_sockets_.erase(iter);
+ socket->SignalReadEvent.disconnect(this);
+}
+
+int RelayServer::GetConnectionCount() {
+ return connections_.size();
+}
+
+bool RelayServer::HasConnection(const talk_base::SocketAddress& address) {
+ for (ConnectionMap::iterator it = connections_.begin();
+ it != connections_.end(); ++it) {
+ if (it->second->addr_pair().destination() == address) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void RelayServer::OnReadEvent(talk_base::AsyncSocket* socket) {
+ ServerSocketMap::iterator iter = server_sockets_.find(socket);
+ ASSERT(iter != server_sockets_.end());
+ AcceptConnection(socket);
+}
+
+void RelayServer::OnInternalPacket(
+ const char* bytes, size_t size, const talk_base::SocketAddress& remote_addr,
+ talk_base::AsyncPacketSocket* socket) {
+
+ // Get the address of the connection we just received on.
+ talk_base::SocketAddressPair ap(remote_addr, socket->GetLocalAddress());
+ ASSERT(!ap.destination().IsAny());
+
+ // If this did not come from an existing connection, it should be a STUN
+ // allocate request.
+ ConnectionMap::iterator piter = connections_.find(ap);
+ if (piter == connections_.end()) {
+ HandleStunAllocate(bytes, size, ap, socket);
+ return;
+ }
+
+ RelayServerConnection* int_conn = piter->second;
+
+ // Handle STUN requests to the server itself.
+ if (int_conn->binding()->HasMagicCookie(bytes, size)) {
+ HandleStun(int_conn, bytes, size);
+ return;
+ }
+
+ // Otherwise, this is a non-wrapped packet that we are to forward. Make sure
+ // that this connection has been locked. (Otherwise, we would not know what
+ // address to forward to.)
+ if (!int_conn->locked()) {
+ LOG(LS_WARNING) << "Dropping packet: connection not locked";
+ return;
+ }
+
+ // Forward this to the destination address into the connection.
+ RelayServerConnection* ext_conn = int_conn->binding()->GetExternalConnection(
+ int_conn->default_destination());
+ if (ext_conn && ext_conn->locked()) {
+ // TODO(juberti): Check the HMAC.
+ ext_conn->Send(bytes, size);
+ } else {
+ // This happens very often and is not an error.
+ LOG(LS_INFO) << "Dropping packet: no external connection";
+ }
+}
+
+void RelayServer::OnExternalPacket(
+ const char* bytes, size_t size, const talk_base::SocketAddress& remote_addr,
+ talk_base::AsyncPacketSocket* socket) {
+
+ // Get the address of the connection we just received on.
+ talk_base::SocketAddressPair ap(remote_addr, socket->GetLocalAddress());
+ ASSERT(!ap.destination().IsAny());
+
+ // If this connection already exists, then forward the traffic.
+ ConnectionMap::iterator piter = connections_.find(ap);
+ if (piter != connections_.end()) {
+ // TODO(juberti): Check the HMAC.
+ RelayServerConnection* ext_conn = piter->second;
+ RelayServerConnection* int_conn =
+ ext_conn->binding()->GetInternalConnection(
+ ext_conn->addr_pair().source());
+ ASSERT(int_conn != NULL);
+ int_conn->Send(bytes, size, ext_conn->addr_pair().source());
+ ext_conn->Lock(); // allow outgoing packets
+ return;
+ }
+
+ // The first packet should always be a STUN / TURN packet. If it isn't, then
+ // we should just ignore this packet.
+ StunMessage msg;
+ talk_base::ByteBuffer buf(bytes, size);
+ if (!msg.Read(&buf)) {
+ LOG(LS_WARNING) << "Dropping packet: first packet not STUN";
+ return;
+ }
+
+ // The initial packet should have a username (which identifies the binding).
+ const StunByteStringAttribute* username_attr =
+ msg.GetByteString(STUN_ATTR_USERNAME);
+ if (!username_attr) {
+ LOG(LS_WARNING) << "Dropping packet: no username";
+ return;
+ }
+
+ uint32 length = talk_base::_min(static_cast<uint32>(username_attr->length()),
+ USERNAME_LENGTH);
+ std::string username(username_attr->bytes(), length);
+ // TODO(juberti): Check the HMAC.
+
+ // The binding should already be present.
+ BindingMap::iterator biter = bindings_.find(username);
+ if (biter == bindings_.end()) {
+ LOG(LS_WARNING) << "Dropping packet: no binding with username";
+ return;
+ }
+
+ // Add this authenticted connection to the binding.
+ RelayServerConnection* ext_conn =
+ new RelayServerConnection(biter->second, ap, socket);
+ ext_conn->binding()->AddExternalConnection(ext_conn);
+ AddConnection(ext_conn);
+
+ // We always know where external packets should be forwarded, so we can lock
+ // them from the beginning.
+ ext_conn->Lock();
+
+ // Send this message on the appropriate internal connection.
+ RelayServerConnection* int_conn = ext_conn->binding()->GetInternalConnection(
+ ext_conn->addr_pair().source());
+ ASSERT(int_conn != NULL);
+ int_conn->Send(bytes, size, ext_conn->addr_pair().source());
+}
+
+bool RelayServer::HandleStun(
+ const char* bytes, size_t size, const talk_base::SocketAddress& remote_addr,
+ talk_base::AsyncPacketSocket* socket, std::string* username,
+ StunMessage* msg) {
+
+ // Parse this into a stun message.
+ talk_base::ByteBuffer buf(bytes, size);
+ if (!msg->Read(&buf)) {
+ SendStunError(*msg, socket, remote_addr, 400, "Bad Request", "");
+ return false;
+ }
+
+ // The initial packet should have a username (which identifies the binding).
+ const StunByteStringAttribute* username_attr =
+ msg->GetByteString(STUN_ATTR_USERNAME);
+ if (!username_attr) {
+ SendStunError(*msg, socket, remote_addr, 432, "Missing Username", "");
+ return false;
+ }
+
+ // Record the username if requested.
+ if (username)
+ username->append(username_attr->bytes(), username_attr->length());
+
+ // TODO(juberti): Check for unknown attributes (<= 0x7fff)
+
+ return true;
+}
+
+void RelayServer::HandleStunAllocate(
+ const char* bytes, size_t size, const talk_base::SocketAddressPair& ap,
+ talk_base::AsyncPacketSocket* socket) {
+
+ // Make sure this is a valid STUN request.
+ StunMessage request;
+ std::string username;
+ if (!HandleStun(bytes, size, ap.source(), socket, &username, &request))
+ return;
+
+ // Make sure this is a an allocate request.
+ if (request.type() != STUN_ALLOCATE_REQUEST) {
+ SendStunError(request,
+ socket,
+ ap.source(),
+ 600,
+ "Operation Not Supported",
+ "");
+ return;
+ }
+
+ // TODO(juberti): Check the HMAC.
+
+ // Find or create the binding for this username.
+
+ RelayServerBinding* binding;
+
+ BindingMap::iterator biter = bindings_.find(username);
+ if (biter != bindings_.end()) {
+ binding = biter->second;
+ } else {
+ // NOTE: In the future, bindings will be created by the bot only. This
+ // else-branch will then disappear.
+
+ // Compute the appropriate lifetime for this binding.
+ uint32 lifetime = MAX_LIFETIME;
+ const StunUInt32Attribute* lifetime_attr =
+ request.GetUInt32(STUN_ATTR_LIFETIME);
+ if (lifetime_attr)
+ lifetime = talk_base::_min(lifetime, lifetime_attr->value() * 1000);
+
+ binding = new RelayServerBinding(this, username, "0", lifetime);
+ binding->SignalTimeout.connect(this, &RelayServer::OnTimeout);
+ bindings_[username] = binding;
+
+ if (log_bindings_) {
+ LOG(LS_INFO) << "Added new binding " << username << ", "
+ << bindings_.size() << " total";
+ }
+ }
+
+ // Add this connection to the binding. It starts out unlocked.
+ RelayServerConnection* int_conn =
+ new RelayServerConnection(binding, ap, socket);
+ binding->AddInternalConnection(int_conn);
+ AddConnection(int_conn);
+
+ // Now that we have a connection, this other method takes over.
+ HandleStunAllocate(int_conn, request);
+}
+
+void RelayServer::HandleStun(
+ RelayServerConnection* int_conn, const char* bytes, size_t size) {
+
+ // Make sure this is a valid STUN request.
+ StunMessage request;
+ std::string username;
+ if (!HandleStun(bytes, size, int_conn->addr_pair().source(),
+ int_conn->socket(), &username, &request))
+ return;
+
+ // Make sure the username is the one were were expecting.
+ if (username != int_conn->binding()->username()) {
+ int_conn->SendStunError(request, 430, "Stale Credentials");
+ return;
+ }
+
+ // TODO(juberti): Check the HMAC.
+
+ // Send this request to the appropriate handler.
+ if (request.type() == STUN_SEND_REQUEST)
+ HandleStunSend(int_conn, request);
+ else if (request.type() == STUN_ALLOCATE_REQUEST)
+ HandleStunAllocate(int_conn, request);
+ else
+ int_conn->SendStunError(request, 600, "Operation Not Supported");
+}
+
+void RelayServer::HandleStunAllocate(
+ RelayServerConnection* int_conn, const StunMessage& request) {
+
+ // Create a response message that includes an address with which external
+ // clients can communicate.
+
+ StunMessage response;
+ response.SetType(STUN_ALLOCATE_RESPONSE);
+ response.SetTransactionID(request.transaction_id());
+
+ StunByteStringAttribute* magic_cookie_attr =
+ StunAttribute::CreateByteString(cricket::STUN_ATTR_MAGIC_COOKIE);
+ magic_cookie_attr->CopyBytes(int_conn->binding()->magic_cookie().c_str(),
+ int_conn->binding()->magic_cookie().size());
+ response.AddAttribute(magic_cookie_attr);
+
+ size_t index = rand() % external_sockets_.size();
+ talk_base::SocketAddress ext_addr =
+ external_sockets_[index]->GetLocalAddress();
+
+ StunAddressAttribute* addr_attr =
+ StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
+ addr_attr->SetFamily(1);
+ addr_attr->SetIP(ext_addr.ip());
+ addr_attr->SetPort(ext_addr.port());
+ response.AddAttribute(addr_attr);
+
+ StunUInt32Attribute* res_lifetime_attr =
+ StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
+ res_lifetime_attr->SetValue(int_conn->binding()->lifetime() / 1000);
+ response.AddAttribute(res_lifetime_attr);
+
+ // TODO(juberti): Support transport-prefs (preallocate RTCP port).
+ // TODO(juberti): Support bandwidth restrictions.
+ // TODO(juberti): Add message integrity check.
+
+ // Send a response to the caller.
+ int_conn->SendStun(response);
+}
+
+void RelayServer::HandleStunSend(
+ RelayServerConnection* int_conn, const StunMessage& request) {
+
+ const StunAddressAttribute* addr_attr =
+ request.GetAddress(STUN_ATTR_DESTINATION_ADDRESS);
+ if (!addr_attr) {
+ int_conn->SendStunError(request, 400, "Bad Request");
+ return;
+ }
+
+ const StunByteStringAttribute* data_attr =
+ request.GetByteString(STUN_ATTR_DATA);
+ if (!data_attr) {
+ int_conn->SendStunError(request, 400, "Bad Request");
+ return;
+ }
+
+ talk_base::SocketAddress ext_addr(addr_attr->ip(), addr_attr->port());
+ RelayServerConnection* ext_conn =
+ int_conn->binding()->GetExternalConnection(ext_addr);
+ if (!ext_conn) {
+ // Create a new connection to establish the relationship with this binding.
+ ASSERT(external_sockets_.size() == 1);
+ talk_base::AsyncPacketSocket* socket = external_sockets_[0];
+ talk_base::SocketAddressPair ap(ext_addr, socket->GetLocalAddress());
+ ext_conn = new RelayServerConnection(int_conn->binding(), ap, socket);
+ ext_conn->binding()->AddExternalConnection(ext_conn);
+ AddConnection(ext_conn);
+ }
+
+ // If this connection has pinged us, then allow outgoing traffic.
+ if (ext_conn->locked())
+ ext_conn->Send(data_attr->bytes(), data_attr->length());
+
+ const StunUInt32Attribute* options_attr =
+ request.GetUInt32(STUN_ATTR_OPTIONS);
+ if (options_attr && (options_attr->value() & 0x01)) {
+ int_conn->set_default_destination(ext_addr);
+ int_conn->Lock();
+
+ StunMessage response;
+ response.SetType(STUN_SEND_RESPONSE);
+ response.SetTransactionID(request.transaction_id());
+
+ StunByteStringAttribute* magic_cookie_attr =
+ StunAttribute::CreateByteString(cricket::STUN_ATTR_MAGIC_COOKIE);
+ magic_cookie_attr->CopyBytes(int_conn->binding()->magic_cookie().c_str(),
+ int_conn->binding()->magic_cookie().size());
+ response.AddAttribute(magic_cookie_attr);
+
+ StunUInt32Attribute* options2_attr =
+ StunAttribute::CreateUInt32(cricket::STUN_ATTR_OPTIONS);
+ options2_attr->SetValue(0x01);
+ response.AddAttribute(options2_attr);
+
+ int_conn->SendStun(response);
+ }
+}
+
+void RelayServer::AddConnection(RelayServerConnection* conn) {
+ ASSERT(connections_.find(conn->addr_pair()) == connections_.end());
+ connections_[conn->addr_pair()] = conn;
+}
+
+void RelayServer::RemoveConnection(RelayServerConnection* conn) {
+ ConnectionMap::iterator iter = connections_.find(conn->addr_pair());
+ ASSERT(iter != connections_.end());
+ connections_.erase(iter);
+}
+
+void RelayServer::RemoveBinding(RelayServerBinding* binding) {
+ BindingMap::iterator iter = bindings_.find(binding->username());
+ ASSERT(iter != bindings_.end());
+ bindings_.erase(iter);
+
+ if (log_bindings_) {
+ LOG(LS_INFO) << "Removed binding " << binding->username() << ", "
+ << bindings_.size() << " remaining";
+ }
+}
+
+void RelayServer::OnMessage(talk_base::Message *pmsg) {
+ ASSERT(pmsg->message_id == kMessageAcceptConnection);
+ talk_base::MessageData* data = pmsg->pdata;
+ talk_base::AsyncSocket* socket =
+ static_cast <talk_base::TypedMessageData<talk_base::AsyncSocket*>*>
+ (data)->data();
+ AcceptConnection(socket);
+ delete data;
+}
+
+void RelayServer::OnTimeout(RelayServerBinding* binding) {
+ // This call will result in all of the necessary clean-up. We can't call
+ // delete here, because you can't delete an object that is signaling you.
+ thread_->Dispose(binding);
+}
+
+void RelayServer::AcceptConnection(talk_base::AsyncSocket* server_socket) {
+ // Check if someone is trying to connect to us.
+ talk_base::SocketAddress accept_addr;
+ talk_base::AsyncSocket* accepted_socket =
+ server_socket->Accept(&accept_addr);
+ if (accepted_socket != NULL) {
+ // We had someone trying to connect, now check which protocol to
+ // use and create a packet socket.
+ ASSERT(server_sockets_[server_socket] == cricket::PROTO_TCP ||
+ server_sockets_[server_socket] == cricket::PROTO_SSLTCP);
+ if (server_sockets_[server_socket] == cricket::PROTO_SSLTCP) {
+ accepted_socket = new talk_base::AsyncSSLServerSocket(accepted_socket);
+ }
+ talk_base::AsyncTCPSocket* tcp_socket =
+ new talk_base::AsyncTCPSocket(accepted_socket);
+
+ // Finally add the socket so it can start communicating with the client.
+ AddInternalSocket(tcp_socket);
+ }
+}
+
+RelayServerConnection::RelayServerConnection(
+ RelayServerBinding* binding, const talk_base::SocketAddressPair& addrs,
+ talk_base::AsyncPacketSocket* socket)
+ : binding_(binding), addr_pair_(addrs), socket_(socket), locked_(false) {
+ // The creation of a new connection constitutes a use of the binding.
+ binding_->NoteUsed();
+}
+
+RelayServerConnection::~RelayServerConnection() {
+ // Remove this connection from the server's map (if it exists there).
+ binding_->server()->RemoveConnection(this);
+}
+
+void RelayServerConnection::Send(const char* data, size_t size) {
+ // Note that the binding has been used again.
+ binding_->NoteUsed();
+
+ cricket::Send(socket_, data, size, addr_pair_.source());
+}
+
+void RelayServerConnection::Send(
+ const char* data, size_t size, const talk_base::SocketAddress& from_addr) {
+ // If the from address is known to the client, we don't need to send it.
+ if (locked() && (from_addr == default_dest_)) {
+ Send(data, size);
+ return;
+ }
+
+ // Wrap the given data in a data-indication packet.
+
+ StunMessage msg;
+ msg.SetType(STUN_DATA_INDICATION);
+ msg.SetTransactionID("0000000000000000");
+
+ StunByteStringAttribute* magic_cookie_attr =
+ StunAttribute::CreateByteString(cricket::STUN_ATTR_MAGIC_COOKIE);
+ magic_cookie_attr->CopyBytes(binding_->magic_cookie().c_str(),
+ binding_->magic_cookie().size());
+ msg.AddAttribute(magic_cookie_attr);
+
+ StunAddressAttribute* addr_attr =
+ StunAttribute::CreateAddress(STUN_ATTR_SOURCE_ADDRESS2);
+ addr_attr->SetFamily(1);
+ addr_attr->SetIP(from_addr.ip());
+ addr_attr->SetPort(from_addr.port());
+ msg.AddAttribute(addr_attr);
+
+ StunByteStringAttribute* data_attr =
+ StunAttribute::CreateByteString(STUN_ATTR_DATA);
+ ASSERT(size <= 65536);
+ data_attr->CopyBytes(data, uint16(size));
+ msg.AddAttribute(data_attr);
+
+ SendStun(msg);
+}
+
+void RelayServerConnection::SendStun(const StunMessage& msg) {
+ // Note that the binding has been used again.
+ binding_->NoteUsed();
+
+ cricket::SendStun(msg, socket_, addr_pair_.source());
+}
+
+void RelayServerConnection::SendStunError(
+ const StunMessage& request, int error_code, const char* error_desc) {
+ // An error does not indicate use. If no legitimate use off the binding
+ // occurs, we want it to be cleaned up even if errors are still occuring.
+
+ cricket::SendStunError(
+ request, socket_, addr_pair_.source(), error_code, error_desc,
+ binding_->magic_cookie());
+}
+
+void RelayServerConnection::Lock() {
+ locked_ = true;
+}
+
+void RelayServerConnection::Unlock() {
+ locked_ = false;
+}
+
+// IDs used for posted messages:
+const uint32 MSG_LIFETIME_TIMER = 1;
+
+RelayServerBinding::RelayServerBinding(
+ RelayServer* server, const std::string& username,
+ const std::string& password, uint32 lifetime)
+ : server_(server), username_(username), password_(password),
+ lifetime_(lifetime) {
+ // For now, every connection uses the standard magic cookie value.
+ magic_cookie_.append(
+ reinterpret_cast<const char*>(STUN_MAGIC_COOKIE_VALUE), 4);
+
+ // Initialize the last-used time to now.
+ NoteUsed();
+
+ // Set the first timeout check.
+ server_->thread()->PostDelayed(lifetime_, this, MSG_LIFETIME_TIMER);
+}
+
+RelayServerBinding::~RelayServerBinding() {
+ // Clear the outstanding timeout check.
+ server_->thread()->Clear(this);
+
+ // Clean up all of the connections.
+ for (size_t i = 0; i < internal_connections_.size(); ++i)
+ delete internal_connections_[i];
+ for (size_t i = 0; i < external_connections_.size(); ++i)
+ delete external_connections_[i];
+
+ // Remove this binding from the server's map.
+ server_->RemoveBinding(this);
+}
+
+void RelayServerBinding::AddInternalConnection(RelayServerConnection* conn) {
+ internal_connections_.push_back(conn);
+}
+
+void RelayServerBinding::AddExternalConnection(RelayServerConnection* conn) {
+ external_connections_.push_back(conn);
+}
+
+void RelayServerBinding::NoteUsed() {
+ last_used_ = talk_base::Time();
+}
+
+bool RelayServerBinding::HasMagicCookie(const char* bytes, size_t size) const {
+ if (size < 24 + magic_cookie_.size()) {
+ return false;
+ } else {
+ return 0 == std::memcmp(
+ bytes + 24, magic_cookie_.c_str(), magic_cookie_.size());
+ }
+}
+
+RelayServerConnection* RelayServerBinding::GetInternalConnection(
+ const talk_base::SocketAddress& ext_addr) {
+
+ // Look for an internal connection that is locked to this address.
+ for (size_t i = 0; i < internal_connections_.size(); ++i) {
+ if (internal_connections_[i]->locked() &&
+ (ext_addr == internal_connections_[i]->default_destination()))
+ return internal_connections_[i];
+ }
+
+ // If one was not found, we send to the first connection.
+ ASSERT(internal_connections_.size() > 0);
+ return internal_connections_[0];
+}
+
+RelayServerConnection* RelayServerBinding::GetExternalConnection(
+ const talk_base::SocketAddress& ext_addr) {
+ for (size_t i = 0; i < external_connections_.size(); ++i) {
+ if (ext_addr == external_connections_[i]->addr_pair().source())
+ return external_connections_[i];
+ }
+ return 0;
+}
+
+void RelayServerBinding::OnMessage(talk_base::Message *pmsg) {
+ if (pmsg->message_id == MSG_LIFETIME_TIMER) {
+ ASSERT(!pmsg->pdata);
+
+ // If the lifetime timeout has been exceeded, then send a signal.
+ // Otherwise, just keep waiting.
+ if (talk_base::Time() >= last_used_ + lifetime_) {
+ LOG(LS_INFO) << "Expiring binding " << username_;
+ SignalTimeout(this);
+ } else {
+ server_->thread()->PostDelayed(lifetime_, this, MSG_LIFETIME_TIMER);
+ }
+
+ } else {
+ ASSERT(false);
+ }
+}
+
+} // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/relayserver.h b/third_party/libjingle/source/talk/p2p/base/relayserver.h
new file mode 100644
index 0000000..3337991
--- /dev/null
+++ b/third_party/libjingle/source/talk/p2p/base/relayserver.h
@@ -0,0 +1,241 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * 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. The name of the author may not 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.
+ */
+
+#ifndef __RELAYSERVER_H__
+#define __RELAYSERVER_H__
+
+#include "talk/base/asyncudpsocket.h"
+#include "talk/base/socketaddresspair.h"
+#include "talk/base/thread.h"
+#include "talk/base/time.h"
+#include "talk/p2p/base/port.h"
+#include "talk/p2p/base/stun.h"
+
+#include <string>
+#include <vector>
+#include <map>
+
+namespace cricket {
+
+class RelayServerBinding;
+class RelayServerConnection;
+
+// Relays traffic between connections to the server that are "bound" together.
+// All connections created with the same username/password are bound together.
+class RelayServer : public talk_base::MessageHandler,
+ public sigslot::has_slots<> {
+public:
+ // Creates a server, which will use this thread to post messages to itself.
+ RelayServer(talk_base::Thread* thread);
+ ~RelayServer();
+
+ talk_base::Thread* thread() { return thread_; }
+
+ // Indicates whether we will print updates of the number of bindings.
+ bool log_bindings() const { return log_bindings_; }
+ void set_log_bindings(bool log_bindings) { log_bindings_ = log_bindings; }
+
+ // Updates the set of sockets that the server uses to talk to "internal"
+ // clients. These are clients that do the "port allocations".
+ void AddInternalSocket(talk_base::AsyncPacketSocket* socket);
+ void RemoveInternalSocket(talk_base::AsyncPacketSocket* socket);
+
+ // Updates the set of sockets that the server uses to talk to "external"
+ // clients. These are the clients that do not do allocations. They do not
+ // know that these addresses represent a relay server.
+ void AddExternalSocket(talk_base::AsyncPacketSocket* socket);
+ void RemoveExternalSocket(talk_base::AsyncPacketSocket* socket);
+
+ // Starts listening for connections on this sockets. When someone
+ // tries to connect, the connection will be accepted and a new
+ // internal socket will be added.
+ void AddInternalServerSocket(talk_base::AsyncSocket* socket,
+ cricket::ProtocolType proto);
+
+ // Removes this server socket from the list.
+ void RemoveInternalServerSocket(talk_base::AsyncSocket* socket);
+
+ int GetConnectionCount();
+
+ bool HasConnection(const talk_base::SocketAddress& address);
+
+private:
+ typedef std::vector<talk_base::AsyncPacketSocket*> SocketList;
+ typedef std::map<talk_base::AsyncSocket*,
+ cricket::ProtocolType> ServerSocketMap;
+ typedef std::map<std::string,RelayServerBinding*> BindingMap;
+ typedef std::map<talk_base::SocketAddressPair,RelayServerConnection*> ConnectionMap;
+
+ talk_base::Thread* thread_;
+ bool log_bindings_;
+ SocketList internal_sockets_;
+ SocketList external_sockets_;
+ ServerSocketMap server_sockets_;
+ BindingMap bindings_;
+ ConnectionMap connections_;
+
+ // Called when a packet is received by the server on one of its sockets.
+ void OnInternalPacket(
+ const char* bytes, size_t size, const talk_base::SocketAddress& remote_addr,
+ talk_base::AsyncPacketSocket* socket);
+ void OnExternalPacket(
+ const char* bytes, size_t size, const talk_base::SocketAddress& remote_addr,
+ talk_base::AsyncPacketSocket* socket);
+
+ void OnReadEvent(talk_base::AsyncSocket* socket);
+
+ // Processes the relevant STUN request types from the client.
+ bool HandleStun(const char* bytes, size_t size,
+ const talk_base::SocketAddress& remote_addr, talk_base::AsyncPacketSocket* socket,
+ std::string* username, StunMessage* msg);
+ void HandleStunAllocate(const char* bytes, size_t size,
+ const talk_base::SocketAddressPair& ap,
+ talk_base::AsyncPacketSocket* socket);
+ void HandleStun(RelayServerConnection* int_conn, const char* bytes,
+ size_t size);
+ void HandleStunAllocate(RelayServerConnection* int_conn,
+ const StunMessage& msg);
+ void HandleStunSend(RelayServerConnection* int_conn, const StunMessage& msg);
+
+ // Adds/Removes the a connection or binding.
+ void AddConnection(RelayServerConnection* conn);
+ void RemoveConnection(RelayServerConnection* conn);
+ void RemoveBinding(RelayServerBinding* binding);
+
+ // Handle messages in our worker thread.
+ void OnMessage(talk_base::Message *pmsg);
+
+ // Called when the timer for checking lifetime times out.
+ void OnTimeout(RelayServerBinding* binding);
+
+ // Accept connections on this server socket.
+ void AcceptConnection(talk_base::AsyncSocket* server_socket);
+
+ friend class RelayServerConnection;
+ friend class RelayServerBinding;
+};
+
+// Maintains information about a connection to the server. Each connection is
+// part of one and only one binding.
+class RelayServerConnection {
+public:
+ RelayServerConnection(RelayServerBinding* binding,
+ const talk_base::SocketAddressPair& addrs,
+ talk_base::AsyncPacketSocket* socket);
+ ~RelayServerConnection();
+
+ RelayServerBinding* binding() { return binding_; }
+ talk_base::AsyncPacketSocket* socket() { return socket_; }
+
+ // Returns a pair where the source is the remote address and the destination
+ // is the local address.
+ const talk_base::SocketAddressPair& addr_pair() { return addr_pair_; }
+
+ // Sends a packet to the connected client. If an address is provided, then
+ // we make sure the internal client receives it, wrapping if necessary.
+ void Send(const char* data, size_t size);
+ void Send(const char* data, size_t size, const talk_base::SocketAddress& ext_addr);
+
+ // Sends a STUN message to the connected client with no wrapping.
+ void SendStun(const StunMessage& msg);
+ void SendStunError(const StunMessage& request, int code, const char* desc);
+
+ // A locked connection is one for which we know the intended destination of
+ // any raw packet received.
+ bool locked() const { return locked_; }
+ void Lock();
+ void Unlock();
+
+ // Records the address that raw packets should be forwarded to (for internal
+ // packets only; for external, we already know where they go).
+ const talk_base::SocketAddress& default_destination() const { return default_dest_; }
+ void set_default_destination(const talk_base::SocketAddress& addr) {
+ default_dest_ = addr;
+ }
+
+private:
+ RelayServerBinding* binding_;
+ talk_base::SocketAddressPair addr_pair_;
+ talk_base::AsyncPacketSocket* socket_;
+ bool locked_;
+ talk_base::SocketAddress default_dest_;
+};
+
+// Records a set of internal and external connections that we relay between,
+// or in other words, that are "bound" together.
+class RelayServerBinding : public talk_base::MessageHandler {
+public:
+ RelayServerBinding(
+ RelayServer* server, const std::string& username,
+ const std::string& password, uint32 lifetime);
+ virtual ~RelayServerBinding();
+
+ RelayServer* server() { return server_; }
+ uint32 lifetime() { return lifetime_; }
+ const std::string& username() { return username_; }
+ const std::string& password() { return password_; }
+ const std::string& magic_cookie() { return magic_cookie_; }
+
+ // Adds/Removes a connection into the binding.
+ void AddInternalConnection(RelayServerConnection* conn);
+ void AddExternalConnection(RelayServerConnection* conn);
+
+ // We keep track of the use of each binding. If we detect that it was not
+ // used for longer than the lifetime, then we send a signal.
+ void NoteUsed();
+ sigslot::signal1<RelayServerBinding*> SignalTimeout;
+
+ // Determines whether the given packet has the magic cookie present (in the
+ // right place).
+ bool HasMagicCookie(const char* bytes, size_t size) const;
+
+ // Determines the connection to use to send packets to or from the given
+ // external address.
+ RelayServerConnection* GetInternalConnection(const talk_base::SocketAddress& ext_addr);
+ RelayServerConnection* GetExternalConnection(const talk_base::SocketAddress& ext_addr);
+
+ // MessageHandler:
+ void OnMessage(talk_base::Message *pmsg);
+
+private:
+ RelayServer* server_;
+
+ std::string username_;
+ std::string password_;
+ std::string magic_cookie_;
+
+ std::vector<RelayServerConnection*> internal_connections_;
+ std::vector<RelayServerConnection*> external_connections_;
+
+ uint32 lifetime_;
+ uint32 last_used_;
+ // TODO: bandwidth
+};
+
+} // namespace cricket
+
+#endif // __RELAYSERVER_H__
diff --git a/third_party/libjingle/source/talk/p2p/base/relayserver_main.cc b/third_party/libjingle/source/talk/p2p/base/relayserver_main.cc
new file mode 100644
index 0000000..2f07458
--- /dev/null
+++ b/third_party/libjingle/source/talk/p2p/base/relayserver_main.cc
@@ -0,0 +1,80 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * 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. The name of the author may not 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.
+ */
+
+#include <iostream> // NOLINT
+
+#include "talk/base/thread.h"
+#include "talk/base/scoped_ptr.h"
+#include "talk/p2p/base/relayserver.h"
+
+int main(int argc, char **argv) {
+ if (argc != 3) {
+ std::cerr << "usage: relayserver internal-address external-address"
+ << std::endl;
+ return 1;
+ }
+
+ talk_base::SocketAddress int_addr;
+ if (!int_addr.FromString(argv[1])) {
+ std::cerr << "Unable to parse IP address: " << argv[1];
+ return 1;
+ }
+
+ talk_base::SocketAddress ext_addr;
+ if (!ext_addr.FromString(argv[2])) {
+ std::cerr << "Unable to parse IP address: " << argv[2];
+ return 1;
+ }
+
+ talk_base::Thread *pthMain = talk_base::Thread::Current();
+
+ talk_base::scoped_ptr<talk_base::AsyncUDPSocket> int_socket(
+ talk_base::CreateAsyncUDPSocket(pthMain->socketserver()));
+ if (int_socket->Bind(int_addr) < 0) {
+ std::cerr << "Internal socket bind(" << int_addr.ToString() << "): "
+ << std::strerror(int_socket->GetError()) << std::endl;
+ return 1;
+ }
+
+ talk_base::scoped_ptr<talk_base::AsyncUDPSocket> ext_socket(
+ talk_base::CreateAsyncUDPSocket(pthMain->socketserver()));
+ if (ext_socket->Bind(ext_addr) < 0) {
+ std::cerr << "External socket bind(" << ext_addr.ToString() << "): "
+ << std::strerror(ext_socket->GetError()) << std::endl;
+ return 1;
+ }
+
+ cricket::RelayServer server(pthMain);
+ server.AddInternalSocket(int_socket.get());
+ server.AddExternalSocket(ext_socket.get());
+
+ std::cout << "Listening internally at " << int_addr.ToString() << std::endl;
+ std::cout << "Listening externally at " << ext_addr.ToString() << std::endl;
+
+ pthMain->Run();
+ return 0;
+}
diff --git a/third_party/libjingle/source/talk/p2p/base/sessiondescription.cc b/third_party/libjingle/source/talk/p2p/base/sessiondescription.cc
new file mode 100644
index 0000000..5fef38b
--- /dev/null
+++ b/third_party/libjingle/source/talk/p2p/base/sessiondescription.cc
@@ -0,0 +1,62 @@
+/*
+ * libjingle
+ * Copyright 2010, Google Inc.
+ *
+ * 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. The name of the author may not 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.
+ */
+
+#include "talk/p2p/base/sessiondescription.h"
+
+#include "talk/xmllite/xmlelement.h"
+
+namespace cricket {
+
+const ContentInfo* SessionDescription::GetContentByName(
+ const std::string& name) const {
+ for (std::vector<ContentInfo>::const_iterator content = contents_.begin();
+ content != contents_.end(); content++) {
+ if (content->name == name) {
+ return &(*content);
+ }
+ }
+ return NULL;
+}
+
+const ContentInfo* SessionDescription::FirstContentByType(
+ const std::string& type) const {
+ for (std::vector<ContentInfo>::const_iterator content = contents_.begin();
+ content != contents_.end(); content++) {
+ if (content->type == type) {
+ return &(*content);
+ }
+ }
+ return NULL;
+}
+
+void SessionDescription::AddContent(const std::string& name,
+ const std::string& type,
+ const ContentDescription* description) {
+ contents_.push_back(ContentInfo(name, type, description));
+}
+
+} // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/stunserver.cc b/third_party/libjingle/source/talk/p2p/base/stunserver.cc
new file mode 100644
index 0000000..1ff02ee
--- /dev/null
+++ b/third_party/libjingle/source/talk/p2p/base/stunserver.cc
@@ -0,0 +1,159 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * 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. The name of the author may not 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.
+ */
+
+#ifdef POSIX
+#include <errno.h>
+#endif // POSIX
+
+#include "talk/p2p/base/stunserver.h"
+#include "talk/base/bytebuffer.h"
+#include "talk/base/logging.h"
+
+namespace cricket {
+
+StunServer::StunServer(talk_base::AsyncUDPSocket* socket) : socket_(socket) {
+ socket_->SignalReadPacket.connect(this, &StunServer::OnPacket);
+}
+
+StunServer::~StunServer() {
+ socket_->SignalReadPacket.disconnect(this);
+}
+
+void StunServer::OnPacket(
+ const char* buf, size_t size, const talk_base::SocketAddress& remote_addr,
+ talk_base::AsyncPacketSocket* socket) {
+
+ // TODO: If appropriate, look for the magic cookie before parsing.
+
+ // Parse the STUN message.
+ talk_base::ByteBuffer bbuf(buf, size);
+ StunMessage msg;
+ if (!msg.Read(&bbuf)) {
+ SendErrorResponse(msg, remote_addr, 400, "Bad Request");
+ return;
+ }
+
+ // TODO: If this is UDP, then we shouldn't allow non-fully-parsed messages.
+
+ // TODO: If unknown non-optiional (<= 0x7fff) attributes are found, send a
+ // 420 "Unknown Attribute" response.
+
+ // TODO: Check that a message-integrity attribute was given (or send 401
+ // "Unauthorized"). Check that a username attribute was given (or send
+ // 432 "Missing Username"). Look up the username and password. If it
+ // is missing or the HMAC is wrong, send 431 "Integrity Check Failure".
+
+ // Send the message to the appropriate handler function.
+ switch (msg.type()) {
+ case STUN_BINDING_REQUEST:
+ OnBindingRequest(&msg, remote_addr);
+ return;
+
+ case STUN_ALLOCATE_REQUEST:
+ OnAllocateRequest(&msg, remote_addr);
+ return;
+
+ default:
+ SendErrorResponse(msg, remote_addr, 600, "Operation Not Supported");
+ }
+}
+
+void StunServer::OnBindingRequest(
+ StunMessage* msg, const talk_base::SocketAddress& remote_addr) {
+ StunMessage response;
+ response.SetType(STUN_BINDING_RESPONSE);
+ response.SetTransactionID(msg->transaction_id());
+
+ // Tell the user the address that we received their request from.
+ StunAddressAttribute* mapped_addr =
+ StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
+ mapped_addr->SetFamily(1);
+ mapped_addr->SetPort(remote_addr.port());
+ mapped_addr->SetIP(remote_addr.ip());
+ response.AddAttribute(mapped_addr);
+
+ // Tell the user the address that we are sending the response from.
+ talk_base::SocketAddress local_addr = socket_->GetLocalAddress();
+ StunAddressAttribute* source_addr =
+ StunAttribute::CreateAddress(STUN_ATTR_SOURCE_ADDRESS);
+ source_addr->SetFamily(1);
+ source_addr->SetPort(local_addr.port());
+ source_addr->SetIP(local_addr.ip());
+ response.AddAttribute(source_addr);
+
+ // TODO: Add username and message-integrity.
+
+ // TODO: Add changed-address. (Keep information about three other servers.)
+
+ SendResponse(response, remote_addr);
+}
+
+void StunServer::OnAllocateRequest(
+ StunMessage* msg, const talk_base::SocketAddress& addr) {
+ SendErrorResponse(*msg, addr, 600, "Operation Not Supported");
+}
+
+void StunServer::OnSharedSecretRequest(
+ StunMessage* msg, const talk_base::SocketAddress& addr) {
+ SendErrorResponse(*msg, addr, 600, "Operation Not Supported");
+}
+
+void StunServer::OnSendRequest(StunMessage* msg,
+ const talk_base::SocketAddress& addr) {
+ SendErrorResponse(*msg, addr, 600, "Operation Not Supported");
+}
+
+void StunServer::SendErrorResponse(
+ const StunMessage& msg, const talk_base::SocketAddress& addr,
+ int error_code, const char* error_desc) {
+
+ StunMessage err_msg;
+ err_msg.SetType(GetStunErrorResponseType(msg.type()));
+ err_msg.SetTransactionID(msg.transaction_id());
+
+ StunErrorCodeAttribute* err_code = StunAttribute::CreateErrorCode();
+ err_code->SetErrorClass(error_code / 100);
+ err_code->SetNumber(error_code % 100);
+ err_code->SetReason(error_desc);
+ err_msg.AddAttribute(err_code);
+
+ SendResponse(err_msg, addr);
+}
+
+void StunServer::SendResponse(
+ const StunMessage& msg, const talk_base::SocketAddress& addr) {
+
+ talk_base::ByteBuffer buf;
+ msg.Write(&buf);
+
+ // TODO: Allow response addr attribute if sent from another stun server.
+
+ if (socket_->SendTo(buf.Data(), buf.Length(), addr) < 0)
+ LOG_ERR(LS_ERROR) << "sendto";
+}
+
+} // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/stunserver.h b/third_party/libjingle/source/talk/p2p/base/stunserver.h
new file mode 100644
index 0000000..83ac174
--- /dev/null
+++ b/third_party/libjingle/source/talk/p2p/base/stunserver.h
@@ -0,0 +1,77 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * 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. The name of the author may not 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.
+ */
+
+#ifndef TALK_P2P_BASE_STUNSERVER_H_
+#define TALK_P2P_BASE_STUNSERVER_H_
+
+#include "talk/base/asyncudpsocket.h"
+#include "talk/base/scoped_ptr.h"
+#include "talk/p2p/base/stun.h"
+
+namespace cricket {
+
+const int STUN_SERVER_PORT = 3478;
+
+class StunServer : public sigslot::has_slots<> {
+ public:
+ // Creates a STUN server, which will listen on the given socket.
+ explicit StunServer(talk_base::AsyncUDPSocket* socket);
+ // Removes the STUN server from the socket and deletes the socket.
+ ~StunServer();
+
+ protected:
+ // Slot for AsyncSocket.PacketRead:
+ void OnPacket(
+ const char* buf, size_t size, const talk_base::SocketAddress& remote_addr,
+ talk_base::AsyncPacketSocket* socket);
+
+ // Handlers for the different types of STUN/TURN requests:
+ void OnBindingRequest(StunMessage* msg,
+ const talk_base::SocketAddress& addr);
+ void OnAllocateRequest(StunMessage* msg,
+ const talk_base::SocketAddress& addr);
+ void OnSharedSecretRequest(StunMessage* msg,
+ const talk_base::SocketAddress& addr);
+ void OnSendRequest(StunMessage* msg,
+ const talk_base::SocketAddress& addr);
+
+ // Sends an error response to the given message back to the user.
+ void SendErrorResponse(
+ const StunMessage& msg, const talk_base::SocketAddress& addr,
+ int error_code, const char* error_desc);
+
+ // Sends the given message to the appropriate destination.
+ void SendResponse(const StunMessage& msg,
+ const talk_base::SocketAddress& addr);
+
+ private:
+ talk_base::scoped_ptr<talk_base::AsyncUDPSocket> socket_;
+};
+
+} // namespace cricket
+
+#endif // TALK_P2P_BASE_STUNSERVER_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/stunserver_main.cc b/third_party/libjingle/source/talk/p2p/base/stunserver_main.cc
new file mode 100644
index 0000000..e4a2df6
--- /dev/null
+++ b/third_party/libjingle/source/talk/p2p/base/stunserver_main.cc
@@ -0,0 +1,69 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * 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. The name of the author may not 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.
+ */
+
+#ifdef POSIX
+#include <errno.h>
+#endif // POSIX
+
+#include <iostream>
+
+#include "talk/base/host.h"
+#include "talk/base/thread.h"
+#include "talk/p2p/base/stunserver.h"
+
+using namespace cricket;
+
+int main(int argc, char* argv[]) {
+ if (argc != 2) {
+ std::cerr << "usage: stunserver address" << std::endl;
+ return 1;
+ }
+
+ talk_base::SocketAddress server_addr;
+ if (!server_addr.FromString(argv[1])) {
+ std::cerr << "Unable to parse IP address: " << argv[1];
+ return 1;
+ }
+
+ talk_base::Thread *pthMain = talk_base::Thread::Current();
+
+ talk_base::AsyncUDPSocket* server_socket =
+ talk_base::CreateAsyncUDPSocket(pthMain->socketserver());
+ if (server_socket->Bind(server_addr) < 0) {
+ std::cerr << "bind: " << std::strerror(errno) << std::endl;
+ return 1;
+ }
+
+ StunServer* server = new StunServer(server_socket);
+
+ std::cout << "Listening at " << server_addr.ToString() << std::endl;
+
+ pthMain->Run();
+
+ delete server;
+ return 0;
+}
diff --git a/third_party/libjingle/source/talk/session/phone/devicemanager_mac.mm b/third_party/libjingle/source/talk/session/phone/devicemanager_mac.mm
new file mode 100644
index 0000000..1a14e95
--- /dev/null
+++ b/third_party/libjingle/source/talk/session/phone/devicemanager_mac.mm
@@ -0,0 +1,68 @@
+/*
+ * libjingle
+ * Copyright 2004--2010, Google Inc.
+ *
+ * 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. The name of the author may not 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.
+ */
+
+#include "talk/session/phone/devicemanager.h"
+
+#import <QTKit/QTKit.h>
+
+#include "talk/base/logging.h"
+
+namespace cricket {
+
+bool GetQTKitVideoDevices(std::vector<Device>* devices) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ NSArray* qt_capture_devices =
+ [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo];
+ NSUInteger count = [qt_capture_devices count];
+ LOG(LS_INFO) << count << " capture device(s) found:";
+ for (NSUInteger i = 0; i < count; ++i) {
+ QTCaptureDevice* qt_capture_device = [qt_capture_devices objectAtIndex:i];
+
+ static const NSString* kFormat = @"localizedDisplayName: \"%@\", "
+ "modelUniqueID: \"%@\", isConnected: %d, isOpen: %d, "
+ "isInUseByAnotherApplication: %d";
+ NSString* info = [NSString stringWithFormat:kFormat,
+ [qt_capture_device localizedDisplayName],
+ [qt_capture_device modelUniqueID],
+ [qt_capture_device isConnected],
+ [qt_capture_device isOpen],
+ [qt_capture_device isInUseByAnotherApplication]];
+ LOG(LS_INFO) << [info cStringUsingEncoding:NSUTF8StringEncoding];
+
+ std::string name([[qt_capture_device localizedDisplayName]
+ cStringUsingEncoding:NSUTF8StringEncoding]);
+ devices->push_back(Device(name,
+ [[qt_capture_device modelUniqueID]
+ cStringUsingEncoding:NSUTF8StringEncoding]));
+ }
+
+ [pool drain];
+ return true;
+}
+
+} // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/videocommon.h b/third_party/libjingle/source/talk/session/phone/videocommon.h
new file mode 100644
index 0000000..1092b5c
--- /dev/null
+++ b/third_party/libjingle/source/talk/session/phone/videocommon.h
@@ -0,0 +1,161 @@
+// libjingle
+// Copyright 2004--2005, Google Inc.
+//
+// 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. The name of the author may not 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.
+//
+// Common definition for video, including fourcc and VideoFormat
+
+#ifndef TALK_SESSION_PHONE_VIDEOCOMMON_H_
+#define TALK_SESSION_PHONE_VIDEOCOMMON_H_
+
+#include <string>
+
+#include "talk/base/basictypes.h"
+
+namespace cricket {
+
+//////////////////////////////////////////////////////////////////////////////
+// Definition of fourcc.
+//////////////////////////////////////////////////////////////////////////////
+// Convert four characters to a fourcc code.
+// Needs to be a macro otherwise the OS X compiler complains when the kFormat*
+// constants are used in a switch.
+#define FOURCC(a, b, c, d) (\
+ (static_cast<uint32>(a)) | (static_cast<uint32>(b) << 8) | \
+ (static_cast<uint32>(c) << 16) | (static_cast<uint32>(d) << 24))
+
+// Get the name, that is, string with four characters, of a fourcc code.
+inline std::string GetFourccName(uint32 fourcc) {
+ std::string name;
+ name.push_back(static_cast<char>(fourcc & 0xFF));
+ name.push_back(static_cast<char>((fourcc >> 8) & 0xFF));
+ name.push_back(static_cast<char>((fourcc >> 16) & 0xFF));
+ name.push_back(static_cast<char>((fourcc >> 24) & 0xFF));
+ return name;
+}
+
+// FourCC codes used in Google Talk.
+// Some good pages discussing FourCC codes:
+// http://developer.apple.com/quicktime/icefloe/dispatch020.html
+// http://www.fourcc.org/yuv.php
+enum {
+ FOURCC_I420 = FOURCC('I', '4', '2', '0'),
+ FOURCC_IYUV = FOURCC('I', 'Y', 'U', 'V'), // Alias for I420
+ FOURCC_YU12 = FOURCC('Y', 'U', '1', '2'), // Alias for I420
+ FOURCC_YUY2 = FOURCC('Y', 'U', 'Y', '2'),
+ FOURCC_UYVY = FOURCC('U', 'Y', 'V', 'Y'),
+ FOURCC_HDYC = FOURCC('H', 'D', 'Y', 'C'),
+ FOURCC_24BG = FOURCC('2', '4', 'B', 'G'),
+ FOURCC_RGB1 = FOURCC('R', 'G', 'B', '1'),
+ FOURCC_RGBA = FOURCC('R', 'G', 'B', 'A'),
+ FOURCC_RGB2 = FOURCC('R', 'G', 'B', '2'),
+ FOURCC_ARGB = FOURCC('A', 'R', 'G', 'B'),
+ FOURCC_BGRA = FOURCC('B', 'G', 'R', 'A'),
+ FOURCC_MJPG = FOURCC('M', 'J', 'P', 'G'),
+ FOURCC_JPEG = FOURCC('J', 'P', 'E', 'G'),
+ FOURCC_2VUY = FOURCC('2', 'v', 'u', 'y'), // Alias for UYVY
+ FOURCC_YUVS = FOURCC('y', 'u', 'v', 's'), // Alias for YUY2
+ FOURCC_YUYV = FOURCC('Y', 'U', 'Y', 'V'), // Alias for YUY2
+ FOURCC_RAW = FOURCC('r', 'a', 'w', ' '),
+ // Next five are Bayer RGB formats. The four characters define the order of
+ // the colours in each 2x2 pixel grid, going left-to-right and top-to-bottom.
+ FOURCC_RGGB = FOURCC('R', 'G', 'G', 'B'),
+ FOURCC_BGGR = FOURCC('B', 'G', 'G', 'R'),
+ FOURCC_GRBG = FOURCC('G', 'R', 'B', 'G'),
+ FOURCC_GBRG = FOURCC('G', 'B', 'R', 'G'),
+ FOURCC_BA81 = FOURCC('B', 'A', '8', '1'), // Alias for BGGR
+ FOURCC_ANY = 0xFFFFFFFF, // Match any fourcc.
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// Definition of VideoFormat.
+//////////////////////////////////////////////////////////////////////////////
+
+static const int64 kNumNanosecsPerSec = 1000000000;
+
+struct VideoFormat {
+ static const int64 kMinimumInterval = kNumNanosecsPerSec / 10000; // 10k fps
+
+ VideoFormat() : width(0), height(0), interval(0), fourcc(0) {}
+
+ VideoFormat(int w, int h, int64 interval_ns, uint32 cc)
+ : width(w),
+ height(h),
+ interval(interval_ns),
+ fourcc(cc) {
+ }
+
+ VideoFormat(const VideoFormat& format)
+ : width(format.width),
+ height(format.height),
+ interval(format.interval),
+ fourcc(format.fourcc) {
+ }
+
+ static int64 FpsToInterval(int fps) {
+ return fps ? kNumNanosecsPerSec / fps : kMinimumInterval;
+ }
+
+ static int IntervalToFps(int64 interval) {
+ // Normalize the interval first.
+ interval = talk_base::_max(interval, kMinimumInterval);
+ return static_cast<int>(kNumNanosecsPerSec / interval);
+ }
+
+ bool operator==(const VideoFormat& format) const {
+ return width == format.width && height == format.height &&
+ interval == format.interval && fourcc == format.fourcc;
+ }
+
+ bool operator!=(const VideoFormat& format) const {
+ return !(*this == format);
+ }
+
+ bool operator<(const VideoFormat& format) const {
+ return (fourcc < format.fourcc) ||
+ (fourcc == format.fourcc && width < format.width) ||
+ (fourcc == format.fourcc && width == format.width &&
+ height < format.height) ||
+ (fourcc == format.fourcc && width == format.width &&
+ height == format.height && interval > format.interval);
+ }
+
+ int framerate() const { return IntervalToFps(interval); }
+
+ int width; // in number of pixels
+ int height; // in number of pixels
+ int64 interval; // in nanoseconds
+ uint32 fourcc; // color space. FOURCC_ANY means that any color space is OK.
+};
+
+// Result of video capturer start.
+enum CaptureResult {
+ CR_SUCCESS, // The capturer starts successfully.
+ CR_PENDING, // The capturer is pending to start the capture device.
+ CR_FAILURE, // The capturer fails to start.
+ CR_NO_DEVICE, // The capturer has no device and fails to start.
+};
+
+} // namespace cricket
+
+#endif // TALK_SESSION_PHONE_VIDEOCOMMON_H_