diff options
author | Kristian Monsen <kristianm@google.com> | 2010-10-27 21:32:02 +0100 |
---|---|---|
committer | Kristian Monsen <kristianm@google.com> | 2010-10-27 21:32:02 +0100 |
commit | 1391b24619d56bae6ce14bb54ed0fb16a945e853 (patch) | |
tree | fbd465b79fe889aa53ee313b2a2b280b37a497d8 /third_party | |
parent | c77745f79a9f73c4e2d409f8ebc8b031fce6ca75 (diff) | |
download | external_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')
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_ |