•  绝大部分iOS程序的后台服务都是基于RESTful或者WebService的,不论在任何时候,你都应该将服务置于HTTPS上,因为它可以避免中间人攻击的问题,还自带了基于非对称密钥的加密通道!现实是这些年涌现了大量速成的...

      友情提示:本文使用的AFNetworking是最新git pull的2.3.1版本,如果想确认你机器上的AFNetworking版本,请打git tag命令查看。

      绝大部分iOS程序的后台服务都是基于RESTful或者WebService的,不论在任何时候,你都应该将服务置于HTTPS上,因为它可以避免中间人攻击的问题,还自带了基于非对称密钥的加密通道!现实是这些年涌现了大量速成的移动端开发人员,这些人往往基础很差,完全不了解加解密为何物,使用HTTPS后,可以省去教育他们各种加解密技术,生活轻松多了。

      使用HTTPS有个问题,就是CA证书。缺省情况下,iOS要求连接的HTTPS站点必须为CA签名过的合法证书,AFNetworking是个iOS上常用的HTTP访问库,由于它是基于iOS的HTTP网络通讯库,自然证书方面的要求和系统是一致的,也就是你需要有一张合法的站点证书。

      正式的CA证书非常昂贵,很多人都知道,AFNetworking2只要通过下面的代码,你就可以使用自签证书来访问HTTPS

    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
    securityPolicy.allowInvalidCertificates = YES;
    

      这么做有个问题,就是你无法验证证书是否是你的服务器后端的证书,给中间人攻击,即通过重定向路由来分析伪造你的服务器端打开了大门。

      解决方法。AFNetworking2是允许内嵌证书的,通过内嵌证书,AFNetworking2就通过比对服务器端证书、内嵌的证书、站点域名是否一致来验证连接的服务器是否正确。由于CA证书验证是通过站点域名进行验证的,如果你的服务器后端有绑定的域名,这是最方便的。将你的服务器端证书,如果是pem格式的,用下面的命令转成cer格式

    openssl x509 -in <你的服务器证书>.pem -outform der -out server.cer
    然后将生成的server.cer文件,如果有自建ca,再加上ca的cer格式证书,引入到app的bundle里,AFNetworking2在

    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy AFSSLPinningModeCertificate];
    或者
    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy AFSSLPinningModePublicKey];
    securityPolicy.allowInvalidCertificates = YES; //还是必须设成YES

    情况下,会自动扫描bundle中.cer的文件,并引入,这样就可以通过自签证书来验证服务器唯一性了。

      我前面说过,验证站点证书,是通过域名的,如果服务器端站点没有绑定域名(万恶的备案),仅靠IP地址上面的方法是绝对不行的。怎么办?答案是想通过设置是不可以的,你只能修改AFNetworking2的源代码!打开AFSecurityPolicy.m文件,找到方法:

    - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust
                      forDomain:(NSString *)domain

    将下面这部分注释掉

    //            SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)pinnedCertificates);
    //
    //            if (!AFServerTrustIsValid(serverTrust)) {
    //                return NO;
    //            }
    //
    //            if (!self.validatesCertificateChain) {
    //                return YES;
    //            }

    这样,AFSecurityPolicy就只会比对服务器证书和内嵌证书是否一致,不会再验证证书是否和站点域名一致了。

      这么做为什么是安全的?了解HTTPS的人都知道,整个验证体系中,最核心的实际上是服务器的私钥。私钥永远,永远也不会离开服务器,或者以任何形式向外传输。私钥和公钥是配对的,如果事先在客户端预留了公钥,只要服务器端的公钥和预留的公钥一致,实际上就已经可以排除中间人攻击了。

    转自:https://my.oschina.net/non6/blog/290175
    侵权请告知

    展开全文
  • socket.io-client-cpp ios 构建 demo 下 有ios demo 第一步1.55.0 安装,ios版本 交叉编译的脚本 #=============================================================================== # Filename: boost.sh # ...

    socket.io-client-cpp ios 构建

    从demo里获取到sioclient.a静态库
    Use sioclient as static lib on iOS

    • There’s a target named sioclient in the Demo project, That is the exactly right config for buiding the sioclient as a static library on iOS. With the static library file libsioclient.a and two exported headers sio_client.h and sio_message.h, you won’t need to config anything again and again in your integrating projects.

    依赖于boost,所以要交叉编译 boost库的ios版本
    由于我的socket io的nodejs服务端是开了ssl的,关了,那么js的sample连不上,所以还是打算给socket io client 增加一个ssl的 sioclient_tls.a

    demo 下 有ios demo ,首先构建boost ios

    • 第一步1.55.0 安装,ios版本
    • 交叉编译的脚本
    #===============================================================================
    # Filename:  boost.sh
    # Author:    Pete Goodliffe
    # Copyright: (c) Copyright 2009 Pete Goodliffe
    # Licence:   Please feel free to use this, with attribution
    # Modified version
    #===============================================================================
    #
    # Builds a Boost framework for the iPhone.
    # Creates a set of universal libraries that can be used on an iPhone and in the
    # iPhone simulator. Then creates a pseudo-framework to make using boost in Xcode
    # less painful.
    #
    # To configure the script, define:
    #    BOOST_LIBS:        which libraries to build
    #    IPHONE_SDKVERSION: iPhone SDK version (e.g. 5.1)
    #
    # Then go get the source tar.bz of the boost you want to build, shove it in the
    # same directory as this script, and run "./boost.sh". Grab a cuppa. And voila.
    #===============================================================================
    
    : ${BOOST_LIBS:="random regex graph random chrono thread signals filesystem system date_time"}
    : ${IPHONE_SDKVERSION:=`xcodebuild -showsdks | grep iphoneos | egrep "[[:digit:]]+\.[[:digit:]]+" -o | tail -1`}
    : ${OSX_SDKVERSION:=10.8}
    : ${XCODE_ROOT:=`xcode-select -print-path`}
    : ${EXTRA_CPPFLAGS:="-DBOOST_AC_USE_PTHREADS -DBOOST_SP_USE_PTHREADS -std=c++11 -stdlib=libc++"}
    
    # The EXTRA_CPPFLAGS definition works around a thread race issue in
    # shared_ptr. I encountered this historically and have not verified that
    # the fix is no longer required. Without using the posix thread primitives
    # an invalid compare-and-swap ARM instruction (non-thread-safe) was used for the
    # shared_ptr use count causing nasty and subtle bugs.
    #
    # Should perhaps also consider/use instead: -BOOST_SP_USE_PTHREADS
    
    : ${TARBALLDIR:=`pwd`}
    : ${SRCDIR:=`pwd`/src}
    : ${IOSBUILDDIR:=`pwd`/ios/build}
    : ${OSXBUILDDIR:=`pwd`/osx/build}
    : ${PREFIXDIR:=`pwd`/ios/prefix}
    : ${IOSFRAMEWORKDIR:=`pwd`/ios/framework}
    : ${OSXFRAMEWORKDIR:=`pwd`/osx/framework}
    : ${COMPILER:="clang++"}
    
    : ${BOOST_VERSION:=1.55.0}
    : ${BOOST_VERSION2:=1_55_0}
    
    BOOST_TARBALL=$TARBALLDIR/boost_$BOOST_VERSION2.tar.bz2
    BOOST_SRC=$SRCDIR/boost_${BOOST_VERSION2}
    
    #===============================================================================
    ARM_DEV_CMD="xcrun --sdk iphoneos"
    SIM_DEV_CMD="xcrun --sdk iphonesimulator"
    OSX_DEV_CMD="xcrun --sdk macosx"
    
    ARM_COMBINED_LIB=$IOSBUILDDIR/lib_boost_arm.a
    SIM_COMBINED_LIB=$IOSBUILDDIR/lib_boost_x86.a
    
    #===============================================================================
    
    
    #===============================================================================
    # Functions
    #===============================================================================
    
    abort()
    {
        echo
        echo "Aborted: $@"
        exit 1
    }
    
    doneSection()
    {
        echo
        echo "================================================================="
        echo "Done"
        echo
    }
    
    #===============================================================================
    
    cleanEverythingReadyToStart()
    {
        echo Cleaning everything before we start to build...
    
        rm -rf iphone-build iphonesim-build osx-build
        rm -rf $IOSBUILDDIR
        rm -rf $OSXBUILDDIR
        rm -rf $PREFIXDIR
        rm -rf $IOSFRAMEWORKDIR/$FRAMEWORK_NAME.framework
        rm -rf $OSXFRAMEWORKDIR/$FRAMEWORK_NAME.framework
    
        doneSection
    }
    
    #===============================================================================
    
    downloadBoost()
    {
        if [ ! -s $TARBALLDIR/boost_${BOOST_VERSION2}.tar.bz2 ]; then
            echo "Downloading boost ${BOOST_VERSION}"
            curl -L -o $TARBALLDIR/boost_${BOOST_VERSION2}.tar.bz2 http://sourceforge.net/projects/boost/files/boost/${BOOST_VERSION}/boost_${BOOST_VERSION2}.tar.bz2/download
        fi
    
        doneSection
    }
    
    #===============================================================================
    
    unpackBoost()
    {
        [ -f "$BOOST_TARBALL" ] || abort "Source tarball missing."
    
        echo Unpacking boost into $SRCDIR...
    
        [ -d $SRCDIR ]    || mkdir -p $SRCDIR
        [ -d $BOOST_SRC ] || ( cd $SRCDIR; tar xfj $BOOST_TARBALL )
        [ -d $BOOST_SRC ] && echo "    ...unpacked as $BOOST_SRC"
    
        doneSection
    }
    
    #===============================================================================
    
    restoreBoost()
    {
        cp $BOOST_SRC/tools/build/v2/user-config.jam-bk $BOOST_SRC/tools/build/v2/user-config.jam
    }
    
    #===============================================================================
    
    updateBoost()
    {
        echo Updating boost into $BOOST_SRC...
    
        cp $BOOST_SRC/tools/build/v2/user-config.jam $BOOST_SRC/tools/build/v2/user-config.jam-bk
    
        cat >> $BOOST_SRC/tools/build/v2/user-config.jam <<EOF
    using darwin : ${IPHONE_SDKVERSION}~iphone
    : $XCODE_ROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/$COMPILER -arch armv6 -arch armv7 -arch armv7s -arch arm64 -fvisibility=hidden -fvisibility-inlines-hidden $EXTRA_CPPFLAGS
    : <striper> <root>$XCODE_ROOT/Platforms/iPhoneOS.platform/Developer
    : <architecture>arm <target-os>iphone
    ;
    using darwin : ${IPHONE_SDKVERSION}~iphonesim
    : $XCODE_ROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/$COMPILER -arch i386 -arch x86_64 -fvisibility=hidden -fvisibility-inlines-hidden $EXTRA_CPPFLAGS
    : <striper> <root>$XCODE_ROOT/Platforms/iPhoneSimulator.platform/Developer
    : <architecture>x86 <target-os>iphone
    ;
    EOF
    
        doneSection
    }
    
    #===============================================================================
    
    inventMissingHeaders()
    {
        # These files are missing in the ARM iPhoneOS SDK, but they are in the simulator.
        # They are supported on the device, so we copy them from x86 SDK to a staging area
        # to use them on ARM, too.
        echo Invent missing headers
    
        cp $XCODE_ROOT/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator${IPHONE_SDKVERSION}.sdk/usr/include/{crt_externs,bzlib}.h $BOOST_SRC
    }
    
    #===============================================================================
    
    bootstrapBoost()
    {
        cd $BOOST_SRC
    
        BOOST_LIBS_COMMA=$(echo $BOOST_LIBS | sed -e "s/ /,/g")
        echo "Bootstrapping (with libs $BOOST_LIBS_COMMA)"
        ./bootstrap.sh --with-libraries=$BOOST_LIBS_COMMA
    
        doneSection
    }
    
    #===============================================================================
    
    buildBoostForIPhoneOS()
    {
        cd $BOOST_SRC
    
        # Install this one so we can copy the includes for the frameworks...
        ./bjam -j16 --build-dir=iphone-build --stagedir=iphone-build/stage --prefix=$PREFIXDIR toolset=darwin architecture=arm target-os=iphone macosx-version=iphone-${IPHONE_SDKVERSION} define=_LITTLE_ENDIAN link=static stage
        ./bjam -j16 --build-dir=iphone-build --stagedir=iphone-build/stage --prefix=$PREFIXDIR toolset=darwin architecture=arm target-os=iphone macosx-version=iphone-${IPHONE_SDKVERSION} define=_LITTLE_ENDIAN link=static install
        doneSection
    
        ./bjam -j16 --build-dir=iphonesim-build --stagedir=iphonesim-build/stage --toolset=darwin-${IPHONE_SDKVERSION}~iphonesim architecture=x86 target-os=iphone macosx-version=iphonesim-${IPHONE_SDKVERSION} link=static stage
        doneSection
    
      #  ./b2 -j16 --build-dir=osx-build --stagedir=osx-build/stage toolset=clang cxxflags="-std=c++11 -stdlib=libc++ -arch i386 -arch x86_64" linkflags="-stdlib=libc++" link=static threading=multi stage
        doneSection
    }
    
    #===============================================================================
    
    scrunchAllLibsTogetherInOneLibPerPlatform()
    {
        cd $BOOST_SRC
    
        mkdir -p $IOSBUILDDIR/armv6/obj
        mkdir -p $IOSBUILDDIR/armv7/obj
        mkdir -p $IOSBUILDDIR/armv7s/obj
    	mkdir -p $IOSBUILDDIR/arm64/obj
        mkdir -p $IOSBUILDDIR/i386/obj
    	mkdir -p $IOSBUILDDIR/x86_64/obj
    
        mkdir -p $OSXBUILDDIR/i386/obj
        mkdir -p $OSXBUILDDIR/x86_64/obj
    
        ALL_LIBS=""
    
        echo Splitting all existing fat binaries...
    
        for NAME in $BOOST_LIBS; do
            ALL_LIBS="$ALL_LIBS libboost_$NAME.a"
    
            $ARM_DEV_CMD lipo "iphone-build/stage/lib/libboost_$NAME.a" -thin armv6 -o $IOSBUILDDIR/armv6/libboost_$NAME.a
            $ARM_DEV_CMD lipo "iphone-build/stage/lib/libboost_$NAME.a" -thin armv7 -o $IOSBUILDDIR/armv7/libboost_$NAME.a
            $ARM_DEV_CMD lipo "iphone-build/stage/lib/libboost_$NAME.a" -thin armv7s -o $IOSBUILDDIR/armv7s/libboost_$NAME.a
    		$ARM_DEV_CMD lipo "iphone-build/stage/lib/libboost_$NAME.a" -thin arm64 -o $IOSBUILDDIR/arm64/libboost_$NAME.a
    
    		$ARM_DEV_CMD lipo "iphonesim-build/stage/lib/libboost_$NAME.a" -thin i386 -o $IOSBUILDDIR/i386/libboost_$NAME.a
    		$ARM_DEV_CMD lipo "iphonesim-build/stage/lib/libboost_$NAME.a" -thin x86_64 -o $IOSBUILDDIR/x86_64/libboost_$NAME.a
    
            $ARM_DEV_CMD lipo "osx-build/stage/lib/libboost_$NAME.a" -thin i386 -o $OSXBUILDDIR/i386/libboost_$NAME.a
            $ARM_DEV_CMD lipo "osx-build/stage/lib/libboost_$NAME.a" -thin x86_64 -o $OSXBUILDDIR/x86_64/libboost_$NAME.a
        done
    
        echo "Decomposing each architecture's .a files"
    
        for NAME in $ALL_LIBS; do
            echo Decomposing $NAME...
            (cd $IOSBUILDDIR/armv6/obj; ar -x ../$NAME );
            (cd $IOSBUILDDIR/armv7/obj; ar -x ../$NAME );
            (cd $IOSBUILDDIR/armv7s/obj; ar -x ../$NAME );
    		(cd $IOSBUILDDIR/arm64/obj; ar -x ../$NAME );
            (cd $IOSBUILDDIR/i386/obj; ar -x ../$NAME );
    		(cd $IOSBUILDDIR/x86_64/obj; ar -x ../$NAME );
    
            (cd $OSXBUILDDIR/i386/obj; ar -x ../$NAME );
            (cd $OSXBUILDDIR/x86_64/obj; ar -x ../$NAME );
        done
    
        echo "Linking each architecture into an uberlib ($ALL_LIBS => libboost.a )"
    
        rm $IOSBUILDDIR/*/libboost.a
        
        echo ...armv6
        (cd $IOSBUILDDIR/armv6; $ARM_DEV_CMD ar crus libboost.a obj/*.o; )
        echo ...armv7
        (cd $IOSBUILDDIR/armv7; $ARM_DEV_CMD ar crus libboost.a obj/*.o; )
        echo ...armv7s
        (cd $IOSBUILDDIR/armv7s; $ARM_DEV_CMD ar crus libboost.a obj/*.o; )
        echo ...arm64
        (cd $IOSBUILDDIR/arm64; $ARM_DEV_CMD ar crus libboost.a obj/*.o; )
        echo ...i386
        (cd $IOSBUILDDIR/i386;  $SIM_DEV_CMD ar crus libboost.a obj/*.o; )
        echo ...x86_64
        (cd $IOSBUILDDIR/x86_64;  $SIM_DEV_CMD ar crus libboost.a obj/*.o; )
    
        rm $OSXBUILDDIR/*/libboost.a
        echo ...osx-i386
        (cd $OSXBUILDDIR/i386;  $SIM_DEV_CMD ar crus libboost.a obj/*.o; )
    
        echo ...x86_64
        (cd $OSXBUILDDIR/x86_64;  $SIM_DEV_CMD ar crus libboost.a obj/*.o; )
    }
    
    #===============================================================================
    buildFramework()
    {
        : ${1:?}
        FRAMEWORKDIR=$1
        BUILDDIR=$2
    
        VERSION_TYPE=Alpha
        FRAMEWORK_NAME=boost
        FRAMEWORK_VERSION=A
    
        FRAMEWORK_CURRENT_VERSION=$BOOST_VERSION
        FRAMEWORK_COMPATIBILITY_VERSION=$BOOST_VERSION
    
        FRAMEWORK_BUNDLE=$FRAMEWORKDIR/$FRAMEWORK_NAME.framework
        echo "Framework: Building $FRAMEWORK_BUNDLE from $BUILDDIR..."
    
        rm -rf $FRAMEWORK_BUNDLE
    
        echo "Framework: Setting up directories..."
        mkdir -p $FRAMEWORK_BUNDLE
        mkdir -p $FRAMEWORK_BUNDLE/Versions
        mkdir -p $FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION
        mkdir -p $FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION/Resources
        mkdir -p $FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION/Headers
        mkdir -p $FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION/Documentation
    
        echo "Framework: Creating symlinks..."
        ln -s $FRAMEWORK_VERSION               $FRAMEWORK_BUNDLE/Versions/Current
        ln -s Versions/Current/Headers         $FRAMEWORK_BUNDLE/Headers
        ln -s Versions/Current/Resources       $FRAMEWORK_BUNDLE/Resources
        ln -s Versions/Current/Documentation   $FRAMEWORK_BUNDLE/Documentation
        ln -s Versions/Current/$FRAMEWORK_NAME $FRAMEWORK_BUNDLE/$FRAMEWORK_NAME
    
        FRAMEWORK_INSTALL_NAME=$FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION/$FRAMEWORK_NAME
    
        echo "Lipoing library into $FRAMEWORK_INSTALL_NAME..."
        $ARM_DEV_CMD lipo -create $BUILDDIR/*/libboost.a -o "$FRAMEWORK_INSTALL_NAME" || abort "Lipo $1 failed"
    
        echo "Framework: Copying includes..."
        cp -r $PREFIXDIR/include/boost/*  $FRAMEWORK_BUNDLE/Headers/
    
        echo "Framework: Creating plist..."
        cat > $FRAMEWORK_BUNDLE/Resources/Info.plist <<EOF
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>English</string>
    <key>CFBundleExecutable</key>
    <string>${FRAMEWORK_NAME}</string>
    <key>CFBundleIdentifier</key>
    <string>org.boost</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundlePackageType</key>
    <string>FMWK</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>${FRAMEWORK_CURRENT_VERSION}</string>
    </dict>
    </plist>
    EOF
    
        doneSection
    }
    
    #===============================================================================
    # Execution starts here
    #===============================================================================
    
    mkdir -p $IOSBUILDDIR
    
    cleanEverythingReadyToStart #may want to comment if repeatedly running during dev
    restoreBoost
    
    echo "BOOST_VERSION:     $BOOST_VERSION"
    echo "BOOST_LIBS:        $BOOST_LIBS"
    echo "BOOST_SRC:         $BOOST_SRC"
    echo "IOSBUILDDIR:       $IOSBUILDDIR"
    echo "OSXBUILDDIR:       $OSXBUILDDIR"
    echo "PREFIXDIR:         $PREFIXDIR"
    echo "IOSFRAMEWORKDIR:   $IOSFRAMEWORKDIR"
    echo "OSXFRAMEWORKDIR:   $OSXFRAMEWORKDIR"
    echo "IPHONE_SDKVERSION: $IPHONE_SDKVERSION"
    echo "XCODE_ROOT:        $XCODE_ROOT"
    echo "COMPILER:          $COMPILER"
    echo
    
    downloadBoost
    unpackBoost
    inventMissingHeaders
    bootstrapBoost
    updateBoost
    buildBoostForIPhoneOS
    scrunchAllLibsTogetherInOneLibPerPlatform
    buildFramework $IOSFRAMEWORKDIR $IOSBUILDDIR
    buildFramework $OSXFRAMEWORKDIR $OSXBUILDDIR
    
    restoreBoost
    
    echo "Completed successfully"
    
    #===============================================================================
    
    

    构建过程

    • 我最终使用的是boost 1.7.0
    • 脚本也换了
    ...updated 10782 targets...
    
    =================================================================
    Done
    
    link.jam: No such file or directory
    Performing configuration checks
    
        - has_icu builds           : no
        - lockfree boost::atomic_flag : no
    
    Component configuration:
    
        - atomic                   : not building
        - chrono                   : building
        - context                  : not building
        - coroutine                : not building
        - date_time                : building
        - exception                : not building
        - filesystem               : building
        - graph                    : building
        - graph_parallel           : not building
        - iostreams                : not building
        - locale                   : not building
        - log                      : not building
        - math                     : not building
        - mpi                      : not building
        - program_options          : not building
        - python                   : not building
        - random                   : building
        - regex                    : building
        - serialization            : not building
        - signals                  : building
        - system                   : building
        - test                     : not building
        - thread                   : building
        - timer                    : not building
        - wave                     : not building
    
    ...patience...
    ...patience...
    ...found 3827 targets...
    ...updating 159 targets...
    common.mkdir iphonesim-build/stage
    common.mkdir iphonesim-build/boost/bin.v2/libs/system/build/darwin-13.2~iphonesim/release
    common.mkdir iphonesim-build/boost/bin.v2/libs/chrono
    common.mkdir iphonesim-build/boost/bin.v2/libs/date_time
    common.mkdir iphonesim-build/boost/bin.v2/libs/filesystem
    common.mkdir iphonesim-build/boost/bin.v2/libs/regex/build/darwin-13.2~iphonesim/release
    common.mkdir iphonesim-build/boost/bin.v2/libs/graph
    common.mkdir iphonesim-build/boost/bin.v2/libs/random
    common.mkdir iphonesim-build/boost/bin.v2/libs/signals
    common.mkdir iphonesim-build/boost/bin.v2/libs/atomic
    common.mkdir iphonesim-build/boost/bin.v2/libs/thread/build/darwin-13.2~iphonesim/release
    common.mkdir iphonesim-build/boost/bin.v2/libs/regex/build/darwin-13.2~iphonesim/release/architecture-x86
    common.mkdir iphonesim-build/boost/bin.v2/libs/filesystem/build
    common.mkdir iphonesim-build/boost/bin.v2/libs/date_time/build
    common.mkdir iphonesim-build/boost/bin.v2/libs/chrono/build
    common.mkdir iphonesim-build/boost/bin.v2/libs/system/build/darwin-13.2~iphonesim/release/architecture-x86
    common.mkdir iphonesim-build/stage/lib
    common.mkdir iphonesim-build/boost/bin.v2/libs/signals/build
    common.mkdir iphonesim-build/boost/bin.v2/libs/random/build
    common.mkdir iphonesim-build/boost/bin.v2/libs/graph/build
    common.mkdir iphonesim-build/boost/bin.v2/libs/thread/build/darwin-13.2~iphonesim/release/architecture-x86
    common.mkdir iphonesim-build/boost/bin.v2/libs/atomic/build
    common.mkdir iphonesim-build/boost/
    
    

    -失败了

    xctoolchain/usr/bin/ranlib: file: libboost.a(w32_regex_traits.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: libboost.a(windows_file_codecvt.o) has no symbols
    ...x86_64
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: libboost.a(icu.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: libboost.a(regex_debug.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: libboost.a(thread_clock.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: libboost.a(usinstances.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: libboost.a(w32_regex_traits.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: libboost.a(windows_file_codecvt.o) has no symbols
    rm: /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/boost/osx/build/*/libboost.a: No such file or directory
    ...osx-i386
    ar: obj/*.o: No such file or directory
    ...x86_64
    ar: obj/*.o: No such file or directory
    Framework: Building /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/boost/ios/framework/boost.framework from /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/boost/ios/build...
    Framework: Setting up directories...
    Framework: Creating symlinks...
    Lipoing library into /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/boost/ios/framework/boost.framework/Versions/A/boost...
    Framework: Copying includes...
    Framework: Creating plist...
    
    =================================================================
    Done
    
    Framework: Building /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/boost/osx/framework/boost.framework from /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/boost/osx/build...
    Framework: Setting up directories...
    Framework: Creating symlinks...
    Lipoing library into /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/boost/osx/framework/boost.framework/Versions/A/boost...
    fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: empty archive with no architecture specification: /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/boost/osx/build/i386/libboost.a (can't determine architecture for it) 这个不是i386么,
    
    Aborted: Lipo /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/boost/osx/framework failed
     ✘ zhangbin@pb6a80114  ~/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/boost   master ●  
    
    

    看下编译过程

    • 1.55的这个在我的mac 上编译不过
    examples/iOS/SioChatDemo/boost   master ●  ./boost.sh
    Cleaning everything before we start to build...
    
    =================================================================
    Done
    
    BOOST_VERSION:     1.55.0
    BOOST_LIBS:        random regex graph random chrono thread signals filesystem system date_time
    BOOST_SRC:         /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/boost/src/boost_1_55_0
    IOSBUILDDIR:       /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/boost/ios/build
    OSXBUILDDIR:       /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/boost/osx/build
    PREFIXDIR:         /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/boost/ios/prefix
    IOSFRAMEWORKDIR:   /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/boost/ios/framework
    OSXFRAMEWORKDIR:   /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/boost/osx/framework
    IPHONE_SDKVERSION: 13.2
    XCODE_ROOT:        /Applications/Xcode.app/Contents/Developer
    COMPILER:          clang++
    
    
    

    换一个构建脚本,构建1.70.0

    • 看了下,自己构建 ios
    • boost.sh脚本有新版本了,cpprest也在用作者说的
    • 脚本在 新版本
    • 默认是1.69.0,但是我没有找到tools文件夹,囧。
    • 换了1.70.0,找到了。最新的是1.72.0,old的从这里 下载。
     ✘ zhangbin@pb6a80114  ~/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript   master  xcrun --sdk macosx --show-sdk-version
    10.15
     zhangbin@pb6a80114  ~/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript   master ●  xcrun --sdk iphoneos --show-sdk-version
    13.2
     zhangbin@pb6a80114  ~/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript   master ● ./boost.sh -ios --boost-libs "chrono filesystem random regex system thread" --framework-header-root 
    
    BUILD_IOS:           YES
    BUILD_TVOS:          NO
    BUILD_MACOS:         NO
    BOOST_VERSION:       1.70.0
    IOS_SDK_VERSION:     13.2
    MIN_IOS_VERSION:     11.0
    TVOS_SDK_VERSION:    13.2
    TVOS_SDK_PATH:       /Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS13.2.sdk
    TVOSSIM_SDK_PATH:    /Applications/Xcode.app/Contents/Developer/Platforms/AppleTVSimulator.platform/Developer/SDKs/AppleTVSimulator13.2.sdk
    MIN_TVOS_VERSION:    11.0
    MACOS_SDK_VERSION:   10.15
    MACOS_SDK_PATH:      /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk
    MIN_MACOS_VERSION:   10.12
    MACOS_ARCHS:         x86_64
    IOS_ARCHS:           arm64
    IOS_SIM_ARCHS        x86_64
    BOOST_LIBS:          chrono filesystem random regex system thread
    BOOST_SRC:           /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/src/boost_1_70_0
    IOS_BUILD_DIR:       /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build
    MACOS_BUILD_DIR:     /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/macos/release/build
    IOS_FRAMEWORK_DIR:   /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/framework
    MACOS_FRAMEWORK_DIR: /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/macos/release/framework
    XCODE_ROOT:          /Applications/Xcode.app/Contents/Developer
    THREADS:             -j8
    VARIANT:             release
    
    Cleaning everything
    rm: /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/src/boost_1_70_0/iphone-build: No such file or directory
    rm: /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/src/boost_1_70_0/iphonesim-build: No such file or directory
    rm: /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release: No such file or directory
    
    Done
    =================================================================
    
    Unpacking boost into /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/src...
    
        ...unpacked as /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/src/boost_1_70_0
    
    Done
    =================================================================
    
    Invent missing headers
    Updating boost into /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/src/boost_1_70_0...
    
    Done
    =================================================================
    
    Bootstrap libs chrono filesystem random regex system thread
    Bootstrapping for iOS (with libs chrono,filesystem,random,regex,system,thread)
    Building Boost.Build engine with toolset darwin... tools/build/src/engine/bin.macosxx86_64/b2
    Unicode/ICU support for Boost.Regex?... not found.
    Generating Boost.Build configuration in project-config.jam for darwin...
    
    Bootstrapping is done. To build, run:
    
        ./b2
        
    To generate header files, run:
    
        ./b2 headers
    
    To adjust configuration, edit 'project-config.jam'.
    Further information:
    
       - Command line help:
         ./b2 --help
         
       - Getting started guide: 
         http://www.boost.org/more/getting_started/unix-variants.html
         
       - Boost.Build documentation:
         http://www.boost.org/build/
    
    
    Done
    =================================================================
    
    Building Boost for iPhone
    
    
    
    • 接下来,好像成功了么?
    Done
    =================================================================
    
    Building Boost for iPhoneSimulator
    
    Done
    =================================================================
    
    Splitting all existing fat binaries...
    Decomposing each architecture's .a files
    Decomposing libboost_chrono.a
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/arm64/obj/chrono
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/x86_64/obj/chrono
    Decomposing libboost_filesystem.a
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/arm64/obj/filesystem
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/x86_64/obj/filesystem
    Decomposing libboost_random.a
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/arm64/obj/random
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/x86_64/obj/random
    Decomposing libboost_regex.a
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/arm64/obj/regex
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/x86_64/obj/regex
    Decomposing libboost_system.a
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/arm64/obj/system
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/x86_64/obj/system
    Decomposing libboost_thread.a
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/arm64/obj/thread
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/x86_64/obj/thread
    Linking each architecture into an uberlib ( libboost_chrono.a libboost_filesystem.a libboost_random.a libboost_regex.a libboost_system.a libboost_thread.a => libboost.a )
    rm: /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/arm64/libboost.a: No such file or directory
    Archiving chrono
    ...ios-arm64
    ...ios-sim-x86_64
    Archiving filesystem
    ...ios-arm64
    ...ios-sim-x86_64
    Archiving random
    ...ios-arm64
    ...ios-sim-x86_64
    Archiving regex
    ...ios-arm64
    ...ios-sim-x86_64
    Archiving system
    ...ios-arm64
    ...ios-sim-x86_64
    Archiving thread
    ...ios-arm64
    ...ios-sim-x86_64
    Framework: Building /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/framework/boost.framework from /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build...
    Framework: Setting up directories...
    Framework: Creating symlinks...
    Lipoing library into /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/framework/boost.framework/Versions/A/boost...
    Framework: Copying includes...
    Framework: Creating plist...
    
    Done
    =================================================================
    
    Completed successfully
     zhangbin@pb6a80114  ~/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript   master ●  
     zhangbin@pb6a80114  ~/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript   master ●  
    
    
    • 结果是这样的

    boost 的ios 版本构建成功 ios 1.70.0

    发现boost库不对,需要多构建一个

    • sioclient.a 需要的链接库
    • 少了一个date_time 在这里插入图片描述

    重来一遍

    • 重新指定了编译的库
    zhangbin@pb6a80114  ~/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript   master ● ./boost.sh -ios --boost-libs "chrono filesystem random regex system thread date_time" --framework-header-root
    
    BUILD_IOS:           YES
    BUILD_TVOS:          NO
    BUILD_MACOS:         NO
    BOOST_VERSION:       1.70.0
    IOS_SDK_VERSION:     13.2
    MIN_IOS_VERSION:     11.0
    TVOS_SDK_VERSION:    13.2
    TVOS_SDK_PATH:       /Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS13.2.sdk
    TVOSSIM_SDK_PATH:    /Applications/Xcode.app/Contents/Developer/Platforms/AppleTVSimulator.platform/Developer/SDKs/AppleTVSimulator13.2.sdk
    MIN_TVOS_VERSION:    11.0
    MACOS_SDK_VERSION:   10.15
    MACOS_SDK_PATH:      /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk
    MIN_MACOS_VERSION:   10.12
    MACOS_ARCHS:         x86_64
    IOS_ARCHS:           arm64
    IOS_SIM_ARCHS        x86_64
    BOOST_LIBS:          chrono filesystem random regex system thread date_time
    BOOST_SRC:           /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/src/boost_1_70_0
    IOS_BUILD_DIR:       /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build
    MACOS_BUILD_DIR:     /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/macos/release/build
    IOS_FRAMEWORK_DIR:   /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/framework
    MACOS_FRAMEWORK_DIR: /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/macos/release/framework
    XCODE_ROOT:          /Applications/Xcode.app/Contents/Developer
    THREADS:             -j8
    VARIANT:             release
    
    Cleaning everything
    
    Done
    =================================================================
    
    Unpacking boost into /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/src...
        ...unpacked as /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/src/boost_1_70_0
    
    Done
    =================================================================
    
    Invent missing headers
    Updating boost into /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/src/boost_1_70_0...
    
    Done
    =================================================================
    
    Bootstrap libs chrono filesystem random regex system thread date_time
    Bootstrapping for iOS (with libs chrono,filesystem,random,regex,system,thread,date_time)
    Building Boost.Build engine with toolset darwin... tools/build/src/engine/bin.macosxx86_64/b2
    Unicode/ICU support for Boost.Regex?... not found.
    Backing up existing Boost.Build configuration in project-config.jam.1
    Generating Boost.Build configuration in project-config.jam for darwin...
    
    Bootstrapping is done. To build, run:
    
        ./b2
        
    To generate header files, run:
    
        ./b2 headers
    
    To adjust configuration, edit 'project-config.jam'.
    Further information:
    
       - Command line help:
         ./b2 --help
         
       - Getting started guide: 
         http://www.boost.org/more/getting_started/unix-variants.html
         
       - Boost.Build documentation:
         http://www.boost.org/build/
    
    
    Done
    =================================================================
    
    Building Boost for iPhone
    
    Done
    =================================================================
    
    Building Boost for iPhoneSimulator
    
    Done
    =================================================================
    
    Splitting all existing fat binaries...
    Decomposing each architecture's .a files
    Decomposing libboost_chrono.a
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/arm64/obj/chrono
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/x86_64/obj/chrono
    Decomposing libboost_filesystem.a
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/arm64/obj/filesystem
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/x86_64/obj/filesystem
    Decomposing libboost_random.a
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/arm64/obj/random
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/x86_64/obj/random
    Decomposing libboost_regex.a
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/arm64/obj/regex
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/x86_64/obj/regex
    Decomposing libboost_system.a
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/arm64/obj/system
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/x86_64/obj/system
    Decomposing libboost_thread.a
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/arm64/obj/thread
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/x86_64/obj/thread
    Decomposing libboost_date_time.a
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/arm64/obj/date_time
    Unpacking /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/x86_64/obj/date_time
    Linking each architecture into an uberlib ( libboost_chrono.a libboost_filesystem.a libboost_random.a libboost_regex.a libboost_system.a libboost_thread.a libboost_date_time.a => libboost.a )
    rm: /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build/arm64/libboost.a: No such file or directory
    Archiving chrono
    ...ios-arm64
    ...ios-sim-x86_64
    Archiving filesystem
    ...ios-arm64
    ...ios-sim-x86_64
    Archiving random
    ...ios-arm64
    ...ios-sim-x86_64
    Archiving regex
    ...ios-arm64
    ...ios-sim-x86_64
    Archiving system
    ...ios-arm64
    ...ios-sim-x86_64
    Archiving thread
    ...ios-arm64
    ...ios-sim-x86_64
    Archiving date_time
    ...ios-arm64
    ...ios-sim-x86_64
    Framework: Building /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/framework/boost.framework from /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/build...
    Framework: Setting up directories...
    Framework: Creating symlinks...
    Lipoing library into /Users/zhangbin/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript/build/boost/1.70.0/ios/release/framework/boost.framework/Versions/A/boost...
    Framework: Copying includes...
    Framework: Creating plist...
    
    Done
    =================================================================
    
    Completed successfully
     zhangbin@pb6a80114  ~/tet/webrtc_build/owt-native/demo/socket.io-client-cpp/examples/iOS/SioChatDemo/Apple-Boost-BuildScript   master ●  
    
    

    还有一个编译错误

    demo 可以跑

    • 看起来要部署一个server nodejs的才行
    • 模拟器

    模拟器版本的静态库

    • 有一个target是sioclient
    • 存放在这里在product目录下

    这么一搞,反而ssl编译不过了??

    • 指定一个ssl的ios构建好的地址,去构建owt,看起来不成功
     ✘ zhangbin@pb6a80114  ~/tet/webrtc_build/owt-native/src/src  ➦ e983dc8 ●  python scripts/build.py --arch 'x64'  --ssl_root '/Users/zhangbin/tet/webrtc_build/owt-native/OpenSSL-for-iPhone/bin/iPhoneSimulator13.2-x86_64.sdk' --scheme 'release'
    Done. Made 1509 targets from 228 files in 1872ms
    ninja: Entering directory `out/Release-simulator-x64'
    [1516/2646] CXX obj/third_party/webrtc/rtc_base/rtc_base/openssl_certificate.o
    FAILED: obj/third_party/webrtc/rtc_base/rtc_base/openssl_certificate.o 
    clang++ -MMD -MF obj/third_party/webrtc/rtc_base/rtc_base/openssl_certificate.o.d -DCR_XCODE_VERSION=1131 -DCR_CLANG_REVISION=\"373424-64a362e7-1\" -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D_FORTIFY_SOURCE=2 -DNDEBUG -DNVALGRIND -DDYNAMIC_ANNOTATIONS_ENABLED=0 -DNS_BLOCK_ASSERTIONS=1 -DWEBRTC_ENABLE_PROTOBUF=1 -DWEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE -DRTC_ENABLE_VP9 -DHAVE_SCTP -DHAVE_WEBRTC_VIDEO -DLOGGING_INSIDE_WEBRTC -DWEBRTC_LIBRARY_IMPL -DWEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS=1 -DWEBRTC_POSIX -DWEBRTC_MAC -DWEBRTC_IOS -DABSL_ALLOCATOR_NOTHROW=1 -I../.. -Igen -I/Users/zhangbin/tet/webrtc_build/owt-native/OpenSSL-for-iPhone/bin/iPhoneSimulator13.2-x86_64.sdk/include -I../../third_party/webrtc -Igen/third_party/webrtc -I../../third_party/abseil-cpp -fno-strict-aliasing --param=ssp-buffer-size=4 -fstack-protector -fcolor-diagnostics -fmerge-all-constants -arch x86_64 -Wno-builtin-macro-redefined -D__DATE__= -D__TIME__= -D__TIMESTAMP__= -no-canonical-prefixes -Wall -Werror -Wextra -Wimplicit-fallthrough -Wthread-safety -Wunguarded-availability -Wundeclared-selector -Wno-missing-field-initializers -Wno-unused-parameter -Wno-c++11-narrowing -Wno-unneeded-internal-declaration -Wno-undefined-var-template -Oz -fno-omit-frame-pointer -g2 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator13.2.sdk -stdlib=libc++ -mios-simulator-version-min=9.0 -Wheader-hygiene -Wstring-conversion -Wtautological-overlap-compare -Wexit-time-destructors -Wglobal-constructors -Wno-shorten-64-to-32 -std=c++14 -Wextra-semi -fno-exceptions -fno-rtti -c ../../third_party/webrtc/rtc_base/openssl_certificate.cc -o obj/third_party/webrtc/rtc_base/rtc_base/openssl_certificate.o
    ../../third_party/webrtc/rtc_base/openssl_certificate.cc:99:22: error: use of undeclared identifier 'X509_get_notBefore'
      if (!X509_time_adj(X509_get_notBefore(x509), params.not_before, &epoch_off) ||
                         ^
    ../../third_party/webrtc/rtc_base/openssl_certificate.cc:100:22: error: use of undeclared identifier 'X509_get_notAfter'
          !X509_time_adj(X509_get_notAfter(x509), params.not_after, &epoch_off)) {
                         ^
    ../../third_party/webrtc/rtc_base/openssl_certificate.cc:289:28: error: use of undeclared identifier 'X509_get_notAfter'
      ASN1_TIME* expire_time = X509_get_notAfter(x509_);
                               ^
    3 errors generated.
    [1519/2646] CXX obj/third_party/webrtc/rtc_base/rtc_base/openssl_adapter.o
    FAILED: obj/third_party/webrtc/rtc_base/rtc_base/openssl_adapter.o 
    clang++ -MMD -MF obj/third_party/webrtc/rtc_base/rtc_base/openssl_adapter.o.d -DCR_XCODE_VERSION=1131 -DCR_CLANG_REVISION=\"373424-64a362e7-1\" -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D_FORTIFY_SOURCE=2 -DNDEBUG -DNVALGRIND -DDYNAMIC_ANNOTATIONS_ENABLED=0 -DNS_BLOCK_ASSERTIONS=1 -DWEBRTC_ENABLE_PROTOBUF=1 -DWEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE -DRTC_ENABLE_VP9 -DHAVE_SCTP -DHAVE_WEBRTC_VIDEO -DLOGGING_INSIDE_WEBRTC -DWEBRTC_LIBRARY_IMPL -DWEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS=1 -DWEBRTC_POSIX -DWEBRTC_MAC -DWEBRTC_IOS -DABSL_ALLOCATOR_NOTHROW=1 -I../.. -Igen -I/Users/zhangbin/tet/webrtc_build/owt-native/OpenSSL-for-iPhone/bin/iPhoneSimulator13.2-x86_64.sdk/include -I../../third_party/webrtc -Igen/third_party/webrtc -I../../third_party/abseil-cpp -fno-strict-aliasing --param=ssp-buffer-size=4 -fstack-protector -fcolor-diagnostics -fmerge-all-constants -arch x86_64 -Wno-builtin-macro-redefined -D__DATE__= -D__TIME__= -D__TIMESTAMP__= -no-canonical-prefixes -Wall -Werror -Wextra -Wimplicit-fallthrough -Wthread-safety -Wunguarded-availability -Wundeclared-selector -Wno-missing-field-initializers -Wno-unused-parameter -Wno-c++11-narrowing -Wno-unneeded-internal-declaration -Wno-undefined-var-template -Oz -fno-omit-frame-pointer -g2 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator13.2.sdk -stdlib=libc++ -mios-simulator-version-min=9.0 -Wheader-hygiene -Wstring-conversion -Wtautological-overlap-compare -Wexit-time-destructors -Wglobal-constructors -Wno-shorten-64-to-32 -std=c++14 -Wextra-semi -fno-exceptions -fno-rtti -c ../../third_party/webrtc/rtc_base/openssl_adapter.cc -o obj/third_party/webrtc/rtc_base/rtc_base/openssl_adapter.o
    ../../third_party/webrtc/rtc_base/openssl_adapter.cc:153:8: error: use of undeclared identifier 'SSL_library_init'
      if (!SSL_library_init())
           ^
    ../../third_party/webrtc/rtc_base/openssl_adapter.cc:157:3: error: use of undeclared identifier 'SSL_load_error_strings'
      SSL_load_error_strings();
      ^
    ../../third_party/webrtc/rtc_base/openssl_adapter.cc:160:3: error: use of undeclared identifier 'OpenSSL_add_all_algorithms'
      OpenSSL_add_all_algorithms();
      ^
    3 errors generated.
    [1525/2646] CXX obj/third_party/webrtc...base/rtc_base/physical_socket_server.o
    ninja: build stopped: subcommand failed.
     ✘ zhangbin@pb6a80114  ~/tet/webrtc_build/owt-native/src/src  ➦ e983dc8 ●  
    
    

    owt ios sdk 的issue里有说明这个问题

    • tls 版本的sioclient 需要openssl,webrtc需要borringssl
    The TLS version of Socket.IO cpp lib depends on OpenSSL, while WebRTC depends on BoringSSL by default. To make them work together, please set GN argument owt_use_openssl to true, and set owt_openssl_header_root, owt_openssl_lib_root to the correct path.
    
    
    I rebuild owt.framework, specify --ssl_root , then found the cause: webrtc uses deprecated openssl x509 methods: X509_get_notAfter, X509_get_notBefore
    
    python3 /Users/jeremy/Documents/Jeremy/Work/Tool/depot_tools/depot_tools/src/scripts/build.py --scheme debug --arch arm64 --ssl_root /Users/jeremy/Documents/Jeremy/Work/Tool/depot_tools/OpenSSL-for-iPhone --skip_tests
    
    • 必须支持deprecated 方法?
    https://github.com/x2on/OpenSSL-for-iPhone
    ./build-libssl.sh --version=1.1.0f --deprecated
    

    我owt 没用ssl构建的模拟器版本

    sioclient 不用tls的,那么我也不用openssl的owt,而且用debug试试

    python scripts/build.py --arch 'x64' --scheme 'debug'
    
    • 能编译过,但是测试失败
     zhangbin@pb6a80114  ~/tet/webrtc_build/owt-native/src/src  ➦ e983dc8 ●  python scripts/build.py --arch 'x64' --scheme 'debug'
    Done. Made 1509 targets from 227 files in 2371ms
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (audio_receive_stream.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(audio_receive_stream.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(audio_receive_stream.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (audio_send_stream.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(audio_send_stream.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(audio_send_stream.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (audio_state.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(audio_state.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(audio_state.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (auto_correlation.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(auto_correlation.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(auto_correlation.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (base64.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(base64.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(base64.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (convert.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(convert.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(convert.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (cross_correlation.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(cross_correlation.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(cross_correlation.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (decoder_database.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(decoder_database.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(decoder_database.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (dtls_transport.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(dtls_transport.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(dtls_transport.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (encoded_frame.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(encoded_frame.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(encoded_frame.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (err.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(err.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(err.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (helpers.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(helpers.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(helpers.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (histogram.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(histogram.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(histogram.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (int128.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(int128.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(int128.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (jsep_ice_candidate.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(jsep_ice_candidate.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(jsep_ice_candidate.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (logging.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(logging.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_sdk_base.a(logging.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (moving_average.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(moving_average.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(moving_average.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (noise_suppression.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(noise_suppression.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(noise_suppression.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (packet.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(packet.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(packet.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (packet_buffer.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(packet_buffer.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(packet_buffer.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (rtp_sender.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(rtp_sender.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(rtp_sender.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (sctp_transport.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(sctp_transport.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(sctp_transport.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (socket.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(socket.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(socket.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (splitting_filter.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(splitting_filter.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(splitting_filter.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (stream.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(stream.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_sdk_base.a(stream.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (sysinfo.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(sysinfo.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_sdk_base.a(sysinfo.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (thread.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(thread.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(thread.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (video_common.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(video_common.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(video_common.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (video_frame_buffer.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(video_frame_buffer.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(video_frame_buffer.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (video_receive_stream.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(video_receive_stream.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(video_receive_stream.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (video_send_stream.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(video_send_stream.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(video_send_stream.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(unscaledcycleclock.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(socket.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(cpu-aarch64-fuchsia.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(cpu-aarch64-linux.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(cpu-arm-linux.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(cpu-arm.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(cpu-intel.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(cpu-ppc64le.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(fips_shared_support.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(poly1305.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(poly1305_arm.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(deterministic.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(fuchsia.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(windows.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(refcount_c11.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(thread_none.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(thread_win.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(convert_jpeg.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(mjpeg_decoder.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(io_win32.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(sctp6_usrreq.o) has no symbols
    Done. Made 1509 targets from 227 files in 1971ms
    Start running unit tests.
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    ninja: Entering directory `out/Debug-simulator-x64'
    [8/8] STAMP obj/third_party/webrtc/examples/AppRTCMobile.stamp
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    User defaults from command line:
        IDETestRunSpecificationPath = /var/folders/c6/dg7ltn4n69g1sxkxc10wzjfr0000gn/T/12E75D95-43B8-456F-8426-57716286DF7C
    
    Testing started on 'iPhone 11 Pro Max'
    2020-01-30 00:46:27.038 xcodebuild[6451:3618413]  IDETestOperationsObserverDebug: Writing diagnostic log for test session to:
    /Users/zhangbin/Library/Developer/Xcode/DerivedData/temporary-affnfagjgcjjroeschzmakkdkdck/Logs/Test/Test-Transient Testing-2020.01.30_00-46-27-+0800.xcresult/Staging/1_Test/Diagnostics/audio_decoder_unittests-044471D6-7F16-4C11-B662-EADFF22D68E8/audio_decoder_unittests-3EFE10EF-608E-4DB7-B6BC-37EB9822D1F0/Session-audio_decoder_unittests-2020-01-30_004627-ys5V3s.log
    2020-01-30 00:46:27.039 xcodebuild[6451:3618255] [MT] IDETestOperationsObserverDebug: (EB48CFD1-F7ED-4196-B0B3-DBF013098466) Beginning test session audio_decoder_unittests-EB48CFD1-F7ED-4196-B0B3-DBF013098466 at 2020-01-30 00:46:27.039 with Xcode 11C504 on target <DVTiPhoneSimulator: 0x7f9344392200> {
    		SimDevice: iPhone 11 Pro Max (1C807845-8DFE-4C0B-AA5B-77D3FA4D532E, iOS 13.3, Shutdown)
    } (13.3 (17C45))
    2020-01-30 00:46:58.869 xcodebuild[6451:3618255] [MT] IDETestOperationsObserverDebug: (EB48CFD1-F7ED-4196-B0B3-DBF013098466) Finished requesting crash reports. Continuing with testing.
    (field_trial.cc:107): Setting field trial string:
    [==========] Running 26 tests from 10 test suites.
    [----------] Global test environment set-up.
    [----------] 2 tests from AudioDecoderPcmUTest
    [ RUN      ] AudioDecoderPcmUTest.EncodeDecode
    [       OK ] AudioDecoderPcmUTest.EncodeDecode (8 ms)
    [ RUN      ] AudioDecoderPcmUTest.SetTargetBitrate
    [       OK ] AudioDecoderPcmUTest.SetTargetBitrate (0 ms)
    [----------] 2 tests from AudioDecoderPcmUTest (8 ms total)
    
    [----------] 2 tests from AudioDecoderPcmATest
    [ RUN      ] AudioDecoderPcmATest.EncodeDecode
    [       OK ] AudioDecoderPcmATest.EncodeDecode (1 ms)
    [ RUN      ] AudioDecoderPcmATest.SetTargetBitrate
    [       OK ] AudioDecoderPcmATest.SetTargetBitrate (0 ms)
    [----------] 2 tests from AudioDecoderPcmATest (1 ms total)
    
    [----------] 2 tests from AudioDecoderPcm16BTest
    [ RUN      ] AudioDecoderPcm16BTest.EncodeDecode
    [       OK ] AudioDecoderPcm16BTest.EncodeDecode (2 ms)
    [ RUN      ] AudioDecoderPcm16BTest.SetTargetBitrate
    [       OK ] AudioDecoderPcm16BTest.SetTargetBitrate (0 ms)
    [----------] 2 tests from AudioDecoderPcm16BTest (2 ms total)
    
    [----------] 2 tests from AudioDecoderIlbcTest
    [ RUN      ] AudioDecoderIlbcTest.EncodeDecode
    [       OK ] AudioDecoderIlbcTest.EncodeDecode (9 ms)
    [ RUN      ] AudioDecoderIlbcTest.SetTargetBitrate
    [       OK ] AudioDecoderIlbcTest.SetTargetBitrate (1 ms)
    [----------] 2 tests from AudioDecoderIlbcTest (10 ms total)
    
    [----------] 2 tests from AudioDecoderIsacFloatTest
    [ RUN      ] AudioDecoderIsacFloatTest.EncodeDecode
    [       OK ] AudioDecoderIsacFloatTest.EncodeDecode (10 ms)
    [ RUN      ] AudioDecoderIsacFloatTest.SetTargetBitrate
    [       OK ] AudioDecoderIsacFloatTest.SetTargetBitrate (0 ms)
    [----------] 2 tests from AudioDecoderIsacFloatTest (10 ms total)
    
    [----------] 2 tests from AudioDecoderIsacSwbTest
    [ RUN      ] AudioDecoderIsacSwbTest.EncodeDecode
    [       OK ] AudioDecoderIsacSwbTest.EncodeDecode (10 ms)
    [ RUN      ] AudioDecoderIsacSwbTest.SetTargetBitrate
    [       OK ] AudioDecoderIsacSwbTest.SetTargetBitrate (0 ms)
    [----------] 2 tests from AudioDecoderIsacSwbTest (10 ms total)
    
    [----------] 2 tests from AudioDecoderIsacFixTest
    [ RUN      ] AudioDecoderIsacFixTest.EncodeDecode
    [       OK ] AudioDecoderIsacFixTest.EncodeDecode (10 ms)
    [ RUN      ] AudioDecoderIsacFixTest.SetTargetBitrate
    [       OK ] AudioDecoderIsacFixTest.SetTargetBitrate (0 ms)
    [----------] 2 tests from AudioDecoderIsacFixTest (10 ms total)
    
    [----------] 2 tests from AudioDecoderG722Test
    [ RUN      ] AudioDecoderG722Test.EncodeDecode
    [       OK ] AudioDecoderG722Test.EncodeDecode (2 ms)
    [ RUN      ] AudioDecoderG722Test.SetTargetBitrate
    [       OK ] AudioDecoderG722Test.SetTargetBitrate (0 ms)
    [----------] 2 tests from AudioDecoderG722Test (2 ms total)
    
    [----------] 2 tests from AudioDecoderG722StereoTest
    [ RUN      ] AudioDecoderG722StereoTest.EncodeDecode
    [       OK ] AudioDecoderG722StereoTest.EncodeDecode (3 ms)
    [ RUN      ] AudioDecoderG722StereoTest.SetTargetBitrate
    [       OK ] AudioDecoderG722StereoTest.SetTargetBitrate (0 ms)
    [----------] 2 tests from AudioDecoderG722StereoTest (4 ms total)
    
    [----------] 8 tests from Param/AudioDecoderOpusTest
    [ RUN      ] Param/AudioDecoderOpusTest.EncodeDecode/0
    (audio_encoder_opus.cc:748): Set Opus bitrate to 32000 bps.
    [       OK ] Param/AudioDecoderOpusTest.EncodeDecode/0 (8 ms)
    [ RUN      ] Param/AudioDecoderOpusTest.EncodeDecode/1
    (audio_encoder_opus.cc:748): Set Opus bitrate to 32000 bps.
    [       OK ] Param/AudioDecoderOpusTest.EncodeDecode/1 (4 ms)
    [ RUN      ] Param/AudioDecoderOpusTest.EncodeDecode/2
    (audio_encoder_opus.cc:748): Set Opus bitrate to 32000 bps.
    [       OK ] Param/AudioDecoderOpusTest.EncodeDecode/2 (6 ms)
    [ RUN      ] Param/AudioDecoderOpusTest.EncodeDecode/3
    (audio_encoder_opus.cc:748): Set Opus bitrate to 32000 bps.
    [       OK ] Param/AudioDecoderOpusTest.EncodeDecode/3 (6 ms)
    [ RUN      ] Param/AudioDecoderOpusTest.SetTargetBitrate/0
    (audio_encoder_opus.cc:748): Set Opus bitrate to 32000 bps.
    (audio_encoder_opus.cc:819): Set Opus bitrate to 6000 bps.
    (audio_encoder_opus.cc:819): Set Opus bitrate to 32000 bps.
    (audio_encoder_opus.cc:819): Set Opus bitrate to 510000 bps.
    [       OK ] Param/AudioDecoderOpusTest.SetTargetBitrate/0 (0 ms)
    [ RUN      ] Param/AudioDecoderOpusTest.SetTargetBitrate/1
    (audio_encoder_opus.cc:748): Set Opus bitrate to 32000 bps.
    (audio_encoder_opus.cc:819): Set Opus bitrate to 6000 bps.
    (audio_encoder_opus.cc:819): Set Opus bitrate to 32000 bps.
    (audio_encoder_opus.cc:819): Set Opus bitrate to 510000 bps.
    [       OK ] Param/AudioDecoderOpusTest.SetTargetBitrate/1 (0 ms)
    [ RUN      ] Param/AudioDecoderOpusTest.SetTargetBitrate/2
    (audio_encoder_opus.cc:748): Set Opus bitrate to 32000 bps.
    (audio_encoder_opus.cc:819): Set Opus bitrate to 6000 bps.
    (audio_encoder_opus.cc:819): Set Opus bitrate to 32000 bps.
    (audio_encoder_opus.cc:819): Set Opus bitrate to 510000 bps.
    [       OK ] Param/AudioDecoderOpusTest.SetTargetBitrate/2 (0 ms)
    [ RUN      ] Param/AudioDecoderOpusTest.SetTargetBitrate/3
    (audio_encoder_opus.cc:748): Set Opus bitrate to 32000 bps.
    (audio_encoder_opus.cc:819): Set Opus bitrate to 6000 bps.
    (audio_encoder_opus.cc:819): Set Opus bitrate to 32000 bps.
    (audio_encoder_opus.cc:819): Set Opus bitrate to 510000 bps.
    [       OK ] Param/AudioDecoderOpusTest.SetTargetBitrate/3 (0 ms)
    [----------] 8 tests from Param/AudioDecoderOpusTest (24 ms total)
    
    [----------] Global test environment tear-down
    [==========] 26 tests from 10 test suites ran. (81 ms total)
    [  PASSED  ] 26 tests.
    
    
    
    • 接下来失败了
    2020-01-30 00:48:08.263 xcodebuild[6451:3618255] [MT] IDETestOperationsObserverDebug: 101.232 elapsed -- Testing started completed.
    2020-01-30 00:48:08.263 xcodebuild[6451:3618255] [MT] IDETestOperationsObserverDebug: 0.000 sec, +0.000 sec -- start
    2020-01-30 00:48:08.263 xcodebuild[6451:3618255] [MT] IDETestOperationsObserverDebug: 101.232 sec, +101.232 sec -- end
    
    Test session results, code coverage, and logs:
    	/Users/zhangbin/Library/Developer/Xcode/DerivedData/temporary-affnfagjgcjjroeschzmakkdkdck/Logs/Test/Test-Transient Testing-2020.01.30_00-46-27-+0800.xcresult
    
    Testing failed:
    	TestTargetName:
    		audio_decoder_unittests.app (6699) encountered an error (Early unexpected exit, operation never finished bootstrapping - no restart will be attempted. (Underlying error: Test runner exited before starting test execution.))
    
    • 跳过测试
     zhangbin@pb6a80114  ~/tet/webrtc_build/owt-native/src/src  ➦ e983dc8 ●  python scripts/build.py --arch 'x64' --scheme 'debug' --skip_tests
    Done. Made 1509 targets from 227 files in 2662ms
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    ninja: Entering directory `out/Debug-simulator-x64'
    ninja: no work to do.
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (audio_receive_stream.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(audio_receive_stream.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(audio_receive_stream.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (audio_send_stream.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(audio_send_stream.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(audio_send_stream.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (audio_state.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(audio_state.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(audio_state.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (auto_correlation.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(auto_correlation.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(auto_correlation.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (base64.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(base64.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(base64.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (convert.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(convert.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(convert.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (cross_correlation.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(cross_correlation.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(cross_correlation.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (decoder_database.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(decoder_database.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(decoder_database.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (dtls_transport.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(dtls_transport.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(dtls_transport.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (encoded_frame.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(encoded_frame.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(encoded_frame.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (err.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(err.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(err.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (helpers.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(helpers.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(helpers.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (histogram.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(histogram.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(histogram.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (int128.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(int128.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(int128.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (jsep_ice_candidate.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(jsep_ice_candidate.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(jsep_ice_candidate.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (logging.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(logging.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_sdk_base.a(logging.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (moving_average.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(moving_average.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(moving_average.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (noise_suppression.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(noise_suppression.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(noise_suppression.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (packet.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(packet.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(packet.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (packet_buffer.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(packet_buffer.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(packet_buffer.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (rtp_sender.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(rtp_sender.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(rtp_sender.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (sctp_transport.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(sctp_transport.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(sctp_transport.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (socket.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(socket.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(socket.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (splitting_filter.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(splitting_filter.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(splitting_filter.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (stream.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(stream.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_sdk_base.a(stream.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (sysinfo.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(sysinfo.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_sdk_base.a(sysinfo.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (thread.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(thread.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(thread.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (video_common.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(video_common.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(video_common.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (video_frame_buffer.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(video_frame_buffer.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(video_frame_buffer.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (video_receive_stream.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(video_receive_stream.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(video_receive_stream.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning same member name (video_send_stream.o) in output file used for input files: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(video_send_stream.o) and: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(video_send_stream.o) due to use of basename, truncation and blank padding
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(unscaledcycleclock.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(socket.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(cpu-aarch64-fuchsia.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(cpu-aarch64-linux.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(cpu-arm-linux.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(cpu-arm.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(cpu-intel.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(cpu-ppc64le.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(fips_shared_support.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(poly1305.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(poly1305_arm.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(deterministic.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(fuchsia.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(windows.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(refcount_c11.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(thread_none.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(thread_win.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(convert_jpeg.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(mjpeg_decoder.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(io_win32.o) has no symbols
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: out/Debug-simulator-x64/obj/talk/owt/libowt_deps.a(sctp6_usrreq.o) has no symbols
    Done.
     zhangbin@pb6a80114  ~/tet/webrtc_build/owt-native/src/src  ➦ e983dc8 ●  
    
    

    之前就有debug模式的x64模拟器

    • 但是framework还是重新生成了
    • 当前时间生成的framework,是不是这里面包含了当前编译出来的arm64和模拟器64在这里插入图片描述

    好不容易编译过然后这样了

    Details
    
    This app could not be installed at this time.
    Domain: IXUserPresentableErrorDomain
    Code: 1
    Failure Reason: Could not install at this time.
    Recovery Suggestion: Failed to load Info.plist from bundle at path /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Library/Caches/com.apple.mobile.installd.staging/temp.G8OZJq/extracted/ICS Conference.app/Frameworks/OWT.framework; Extra info about plist: dev=16777220 ino=8615444705 mode=0100644 nlink=1 uid=501 gid=20 rdev=0 size=766 atime=1580318817.537570 mtime=1580318812.661476 ctime=1580318830.253055 birthtime=1580318812.661345 blksize=4096 blocks=8 flags=0x0 firstBytes={length = 4, bytes = 0x3c3f786d} ACL=<not found> extendedAttributes=<not found> keyCount=10 keySample={ CFBundleShortVersionString CFBundleIdentifier CFBundleName CFBundleSignature CFBundleInfoDictionaryVersion } 
    --
    Failed to load Info.plist from bundle at path /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Library/Caches/com.apple.mobile.installd.staging/temp.G8OZJq/extracted/ICS Conference.app/Frameworks/OWT.framework; Extra info about plist: dev=16777220 ino=8615444705 mode=0100644 nlink=1 uid=501 gid=20 rdev=0 size=766 atime=1580318817.537570 mtime=1580318812.661476 ctime=1580318830.253055 birthtime=1580318812.661345 blksize=4096 blocks=8 flags=0x0 firstBytes={length = 4, bytes = 0x3c3f786d} ACL=<not found> extendedAttributes=<not found> keyCount=10 keySample={ CFBundleShortVersionString CFBundleIdentifier CFBundleName CFBundleSignature CFBundleInfoDictionaryVersion } 
    Domain: MIInstallerErrorDomain
    Code: 35
    User Info: {
       FunctionName = "-[MIBundle _validateWithError:]";
       LegacyErrorString = PackageInspectionFailed;
       SourceFileLine = 128;
    }
    --
    

    webrtc framework 设置为embbed sign

    • owt 没设置,
    • webrtc设置了
    • 如果不设置会有上面哪个无法安装的报错在这里插入图片描述
    • 菜可以跑,但是有这样的警告:
    objc[25247]: Class RTCCVPixelBuffer is implemented in both /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/WebCore.framework/Frameworks/libwebrtc.dylib (0x127662aa8) and /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/Frameworks/WebRTC.framework/WebRTC (0x1136e02e0). One of the two will be used. Which one is undefined.
    objc[25247]: Class RTCAudioSession is implemented in both /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/Frameworks/WebRTC.framework/WebRTC (0x1136deda0) and /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/ICS Conference (0x10b867410). One of the two will be used. Which one is undefined.
    objc[25247]: Class RTCAudioSessionConfiguration is implemented in both /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/Frameworks/WebRTC.framework/WebRTC (0x1136dedf0) and /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/ICS Conference (0x10b867460). One of the two will be used. Which one is undefined.
    objc[25247]: Class RTCNativeAudioSessionDelegateAdapter is implemented in both /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/Frameworks/WebRTC.framework/WebRTC (0x1136dee40) and /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/ICS Conference (0x10b8674b0). One of the two will be used. Which one is undefined.
    objc[25247]: Class RTCEncodedImage is implemented in both /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/Frameworks/WebRTC.framework/WebRTC (0x1136deeb8) and /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/ICS Conference (0x10b867528). One of the two will be used. Which one is undefined.
    objc[25247]: Class RTCRtpFragmentationHeader is implemented in both /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/Frameworks/WebRTC.framework/WebRTC (0x1136def08) and /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/ICS Conference (0x10b867578). One of the two will be used. Which one is undefined.
    objc[25247]: Class RTCVideoCapturer is implemented in both /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/Frameworks/WebRTC.framework/WebRTC (0x1136def30) and /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/ICS Conference (0x10b8675a0). One of the two will be used. Which one is undefined.
    objc[25247]: Class RTCVideoCodecInfo is implemented in both /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/Frameworks/WebRTC.framework/WebRTC (0x1136def80) and /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/ICS Conference (0x10b8675f0). One of the two will be used. Which one is undefined.
    objc[25247]: Class RTCVideoEncoderQpThresholds is implemented in both /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/Frameworks/WebRTC.framework/WebRTC (0x1136defd0) and /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/ICS Conference (0x10b867640). One of the two will be used. Which one is undefined.
    objc[25247]: Class RTCVideoEncoderSettings is implemented in both /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/Frameworks/WebRTC.framework/WebRTC (0x1136df048) and /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/ICS Conference (0x10b8676b8). One of the two will be used. Which one is undefined.
    objc[25247]: Class RTCVideoFrame is implemented in both /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/Frameworks/WebRTC.framework/WebRTC (0x1136df070) and /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/ICS Conference (0x10b8676e0). One of the two will be used. Which one is undefined.
    objc[25247]: Class RTCDispatcher is implemented in both /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/Frameworks/WebRTC.framework/WebRTC (0x1136e0178) and /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/ICS Conference (0x10b867758). One of the two will be used. Which one is undefined.
    objc[25247]: Class RTCCameraPreviewView is implemented in both /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/Frameworks/WebRTC.framework/WebRTC (0x1136e01a0) and /Users/zhangbin/Library/Developer/CoreSimulator/Devices/1C807845-8DFE-4C0B-AA5B-77D3FA4D532E/data/Containers/Bundle/Application/A1BAE1F1-5806-4CAB-8985-FCE0A02BD865/ICS Conference.app/ICS Conference (0x10b867780). One of the two will be used. Which one is undefined.
    2020-01-30 10:51:56.635560+0800 ICS Conference[25247:4414510] Failed to set (MCU) user defined inspected property on (UIPickerView): [<UIPickerView 0x7fbc6460ec50> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key MCU.
    2020-01-30 10:51:56.635851+0800 ICS Conference[25247:4414510] Failed to set (SFU) user defined inspected property on (UIPickerView): [<UIPickerView 0x7fbc6460ec50> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key SFU.
    2020-01-30 10:51:56.636056+0800 ICS Conference[25247:4414510] Failed to set (Mesh) user defined inspected property on (UIPickerView): [<UIPickerView 0x7fbc6460ec50> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key Mesh.
    [2020-01-30 10:51:56] [devel] endpoint constructor
    [2020-01-30 10:51:56] [devel] client constructor
    [2020-01-30 10:51:56] [devel] asio::init_asio
    [2020-01-30 10:51:56] [devel] set_open_handler
    [2020-01-30 10:51:56] [devel] set_close_handler
    [2020-01-30 10:51:56] [devel] set_fail_handler
    [2020-01-30 10:51:56] [devel] set_message_handler
    2020-01-30 10:52:57.725645+0800 ICS Conference[25247:4418070] NSURLConnection finished with error - code -1001
    2020-01-30 10:52:57.726288+0800 ICS Conference[25247:4414510] Error: Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={NSUnderlyingError=0x600000ec1890 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "The request timed out." UserInfo={NSErrorFailingURLStringKey=https://112.74.73.206:3004/rooms/?, NSErrorFailingURLKey=https://112.74.73.206:3004/rooms/?, _kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4, NSLocalizedDescription=The request timed out.}}, NSErrorFailingURLStringKey=https://112.74.73.206:3004/rooms/?, NSErrorFailingURLKey=https://112.74.73.206:3004/rooms/?, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2102, NSLocalizedDescription=The request timed out.}
    2020-01-30 10:52:57.728293+0800 ICS Conference[25247:4418070] Task <3FCCF816-AE6B-4207-B8CF-3FD6AC28A410>.<0> HTTP load failed, 0/0 bytes (error code: -999 [1:89])
    2020-01-30 11:03:16.485241+0800 ICS Conference[25247:4414510] [ZSPDEBUG Function:-[ConferenceConnectionViewController connectBtnTouchDown:] Line:201] can not read rooms info
    
    
    展开全文
  • 2019独角兽企业重金招聘Python工程师标准>>> ...

     

    150027_jBaY_1391394.png

    主线程main退出后 全局变量mutex 没有在 子线程销毁后销毁(析构)

    问题:主线程main退出后 detach后的子线程(C RT托管)和 全局静态变量(生命周期CRT托管)析构 的先后问题。

    翻了一遍CRT源码,,没找到 他们先后关系 ,

    但是这里的示例给出的答案是 main函数return后 detach了的子线程的结束在全局静态变量析构后

     

    吐槽:为什么会是这个顺序 CRT的设计者不会没考虑过这种情况吧?

    全局静态变量并不属于某个thread所有 为了方式出错也应该所有thread被结束后才析构(销毁)全局静态变量

    转载于:https://my.oschina.net/kkkkkkkkkkkkk/blog/1790482

    展开全文
  • 常见的浏览器分辨率

    2019-08-09 00:08:16
    测试web网页的适配,必须要了解下最主要的分辨率,以及最低适配; 16:9宽高比常见的分辨率有四种: 1280×720(17吋)、1366×768&1360×768(18.5吋)、1600×900 ......
    测试web网页的适配,必须要了解下最主要的分辨率,以及最低适配;


    16:9宽高比常见的分辨率有四种:

    1280×720(17吋)、1366×768&1360×768(18.5吋)、1600×900 
    (20吋)、1920×1080(21.5、23、23.6、24、24.6、25、27)。

    1280×800是笔记本常用的分辨率


    16:10常见的分辨率有1280×800(13.3、14.1、15.4吋笔记本)、1440×900(17.1吋、19吋)、

    1680×1050(20吋、21.6吋、22吋)、1920×1200(22、24、25.5、27、27.5)


    5:4常见的分辨率有1280×1024(17吋、19吋)

    三星214T 21吋4:3普屏液晶,分辨率1600×1200


    4:3常见的分辨率有800×600、1024×768(17吋CRT、15吋LCD)、1280×960、1400×1050(20吋)

    、1600×1200(20、21、22吋LCD)、1920×1440、2048×1536(高端CRT显示器)

    转载于:https://www.cnblogs.com/idotest/p/5203846.html

    展开全文
  • Using IPSec (IP Security Protocol) Table of Contents13.1 - What is IPSec? 13.2 - Thats nice, but why do I want to use IPSec? 13.3 - What are the protocols behind IPSec? 13.4 - O

     

    Using IPSec (IP Security Protocol)


     

    Table of Contents

    Portions of this document were taken from:


    13.1 - What is IPSec?

    IPSec is a set of extensions to the IP protocol family. It provides cryptographic security services. These services allow for authentication, integrity, access control, and confidentiality. IPSec provides similar services as SSL, but at the network layer, in a way that is completely transparent to your applications, and much more powerful. We say this because your applications do not have to have any knowledge of IPSec to be able to use it. You can use any IP protocol over IPSec. You can create encrypted tunnels (VPNs), or just do encryption between computers. Since you have so many options, IPSec is rather complex (much more so then SSL!)

    Before you start using IPSec, we strongly recommend that you check out the "recommended reading" of part 6 of the FAQ. In particular, if you don't already understand it, the Understanding IP Addressing document is highly recommended.

    In a logical sense, IPSec works in any of these three ways:

    • Host-to-Host
    • Host-to-Network
    • Network-to-Network
    In every scenario that involves a network, we mean to imply router. As in, Host-to-Router (and this router controls and encrypts traffic for a particular Network.)

    As you can see, IPSec can be used to tunnel traffic for VPN connections. However, its utility reaches beyond VPNs. With a central Internet Key Exchange registry, every machine on the internet could talk to another one and employ powerful encryption and authentication!

    13.2 - That's nice, but why do I want to use IPSec?

    The internet protocol, IP, aka IPv4, does not inherently provide any protection to your transferred data. It does not even guarantee that the sender is who he says he is. IPSec tries to remedy this. These services are considered distinct, but the IPSec supports them in a uniform manner.

     

    Confidentiality

    Make sure it is hard for anyone but the receiver to understand what data has been communicated. You do not want anyone to see your passwords when logging into a remote machine over the Internet.

     

    Integrity

    Guarantee that the data does not get changed on the way. If you are on a line carrying invoicing data you probably want to know that the amounts and account numbers are correct and not altered while in-transit.

     

    Authenticity

    Sign your data so that others can see that it is really you that sent it. It is clearly nice to know that documents are not forged.

     

    Replay protection

    We need ways to ensure a transaction can only be carried out once unless we are authorized to repeat it. I.e. it should not be possible for someone to record a transaction, and then replaying it verbatim, in order to get an effect of multiple transactions being received by the peer. Consider the attacker has got to know what the traffic is all about by other means than cracking the encryption, and that the traffic causes events favourable for him, like depositing money into his account. We need to make sure he cannot just replay that traffic later. WARNING: as per the standards specification, replay protection is not performed when using manual-keyed IPsec (e.g., when using ipsecadm(8)).

    13.3 - What are the protocols behind IPSec?

    IPSec provides confidentiality, integrity, authenticity, and replay protection through two new protocols. These protocols are called AH, Authentication header, and ESP, Encapsulated security payload.

    AH provides authentication, integrity, and replay protection (but not confidentiality). Its main difference with ESP is that AH also secures parts of the IP header of the packet (like the source/destination addresses).

    ESP can provide authentication, integrity, replay protection, and confidentiality of the data (it secures everything in the packet that follows the header). Replay protection requires authentication and integrity (these two go always together). Confidentiality (encryption) can be used with or without authentication/integrity. Similarly, one could use authentication/integrity with or without confidentiality.

    13.4 - On the wire format

    The Authentication Header (AH) comes after the basic IP header and contains cryptographic hashes of the data and identification information. The hashes can also cover the invariant parts of the IP header itself. There are several different RFCs giving a choice of actual algorithms to use in the AH, however they all must follow the guidelines specified in RFC2402.

    The Encapsulating Security Payload (ESP) header, allows for rewriting of the payload in encrypted form. The ESP header does not consider the fields of the IP header before it and therefore makes no guarantees about anything except the payload. The various types of ESP applicable must follow RFC2406. An ESP header can also provide authentication for the payload, (but not the outer header).

    An orthogonal (mostly) division of IPSec functionality is applied depending on whether the endpoint doing the IPSec encapsulation is the original source of the data or a gateway:

    • Transport mode is used by a host that is generating the packets. In transport mode, the security headers are added before the transport layer (e.g . TCP, UDP) headers, before the IP header is prepended to the packet. In other words an AH added to the packet will cover the hashing of the TCP header and some fields of the end-to-end IP header, and an ESP header will cover the encryption of the TCP header and the data, but not the end-to-end IP header.
    • Tunnel mode is used when the end-to-end IP header is already attached to the packet, and one of the ends of the secure connection is only a gateway. In this mode, the AH and ESP headers are used to cover the entire packet including the end-to-end header, and a new IP header is prepended to the packet that covers just the hop to the other end of the secure connection (though that may of course be several IP hops away).

    IPSec secured links are defined in terms of Security Associations (SAs). Each SA is defined for a single unidirectional flow of data, and usually (ignoring multicast) from one single point to another, covering traffic distinguishable by some unique selector. All traffic flowing over a single SA is treated the same. Some traffic may be subject to several SAs, each of which applies some transform. Groups of SAs are called an SA Bundle. Incoming packets can be assigned to a particular SA by the three defining fields, (Destination IP address, Security Parameter Index, security protocol). SPI can be considered a cookie that is handed out by the receiver of the SA when the parameters of the connection are negotiated. The security protocol must be either AH or ESP. Since the IP address of the receiver is part of the triple, this is a guaranteed unique value. They can be found from the outer IP header and the first security header (which contains the SPI and the security protocol).

    An example of a tunnel mode AH packet is:

     

    IPhdr AH IPhdr2 TCPhdr data

    An example of a transport mode AH packet is:

     

    IPhdr AH TCPhdr data

    Because an ESP header cannot authenticate the outer IP header, it is useful to combine an AH and an ESP header to get the following:

     

    IPhdr AH ESP TCPhdr data

    This is called Transport Adjacency. The tunneling version would look like:

     

    IPhdr AH ESP IPhdr2 TCPhdr data

    However it is not specifically mentioned in the RFC. As with Transport adjacency, this would authenticate the entire packet except a few headers in the IP header and also encrypt the payload (seen in italics). When an AH and an ESP header are directly applied together like this, the order of the headers should be as shown. It is possible in tunnel mode, to do arbitrary recursive encapsulation so that order is not specified.

    13.5 - Configuring IPSec

    How the IPSec systems and gateways are configured is to some extent left to the designer, however the RFC has some strong recommendations as to how this should be implemented, so as to minimize confusion.

    There are two administrative entities that control what happens to a packet. One is the Security Association Database (SAD, referred to as TDB or TDB table throughout OpenBSD's IPSec source code) and the other is the Security Policy Database (SPD).

    They are similar in that given a number of selectors that describe some traffic, they will deliver an entry that describes the processing needed. However, the SPD is two steps removed from the actual processing: the SPD is used for outgoing packets, to decide what SAD entries should be used, and the SAD entries in turn describe the actual process and the parameters for it. The SPD entries specify the existing SAD entries to use (if it's a bundle there can be more than 1), but if there is not already a suitable one, it is used to create new ones. The fields of the SA being created can be taken either from the SPD entry or from the packet that initiated the creation.

    Outgoing packets go from the SPD entry to the specific SA, to get encoding parameters. Incoming packets get to the correct SA directly using the SPI/DestIP/Proto triple, and from there get to the SPD entry.

    The SPD can also specify what traffic should bypass IPSec and what should be dropped, so it must also be consulted for incoming non-IPSec traffic. SPD entries must be explicitly ordered as several might match a particular packet, and the processing must be reproducible.

    The SPD can be thought of as similar to a packet filter where the actions decided upon are the activation of SA processes. Selectors can include src and dest address, port numbers if relevant, application and user IDs if available (only on host based transport SAs), hostnames, security sensitivity levels, protocols, etc.

    A SAD entry would include:

    • Dest IP address
    • IPSec proto (AH or ESP)
    • SPI (cookie)
    • Sequence counter
    • Seq O/F flag
    • Anti-replay window info
    • AH type and info
    • ESP type and info
    • Lifetime info
    • Tunnel/transport mode flags
    • Path MTU info

    A SPD entry would contain:

    • Pointer to active SAs
    • Selector fields

    Each SA can define one ESP header and one AH header. An IPSec session must have one or the other or both, but cannot be defined with neither - otherwise there would be no headers to specify the SPI to look up the SA. The RFC doesn't say what would happen if the AH and ESP headers disagree about the SPI value. One would presume this would imply multiple SAs in a bundle.

    The SPD in OpenBSD is managed through the ipsecadm flow command. (You would only make changes to it if you were using manual keying.) SAD entries can be set manually with ipsecadm(8), however the IETF has also defined automatic mechanisms for initialization of sessions and such things as key exchange. OpenBSD implements both Photuris (RFC2522, and RFC2523) and ISAKMP automatic key exchange (RFC2407, RFC2408, and RFC2409) in the photurisd(8) and isakmpd(8) daemons.

    13.6 - How do I setup IPSec with manual keying?

    Manual keying is the easiest way to get started with IPSec. You can setup encryption between networks, to create VPNs using this method. After you have read this section, you may want to investigate using /usr/share/ipsec/rc.vpn to set this up for you automatically.

    First, you need to turn on IP AH and IP ESP options in the OpenBSD kernel (if you are only using ESP, such as with the rc.vpn script, or as with the example below, then you do not need to enable AH. In fact, there may even be security concerns related to enabling AH if you are not using it).

    There is a nice sysctl to enable these protocols.

    # sysctl -w net.inet.esp.enable=1
    net.inet.esp.enable: 0 -> 1
    # sysctl -w net.inet.ah.enable=1
    net.inet.ah.enable: 0 -> 1
    You can edit /etc/sysctl.conf to turn these on at boot time. You need to remove the # mark from in front of net.inet.esp.enable and/or net.inet.ah.enable (depending on which you plan to use) and make sure they are set to 1.

    You also need to generate your manual keys. Since the security of the VPN is based on these keys being unguessable, it is very important that the keys be chosen using a strong random source. One practical method of generating them is by using the random(4) device. To produce 160 bits of randomness, for example, do:

    # dd if=/dev/urandom bs=1024 count=1 | sha1 The number of bits produced is important. Different cipher types may require different sized keys.
    Cipher    Key Length
    DES       56 bits
    3DES      168 bits
    BLF       Variable (40-160, 160 bits recommended)
    CAST      Variable (40-128, 128 bits recommended)
    SKIPJACK  80 bits
    

    Now, you need to setup SAs, or Security Associations. A Security Association is a combination of your IP addresses, an SPI, and your security protocol (AH and/or ESP). The IP addresses are both your own and that of your destination. The SPI, or Security Parameter Index, is a number that OpenBSD uses to classify different SAs.

    These examples only use ESP to encrypt your traffic. ESP includes authentication of the contained encrypted data, but does not authenticate the surrounding IP header, as AH would. This "limited authentication" is nevertheless quite sufficient in most cases, especially for ESP in a tunnel environment.

     

    # ipsecadm new esp -spi SPI_OUT -src MY_EXTERNAL_IP -dst PEER_EXTERNAL_IP -forcetunnel -enc blf -auth sha1 -key ENC_KEY -authkey AUTH_KEY

    Let's put this into practice with two routers, 192.168.5.1 and 192.168.25.9.

    On Host 192.168.5.1:

    # ipsecadm new esp -spi 1000 -src 192.168.5.1 -dst 192.168.25.9 -forcetunnel -enc blf -auth sha1 -key 7762d8707255d974168cbb1d274f8bed4cbd3364 -authkey 6a20367e21c66e5a40739db293cf2ef2a4e6659f
    # ipsecadm new esp -spi 1001 -dst 192.168.5.1 -src 192.168.25.9 -forcetunnel -enc blf -auth sha1 -key 7762d8707255d974168cbb1d274f8bed4cbd3364 -authkey 6a20367e21c66e5a40739db293cf2ef2a4e6659f
    On Host 192.168.25.9: # ipsecadm new esp -spi 1001 -src 192.168.25.9 -dst 192.168.5.1 -forcetunnel -enc blf -auth sha1 -key 7762d8707255d974168cbb1d274f8bed4cbd3364 -authkey 6a20367e21c66e5a40739db293cf2ef2a4e6659f
    # ipsecadm new esp -spi 1000 -dst 192.168.25.9 -src 192.168.5.1 -forcetunnel -enc blf -auth sha1 -key 7762d8707255d974168cbb1d274f8bed4cbd3364 -authkey 6a20367e21c66e5a40739db293cf2ef2a4e6659f

    Notice that the SPIs are different. See On the wire format for a complete description of what the SPI is and where it is used.

    Now that you have your Security Associations in place, set up your flows.

    On 192.168.5.1:

    So, right here, two flows will be created, one the local source address, which covers all packets originating from the local host to the destination, as well as a flow from the destination back to the local host.

    # ipsecadm flow -proto esp -dst 192.168.25.9 -spi 1000 -addr 192.168.5.1 255.255.255.255 192.168.25.9 255.255.255.255 On 192.168.25.9: # ipsecadm flow -proto esp -dst 192.168.5.1 -spi 1001 -addr 192.168.25.9 255.255.255.255 192.168.5.1 255.255.255.255

    If you want less overhead on your Host-to-Host VPNs, creating the SPI without -forcetunnel will let you use transport mode (whereas, -forcetunnel makes sure all of the IP packet, including the IP header, are encapsulated by SPI). If either the source or destination is a network, you will have to use tunnel mode. Creating an SA to and/or from a network will automatically ensure tunnel mode SPIs are being created.

    This is a simple way to start using IPSec.

    You can use IPSec to tunnel private IP address spaces over the Internet. Here is a good example... We want to tunnel 192.168.99.0/24, which is behind 208.1.1.1, to 208.1.2.0/24 and 208.1.5.0/24 which are behind 208.2.2.2. These examples were generated using the rc.vpn script.

    As you can see, when you are using manual keying with IPSec, you have to specify exactly what you want done. It won't guess for you. Look at these examples...

    On 208.1.1.1:

    First, set up the security associations (SAs):
    (This sets up the SPIs, encryption methods, and keys.) # ipsecadm new esp -src 208.1.1.1 -dst 208.2.2.2 -forcetunnel -spi 1001 -enc blf -auth sha1 -key 7762d8707255d974168cbb1d274f8bed4cbd3364 -authkey 67e21c66e5a40739db293cf2ef2a4e6659f
    # ipsecadm new esp -src 208.2.2.2 -dst 208.1.1.1 -forcetunnel -spi 1000 -enc blf -auth sha1 -key 7762d8707255d974168cbb1d274f8bed4cbd3364 -authkey 67e21c66e5a40739db293cf2ef2a4e6659f
    Next, setup a flow from 208.1.1.1 to 208.2.2.2 # ipsecadm flow -proto esp -dst 208.2.2.2 -spi 1001 -addr 208.1.1.1 255.255.255.255 208.2.2.2 255.255.255.255
    Next, setup a flow from 208.1.2.0/24, which is behind 208.2.2.2, to 192.168.99.0/24 # ipsecadm flow -proto esp -dst 208.2.2.2 -spi 1001 -addr 192.168.99.0 255.255.255.0 208.1.2.0 255.255.255.0
    Next, setup a flow from 208.1.5.0/24, which is behind 208.2.2.2, to 192.168.99.0/24 # ipsecadm flow -proto esp -dst 208.2.2.2 -spi 1001 -addr 192.168.99.0 255.255.255.0 208.1.5.0 255.255.255.0
    Now, setup a flow from 208.1.2.0/24, which is behind 208.2.2.2 to the router 208.1.1.1. # ipsecadm flow -proto esp -dst 208.2.2.2 -spi 1001 -addr 208.1.1.1 255.255.255.255 208.1.2.0 255.255.255.0
    OK, setup a flow from 208.1.5.0/24, which is behind 208.2.2.2, to the router 208.1.1.1 # ipsecadm flow -proto esp -dst 208.2.2.2 -spi 1001 -addr 208.1.1.1 255.255.255.255 208.1.5.0 255.255.255.0
    Finally, setup a flow from the router 208.2.2.2 to 192.168.99.0/24 # ipsecadm flow -proto esp -dst 208.2.2.2 -spi 1001 -addr 192.168.99.0 255.255.255.0 208.2.2.2 255.255.255.255

     

    On 208.2.2.2:

    Same as before, we setup the SAs... # ipsecadm new esp -src 208.2.2.2 -dst 208.1.1.1 -forcetunnel -spi 1000 -enc blf -auth sha1 -key 7762d8707255d974168cbb1d274f8bed4cbd3364 -authkey 67e21c66e5a40739db293cf2ef2a4e6659f
    # ipsecadm new esp -src 208.1.1.1 -dst 208.2.2.2 -forcetunnel -spi 1001 -enc blf -auth sha1 -key 7762d8707255d974168cbb1d274f8bed4cbd3364 -authkey 67e21c66e5a40739db293cf2ef2a4e6659f
    Now, this is the reverse side... Setup a flow from the router 208.2.2.2 to 208.1.1.1 # ipsecadm flow -proto esp -dst 208.1.1.1 -spi 1000 -addr 208.2.2.2 255.255.255.255 208.1.1.1 255.255.255.255
    Setup a flow from the network 192.168.99.0/24, which is behind 208.1.1.1, to 208.1.2.0/24 # ipsecadm flow -proto esp -dst 208.1.1.1 -spi 1000 -addr 208.1.2.0 255.255.255.0 192.168.99.0 255.255.255.0
    Setup a flow from the network 192.168.99.0/24, which is behind 208.1.1.1, to 208.1.5.0/24 # ipsecadm flow -proto esp -dst 208.1.1.1 -spi 1000 -addr 208.1.5.0 255.255.255.0 192.168.99.0 255.255.255.0
    Now, setup a flow from 192.169.99.0/24, which is behind 208.1.1.1, to the router 208.2.2.2 # ipsecadm flow -proto esp -dst 208.1.1.1 -spi 1000 -addr 208.2.2.2 255.255.255.255 192.168.99.0 255.255.255.0
    We're almost done... Two flows left to get 208.1.2.0/24 and 208.1.5.0/24 from the router 208.2.2.2 to the router 208.1.1.1. # ipsecadm flow -proto esp -dst 208.1.1.1 -spi 1000 -addr 208.1.2.0 255.255.255.0 208.2.2.2 255.255.255.255 -ingress
    # ipsecadm flow -proto esp -dst 208.1.1.1 -spi 1000 -addr 208.1.5.0 255.255.255.0 208.2.2.2 255.255.255.255 -ingress

    If you have been using ipsecadm, and you want to get rid of any work that you've done, and start from scratch, do

    # ipsecadm flush This will flush all IPSec info (SPIs, flows, routing entries) from your system.

    13.7 - How do I setup photurisd?

    Photuris is not widely used and is still considered experimental as far as the RFC status is concerned. However, many people have used it with OpenBSD.

    To setup your photurisd, first edit /etc/photuris/secrets.conf on each host with photurisd.

    bsd# cat /etc/photuris/secrets.conf
    # Accepted keywords are:
    # identity local "id" "secret"
    # identity pair local "receivedid" "myid" "secret"
    # identity remote "id" "secret"
    # identity lookup "tag" username
    # Simple 
    identity local "Default" "This should be changed."
    identity remote "Default" "This should be changed."
    
    Change "This should be changed." to a key of your choice on the local config, and another key of your choice on the remote config. (Use the same config on your remote box but swap "local" and "remote" so that it sees itself as the local key.) Note that these keys will be replaced in a future version of photurisd that will carry out its initial key exchange with public keys.

    Make sure net.inet.ah.enable is set to 1.

    bsd# sysctl -w net.inet.ah.enable=1
    net.inet.ah.enable: 0 -> 1
    
    And run startkey.
    bsd# startkey dst=remote.host
    
    Now, run tcpdump to verify that your packets are being encrypted with AH. (Run a ping in another window or session to generate traffic.)
    bsd# tcpdump proto ah
    
    You can also try using tcpdump by the host address if you aren't getting anything.
    bsd# tcpdump host remote.host
    
    You can make photurisd automatically set the source and destination host or networks in /etc/photuris/photuris.startup

    13.8 - How do I setup isakmpd?

    If you are thinking about VPNs or other traditional applications of IPSec, you probably are going to use ISAKMP. Some commercial implementations of IPSec do not provide any manual keying ability, instead they require you to use some form of ISAKMP.

     

    13.8.1 - What is isakmpd?

    ISAKMP (sometimes referred to as IKE, or Internet Key Exchange) is the key exchange mechanism for the VPN. It meets security concerns using the methods mentioned in RFC 2407, RFC 2408 and RFC 2409. ISAKMP manages the exchange of cryptographic keys that you would normally have to manage with ipsecadm(8). It employs a two-phase process for establishing the IPSec parameters between two IPSec nodes.

    Phase 1 - The two ISAKMP peers establish a secure, authenticated channel upon which to communicate between two daemons. This establishes a Security Association (SA) between both hosts. Main Mode and Aggressive Mode are the methods used to establish this channel. Main Mode sends the various authentication information in a certain sequence, providing identity protection. Aggressive Mode does not provide identity protection because all of the authentication information is sent at the same time. Aggressive mode should only be used in such cases where network bandwidth is of concern.

    Phase 2 - Security Associations are negotiated on behalf of IPSec. Phase 2 is establishes tunnels or endpoint SAs between IPSec hosts. Quick Mode is used in Phase 2 because there is not need to repeat a full authentication because Phase 1 has already established the SAs.

    In brief, Phase 1 is used to get a secure channel in which to do the (quicker) phase 2 setups. There can be multiple phase 2 setups within the same phase 1 channel. Phase 2 is used to setup the actual tunnels. In Phase 1, your IPSec nodes establish a connection where they exchange authentication (Either a X509 certificate or a pre-shared secret). This allows each end to make sure the other end is authenticated. Phase 2 is an exchange of keys to determine how the data between the two will be encrypted.

    13.8.2 - How do I get started with isakmpd?

    By default, OpenBSD comes with the proper binaries for ISAKMP and the IPSec stack. Unfortunately, the same cannot be said for the sample files. To retrieve them, you need to grab: /usr/src/sbin/isakmpd/samples/VPN-east.conf and /usr/src/sbin/isakmpd/samples/policy from the source tree. You can either use your CD (if you have one), cvsweb, or the command line CVS client. (Cvsweb has VPN-east.conf and policy readily available). For the purposes of this example, copy policy to /etc/isakmpd/isakmpd.policy. Copy VPN-east.conf to /etc/isakmpd/isakmpd.conf. Here we attempt to show you how to setup a VPN (tunnel). If you want to use isakmpd between single hosts, there are other configuration files in the samples directory. The manual pages have detailed information.. Don't forget isakmpd.conf(5) and isakmpd.policy(5).

    Your first step is to turn on esp. The top of section 13.6 tells you how to do this both for run-time and boot. Next, you need to edit /etc/isakmpd.policy. This file tells ISAKMP who can access IPSec. In this scenario, the policy file states that anybody who sends data using Encapsulate Security Payload(ESP), and has authenticated with the passphrase mekmitasdigoat (or whatever passphrase you determine), is allowed to communicate with isakmpd. You can modify this file to let ISAKMP know that we only want to allow data signed with certain digital certificates or using a certain encryption transform. You could also allow anybody to access IPSec. This is only recommended for testing. To do this, edit your policy file to contain only the following lines:

    KeyNote-Version: 2
    Authorizer: "POLICY"
    

    The same policy file contains two lines that start with the $ character. You need to remove these lines before using it, they are only for cvs.

    A more useful policy file for this example looks like this:

    KeyNote-Version: 2
    Comment: This policy accepts ESP SAs from a remote that uses the right password
    Authorizer: "POLICY"
    Licensees: "passphrase:mekmitasdigoat"
    Conditions: app_domain == "IPSec policy" &&
                esp_present == "yes" -> "true"; 
    
    Implementing this will give you a basic VPN (tunnel) using ESP only. On host A, edit /etc/isakmpd/isakmpd.conf. The 249.2.2.2 sample IP address should be replaced with the external IP address of host A.
    [General] 
    Retransmits=		5
    Exchange-max-time=	120
    Listen-on=		249.2.2.2
    
    Do similar for isakmpd.conf on host B. 249.3.3.3 represents the external IP address for host B.
    [General]
    Retransmits=		5
    Exchange-max-time=	120
    Listen-on=		249.3.3.3
    

    This is where you can setup the variables that will affect the main behavior of isakmpd. It is okay to use the defaults here. The Listen-on= value specifies the IP that isakmpd should listen on. Only the Internet IP of your gateway is necessary. If you have multiple external interfaces on your gateway, you could list which interfaces you want to listening on by entering them using a comma separated list.

    Next, on host A, edit isakmpd.conf again.

    [Phase 1]
    249.3.3.3=		HostB
    
    On host B:
    [Phase 1]
    249.2.2.2=		HostA
    

    This section describes the IP addresses to accept in order to negotiate the phase 1 connection. Its value points to the section below (Remember that phase 1 simply authenticates the remote peer to make sure they are who they say they are). You can list multiple peers with additional lines in the format of IP_Address= <PEER-NAME>.

    Next, on host A:

    [Phase 2]
    Connections=		HostA-HostB
    
    On host B:
    [Phase 2]
    Connections=		HostB-HostA
    

    This describes Phase 2 of the connection. This is the phase that determines what protocols the two peers will use to communicate.

    The Connections= tag refers to the section below. It initiates the requirements or the accepted methods to set up Phase 2. This also tells ISAKMPD which connections to initiate once started. Note that you can have multiple sections as illustrated below if you are to connect with multiple peer hosts.

    If you do not have the IP address of the remote host, you can specify a Default= that points to a section describing a generic entry that will be referenced by any incoming IP that is not listed in the Connections= tag.

    On host A:

    [HostB]
    Phase=			1
    Transport=		udp
    Local-address=		249.2.2.2
    Address=		249.3.3.3
    Configuration=		Default-main-mode
    Authentication=		mekmitasdigoat
    #Flags=
    
    On host B:
    [HostA]
    Phase=			1
    Transport=		udp
    Local-address=		249.3.3.3
    Address=		249.2.2.2
    Configuration=		Default-main-mode
    Authentication=		mekmitasdigoat
    #Flags=
    
    These represent the sections referred to by the Phase 1 section above. They each describe the requirements that the peer gateway must fulfill in order to proceed to Phase 2. There are many other options here but the ones mentioned above are the minimum requirements.
    • Phase=1 is required because the ISAKMPD code uses the same procedures to process Phase 1 and Phase 2. It must be 1 or nothing will work.
    • Transport= gives you different possibilities for different peers. It's suggested that udp be used here so we'll leave it at that. Please note that some peers may be behind a firewall that doesn't let UDP traffic through. Obviously, this needs to be determined before setup.
    • Local-address is the destination address that the incoming packets point to. In some cases, you can be listening on different Interfaces for Phase 1 connections. In this example, there is only 1 interface listening, therefore this is the IP of the listening interface on this peer.
    • Address= is the address that points to the source IP of the incoming packets. This usually points to the peer gateway. This needs further explanation, because the source IP address of the peer may be unknown!
    • Configuration= points to the section below. You can specify multiple sections like this. We use the default one specified by the sample file.
    • Authentication= is the pre-shared secret to be used for this particular peer. It is more or less a passphrase that each peer uses. This passphrase gets passed to policy to verify whether this peer is allowed to use IPSEC with this host. If you change this phrase, you must also change it in the policy file because the sample file provides for this passphrase. If you decided to go with a minimum policy file then you can specify whatever you want here.
    • Flags= is not currently being used. The RFCs leave room for extra options to be specified for phase 1.

      There are other tags here that will allow for other options to be set. Refer to isakmpd.conf(5) for descriptions.

    On Host A:

    [HostA-HostB]
    Phase=			2
    ISAKMP-peer=		HostB
    Configuration=		Default-quick-mode
    Local-ID=		Net-A
    Remote-ID=		Net-B
    
    On Host B:
    [HostB-HostA]
    Phase=			2
    ISAKMP-peer=		HostA
    Configuration=		Default-quick-mode
    Local-ID=		Net-B
    Remote-ID=		Net-A
    

    These represent the sections referred to by the Phase 2 section above. They are the individual settings that ISAKMPD must use to talk between the two gateways for the particular connection.

    • Phase=2 is required because ISAKMPD code uses the same functions to authenticate Phase 1 and Phase 2. This is required for the VPN to work.
    • ISAKMPD-Peer= is the name of Host section above. This means that we are talking to that particular peer to establish a Phase 2 connection. This is provided because you can have multiple sections to describe isakmp peers and connections.
    • Configuration= refers to the section below that describes the standards by which this host and the particular peer for this connection must abide.
    • Local-ID= refers to an IPSec-ID section below that describes our Private Network to the peer gateway. This is the portion that is passed so that the other gateway can set up the proper routing table that will transfer data over the VPN to our network.
    • Remote-ID= refers to an IPSec-ID section below that describes what is supposed to be the remote Private Network to our host. This portion is interpreted to set up the proper routing tables that will transfer data from our Private Network over the VPN to the remote Private Network.

      There is another tag that is supported here called Flags=. If you require this tag, read isakmpd.conf(5).

    This is the IPSec-ID section. These entries need to exist in the isakmpd.conf files for both Host A and Host B. This example will setup 192.168.1.0/255.255.255.0 for Host A (which was connected to Net-A above) and 192.168.20.0/255.255.255.0 for Host B (Net-B above).

    [Net-A]
    ID-type=		IPV4_ADDR_SUBNET
    Network=		192.168.1.0
    Netmask=		255.255.255.0
    
    [Net-B]
    ID-type=		IPV4_ADDR_SUBNET
    Network=		192.168.20.0
    Netmask=		255.255.255.0
    

    These two sections are in the conf file of each host. They are the sections referenced by the Local-ID and Remote-ID identifiers. They describe the routes that should be set up to allow traffic from one private network to another. ID-type= can be IPV4_ADDR_SUBNET or IPV4_ADDR (RFC2708 mentions more possible values. Currently only IPv4 is supported in the OpenBSD implementation. IPv6 may be supported in OpenBSD-current. )

    Now, on both hosts, the sample file should read:

    [Default-main-mode]
    DOI=			IPSEC
    EXCHANGE_TYPE=		ID_PROT
    Transforms=		3DES-SHA
    
    This section describes the requirements for the encryption methods of Phase 1 connections. The name reflects the value of Configuration= variable. As we can see here, we are stating our Domain of Interest which is IPSEC. The EXCHANGE_TYPE variable is set to ID_PROT for Phase 1, which identifies the protocols to be covered by this Authentication. Transforms= is the transform required (or assigned) for this exchange. In this case, this points to the section below in the configuration file that says we are receiving a packet encrypted with 3DES and a checksum verifiable with SHA. There are a bunch of different transforms defined inside the sample VPN-east.conf. These are provided because 3DES and SHA are not always supported across different platforms. For OpenBSD there should be no reason to change this for a basic setup. Feel free to create multiples of this section and change the transform. The only requirement is that you change the Configuration= variable.
    [Default-quick-mode]
    DOI=			IPSEC
    EXCHANGE_TYPE=		QUICK_MODE
    Suites=			QM-ESP-3DES-SHA-PFS-SUITE,QM-ESP-DES-MD5-PFS-SUITE
    

    This section describes the requirements for the encryption of the data to be sent through the VPN and is referred to by Configuration above. Note the difference between this section and the Phase 1 equivalent just above is that the EXCHANGE_TYPE is QUICK_MODE. This is always the case for Phase 2. Suites= points to a IPSec Suite section describing the different encryption schemes available between the two hosts. There is much more to be said about ISAKMP and IPSec. By using the above basic descriptions you should be able to create a simple but solid VPN that cares and feeds itself. This is the bare minimum isakmpd.conf for both hosts here.

    13.8.3 - Starting isakmpd

    You may wish to use

     

    # isakmpd -d -DA=99

    the first time you decide to run this daemon. The daemon will not be running in daemon mode but as a regular process. It will log everything to your terminal. To stop isakmpd and flush the routes, you need to kill the isakmpd process on each node, and run ipsecadm flush.

    13.9 - How do I use isakmpd with X.509 certificates?

    Setting up isakmpd to use certificates instead of pre-shared keys is not really that much harder in a big network with many untrusted peers than it would be with a small network. It may actually simplify configuration, and more importantly, key management.

     

    Generating certificates.

    There is a good description of how to generate keys and certificates in the README.PKI file in the isakmpd source directory. You need to have a CA key, a corresponding CA X.509 certificate, one private key for each computer on the network that will use isakmpd and one X.509 certificate for each such key.

    The X.509 certificates need to have a Subject Alternative Name (SubjectAltName) extension describing the certificate holder. How to set a SubjectAltName extension using certpatch for a certificate is also described in README.PKI for the case of setting an IP address as the SubjectAltName. Using an IP address here is also the default behaviour for isakmpd.

    Certpatch also support using either a FQDN (Fully Qualified Domain Name) or a UFQDN (User FQDN). An example of an FQDN might be www.openbsd.org, an example of an UFQDN would be an email address. Something like Jorgen.Granstam@abc.se for example.

    In this howto document I am going to use FQDNs as SubjectAltNames. Using IP addresses would be a bit easier since that is the default behaviour of isakmpd but it is not much of a difference as we soon will see.

    To insert an FQDN SubjectAltName into a certificate one would do something like this:

     

    $ /usr/sbin/certpatch -t fqdn -i home.mysite.se -k ca.key originalcert.crt newcert.crt Here the ca.key is the private key of the CA, thus this can only be done by whoever has access to the CA private key. The (fictional) home.mysite.se is the FQDN to be inserted into the certificate. The originalcert.crt and newcert.crt filenames may be the same name in which case the original file will be overwritten by the new modified certificate.

    Put the keys and certificates in the directories as described at the end of README.PKI. The CA key (ca.key) should be kept in some safe place if the keys are really to be seriously used.

    Configuration of isakmpd

    Lets now look at the /etc/isakmpd/isakmpd.conf configuration file. It was originally taken from the example file in isakmpd.conf(5) but have been heavily modified. I will also use a much shorter file here than the example file in the man-page, I have removed from that file most parts that are not needed in this setup. In part to simplify the understanding of this setup. I have also added some commenting (some comments are left as in the isakmpd.conf(5)) and changed some names. None of the domain names used here exists as far as I know.

    Actually since everyone who reads this already have a working configuration for the preshared keys case (see previous section) there won't be many surprises in this file. I won't explain this in every detail, check isakmpd.conf(5) for descriptions of the parts I don't comment on.

    Let's assume our setup looks something like this

    one.mysite.se                                        one.worksite.se
     192.168.1.2--+    10.0.0.1====/======10.0.0.2     +--192.168.2.2 
                  |  gw.mysite.se       gw.worksite.se |
                  +--192.168.1.1         192.168.2.1---+
    two.mysite.se |                                    | two.worksite.se
     192.168.1.3--+                                    +--192.168.2.3
    

    That is, two networks that should be connected using an IPSec tunnel over an otherwise insecure network. Ignore the fact that I am using IP addresses reserved for private Internets here (RFC1918), I have to use something. I won't explain how to use isakmpd in combination with NAT or similar (because I haven't tried that myself).

    Now, let's look at the configuration file. This is the file for the security gateway gw.mysite.se:

    # *****************************************************************
    # ************* Start of the gw.mysite.se isakmpd.conf ************
    # *****************************************************************
    
    # A configuration sample for the isakmpd ISAKMP/Oakley (aka IKE) daemon.
    [General]
    Policy-File=            /etc/isakmpd/policy
    Retransmits=            5
    Exchange-max-time=      120
    Listen-on=              10.0.0.1
    
    
    # The name work-gw here is used just as a section name and a tag for
    # use in this configuration file below and need not actually be the 
    # real hostname or domain name of the peer (but it could be). The IP 
    # address however needs to be correct. Phase 1, as you might already
    # know, is to negotiate an ISAKMP security association (SA). There 
    # should of course be one IP and name for each peer we want to
    # communicate with.
    [Phase 1]
    10.0.0.2=               work-gw
    
    
    # Now phase 2 is negotiating IPSec SAs. As in phase 1, the name here
    # is a section name to be used later. Actually, it can be a comma
    # separated list of section names here. Thus if traffic from many
    # networks (or individual hosts) should be forwarded through this
    # tunnel, more section names would be added (and of course corresponding 
    # new sections further down). 
    [Phase 2]
    Connections=            work-gw-my-gw
    
    
    # Now, here are some parameters for the ISAKMP SA negotiations. Almost 
    # self documenting. The section name is from [Phase 1] above. The most 
    # interesting tag might be the ID tag. The ID tag is set to the name
    # of the section where the identity information about this host that 
    # will be presented to connecting peers, can be found. If the ID tag 
    # is not available, isakmpd will assume that it will identify itself 
    # using the IP address. You might also notice that there is no longer 
    # any authentication tag here in this configuration. The authentication
    # data is currently used only in the preshared key case. 
    [work-gw]
    Phase=                  1
    Transport=              udp
    Local-address=          10.0.0.1                # Local address
    Address=                10.0.0.2                # Peer address
    ID=                     my-ID
    Configuration=          Default-main-mode
    
    
    # This is the identity data. ID-type may also be IPV4_ADDR (the
    # default), IPV4_ADDR_SUBNET or UFQDN. The Name tag is used for 
    # FQDN and UFQDN, for IPV4_ADDR an Address tag would be used instead.
    # For IPV4_ADDR_SUBNET a Network and a Netmask tag would be used.  
    [my-ID]
    ID-type=                FQDN
    Name=                   gw.mysite.se
    
    
    # This is the section for the IPSec connection. The section name is
    # from the list in the [Phase 2] section above. The ISAKMP-peer is,
    # of course, the tag of our peer from section [Phase 1] above. The 
    # Local-ID and Remote-ID tags should be section names describing which
    # packages should be forwarded over the IPSec tunnel to the remote 
    # network.
    [work-gw-my-gw]
    Phase=                  2
    ISAKMP-peer=            work-gw
    Configuration=          Default-quick-mode
    Local-ID=               Net-west
    Remote-ID=              Net-east
    
    # Any packet originating from a computer on the network described
    # here... 
    [Net-west]
    ID-type=                IPV4_ADDR_SUBNET
    Network=                192.168.1.0
    Netmask=                255.255.255.0
    
    # ... and with a destination matching the network described here, 
    # will be encrypted and forwarded over the IPSec tunnel to the remote 
    # system. 
    [Net-east]
    ID-type=                IPV4_ADDR_SUBNET
    Network=                192.168.2.0
    Netmask=                255.255.255.0
    
    # Main mode descriptions
    
    
    # Here are the data for main mode. Using DES here for real purposes
    # is not very smart since DES is no longer considered a secure
    # encryption algorithm. 3DES is generally considered to have much better
    # security since it has enough bits in the key to be considered secure. 
    # Transforms is a list of tags describing main mode transforms. In 
    # this example we have only one.
    [Default-main-mode]
    DOI=                    IPSEC
    EXCHANGE_TYPE=          ID_PROT
    Transforms=             3DES-MD5
    
    
    # Certificates stored in PEM format
    # This is important when using certificates. The CA certificates should 
    # be in the CA-directory (but not the CA private key of course).
    # The Cert-directory should have at least the certificate for the
    # local host but other certificates are also allowed. The private key 
    # should be the private key of the local host. 
    [X509-certificates]
    CA-directory=           /etc/isakmpd/ca/
    Cert-directory=         /etc/isakmpd/certs/
    Private-key=            /etc/isakmpd/private/local.key
    
    # Main mode transforms
    ######################
    
    # Here is our main mode transform. The important thing here is to use
    # RSA_SIG as authentication method when using certificates. It is the
    # only method supported when using certificates so far. Commercial
    # entities in the US will thus have to wait until September 2000 to
    # use this due to the RSA patent. Luckily, I am not living in the US. 
    # Also important is the GROUP_DESCRIPTION tag. It must match the
    # GROUP_DESCRIPTION tag in the Quick mode transforms further down. 
    # The Life tag here could possibly be modified. The LIFE_60_SECS might 
    # be shorter than necessary for normal use. 
    
    [3DES-MD5]
    ENCRYPTION_ALGORITHM=   3DES_CBC
    HASH_ALGORITHM=         MD5
    AUTHENTICATION_METHOD=  RSA_SIG
    GROUP_DESCRIPTION=      MODP_1024
    Life=                   LIFE_60_SECS,LIFE_1000_KB
    
    # Quick mode description
    ########################
    
    [Default-quick-mode]
    DOI=                    IPSEC
    EXCHANGE_TYPE=          QUICK_MODE
    Suites=                 QM-ESP-3DES-MD5-PFS-SUITE
    
    # Quick mode protection suites
    ##############################
    # 3DES
    
    [QM-ESP-3DES-MD5-PFS-SUITE]
    Protocols=              QM-ESP-3DES-MD5-PFS
    
    # 3DES
    
    [QM-ESP-3DES-MD5-PFS]
    PROTOCOL_ID=            IPSEC_ESP
    Transforms=             QM-ESP-3DES-MD5-PFS-XF
    
    # Quick mode transforms
    
    # Don't forget. The GROUP_DESCRIPTION must match the GROUP_DESCRIPTION 
    # in main mode above. For forwarding packets between two networks (or
    # from a host to a network) we use TUNNEL mode. Between two hosts we
    # may also use TRANSPORT mode instead. 
    [QM-ESP-3DES-MD5-PFS-XF]
    TRANSFORM_ID=           3DES
    ENCAPSULATION_MODE=     TUNNEL
    AUTHENTICATION_ALGORITHM=       HMAC_MD5
    GROUP_DESCRIPTION=      MODP_1024
    Life=                   LIFE_60_SECS
    
    
    # As we know from the isakmpd.config manpage the LIFE_DURATION here is 
    # an offer value (60), a minimum acceptable value (45) and a maximum
    # acceptable value. The isakmpd.conf example has this set to 
    # 600,450/720 instead. That might be a better value for normal use.
    [LIFE_60_SECS]
    LIFE_TYPE=              SECONDS
    LIFE_DURATION=          60,45:72
    
    [LIFE_1000_KB]
    LIFE_TYPE=              KILOBYTES
    LIFE_DURATION=          1000,768:1536
    
    # *****************************************************************
    # ************* End of the gw.mysite.se isakmpd.conf **************
    # *****************************************************************
    

    So far the configuration for the local system. The remote system is configured just the same way only opposite. Thus only the first part of the isakmpd.conf file differs. Let's just look at that first part of the isakmpd.conf file for the security gateway gw.worksite.se:

     

    # *****************************************************************
    # ************* Start of the gw.worksite.se isakmpd.conf **********
    # *****************************************************************
    
    [General]
    Policy-File=            /etc/isakmpd/policy
    Retransmits=            5
    Exchange-max-time=      120
    Listen-on=              10.0.0.2
    
    [Phase 1]
    10.0.0.1=               my-gw
    
    [Phase 2]
    Connections=            work-gw-my-gw
    
    [my-gw]
    Phase=                  1
    Transport=              udp
    Local-address=          10.0.0.2                # Local address
    Address=                10.0.0.1                # Peer address
    ID=                     work-ID
    Configuration=          Default-main-mode
    
    [work-ID]
    ID-type=                FQDN
    Name=                   gw.worksite.se
    
    [work-gw-my-gw]
    Phase=                  2
    ISAKMP-peer=            my-gw
    Configuration=          Default-quick-mode
    Local-ID=               Net-east
    Remote-ID=              Net-west
    
    # *****************************************************************
    # ********************** ... to be continued **********************
    # *****************************************************************
    

    Now that wasn't so hard, just a bit boring to read perhaps. A slightly more interesting part next.

     

    The policy file.

    Actually, the policy file might be slightly confusing for anyone who has not used it before, especially if things doesn't work as expected. The man-page isakmpd.policy(5) is not really that bad. It might perhaps be a little bit unclear in some parts but generally it's good.

    The simplest possible working policy file would contain just a single line:

     

    authorizer: "POLICY"
    

    This basically means that that there is no policy limitations on who would be allowed to connect. Thus not a very secure setup. The authorizer tag here means the one who has the authorization to decide the policy. The special authorizer "POLICY" has the ultimate and unlimited authority on policy. Any other authorizer must first be authorized by "POLICY" to have any authority here.

    There can also be a set of conditions for what is allowed. The following policy thus would mean that only someone using the ESP protocol with some real encryption would be authorized (oh well, someone using DES would also be authorized here although DES could almost be considered snakeoil today, it is left as an exercise for the reader to change this policy into not allowing DES either). Note that anyone who does encrypts with ESP would still be allowed.

     

    authorizer: "POLICY"
    conditions: app_domain == "IPsec policy" &&
                esp_present == "yes" &&
                esp_enc_alg != "null" -> "true";
    
    

    It is also possible to "sublicense" authority to someone else (might be one or more entities). The simple case would be the preshared key case. In that case, anyone who knows the preshared passphrase is authorized. Thus:

     

    authorizer: "POLICY"
    licensees:  "passphrase:something really secret"
    conditions: app_domain == "IPsec policy" &&
                esp_present == "yes" &&
                esp_enc_alg != "null" -> "true";
    

    This would authorize anyone who knows this passphrase to connect and comply with the conditions (but remember that the passphrase must also be set in the Authentication tag in isakmpd.conf).

    Nothing difficult so far. Now to the interesting stuff. First there can be many licensees, although all must be authorized by "POLICY". Further, authorized licensees can sublicense to other licensees. A licensee can be just a string in case it is further described in the policy file:

     

    authorizer: "POLICY"
    licensees:  "subpolicyAH" ||  "subpolicyESP"
    conditions: app_domain == "IPsec policy" -> "true";
    
    authorizer: "subpolicyESP" 
    licensees:  "passphrase:something more secret"
    conditions: esp_present == "yes" -> "true";
    
    authorizer: "subpolicyAH" 
    licensees:  "passphrase:something really secret"
    conditions: ah_present == "yes" -> "true";
    

    And now to what everyone has been waiting for. Policy can also be sublicensed or delegated to a key. In this case it is usually a X.509 certificate. The simple use of certificates would be to use them like the passphrases. Just insert individual users certificates in the policy file:

     

    keynote-version: 2
    comment: This is an example of a policy delegating to a key.
    authorizer: "POLICY"
    licensees: "x509-base64:        MIIBsTCCARoCAQAwDQYJKoZIhvcNAQEEBQAwITELMAkGA1UEBhMCc2UxEjAQBgNV        BAMTCUlLRUxBQiBDQTAeFw0wMDAxMjgxNzQyMTZaFw0wMTAxMjcxNzQyMTZaMCEx        CzA           This is would be a user certificate           AQEB        BQA                                                         IUuz        eOW8P5UGJUH2JVkiA2CTDryFf0CHYwd2P003dtVYw5RvET7XLMpRZiCcWtBdxneW        ct+016zUBP/cQMMl+KownxAUq9ezA8GvTyUWC97SOMOgoVj/QR3FHmEjpUi3AgMB        AAEwDQYJKoZIhvcNAQEEBQADgYEALGShaAxHvGncev0iFnKrJI4x5T4vlaMP1ad+        iWLV5q9H3wickVGN0NPerq0YLwx/VA9WaecYN8V+ALtNKYPuDiT11zwvE8GQeaai        NuzgmQ9hh3GifEgN9VEiC3j4kTytonKr0Q+vTLM7xYzheOxvrtUErRwZ9Xs1KzHe        yiXHSU8="
    conditions: app_domain == "IPsec policy" &&
                esp_present == "yes" &&
                esp_enc_alg != "null" -> "true";
    

    Now, this is obviously a stupid idea if there are a lot of users. The certificates that isakmpd reads from the CA- and Certificate directories, and the certificates received from the peer is converted into pseudo credentials. Such certificates converted into pseudo credentials essentially would look something like:

     

    authorizer: "x509-base64:        MIIBsTCCARoCAQAwDQYJKoZIhvcNAQEEBQAwITELMAkGA1UEBhMCc2UxEjAQBgI2	CzA  This is would be the public key/certificate of the     AQEB        BQA signer of the user certificate (i.e. the CA certificate)IUuz        eOW8P5UGJUH2JVkiA2CTDryFf0CHYwd2P003dtVYw5RvET7XLMpRZiCcWtBdxneW        ct+016zUBP/cQMMl+KownxAUq9ezA8GvTyUWC97SOMOgoVj/QR3FHmEjpUi3AgMB        AAEwDQYJKoZIhvcNAQEEBQADgYEALGShaAxHvGncev0iFnKrJI4x5T4vlaMP1ad+        iWLV5q9H3wickVGN0NPerq0YLwx/VA9WaecYN8V+ALtNKYPuDiT11zwvE8GQeaai        NuzgmQ9hh3GifEgN9VEiC3j4kTytonKr0Q+vTLM7xYzheOxvrtUErRwZ9Xs1KzHe        yiXHSU8="
    licensees:  "x509-base64:        MIIBsTCCARoCAQAwDQYJKoZIhvcNAQEEBQAwITELMAkGA1UEBhMCc2UxEjAQBgNV        BAMTCUlLRUxBQiBDQTAeFw0wMDAxMjgxNzQyMTZaFw0wMTAxMjcxNzQyMTZaMCEx        CzA      This is would be the key of the subject of the     AQEB        BQA                        certificate                      IUuz        eOW8P5UGJUH2JVkiA2CTDryFf0CHYwd2P003dtVYw5RvET7XLMpRZiCcWtBdxneW        ct+016zUBP/cQMMl+KownxAUq9ezA8GvTyUWC97SOMOgoVj/QR3FHmEjpUi3AgMB        AAEwDQYJKoZIhvcNAQEEBQADgYEALGShaAxHvGncev0iFnKrJI4x5T4vlaMP1ad+        iWLV5q9H3wickVGN0NPerq0YLwx/VA9WaecYN8V+ALtNKYPuDiT11zwvE8GQeaai        NuzgmQ9hh3GifEgN9VEiC3j4kTytonKr0Q+vTLM7xYzheOxvrtUErRwZ9Xs1KzHe        yiXHSU8="
    conditions: app_domain == "IPsec policy" -> "true";
    

    Now note that these are not authorized by "POLICY" and thus won't have any effect without a policy authorizing them somehow. Further, this showed what happens to certificates internally. The above credential is thus not seen in the policy file. However, it is possible to sublicense to such credentials. Remember sublicensing above. It is thus possible to license all certificates that are signed by a certain CA by putting the CA certificate as a licensee to "POLICY":

     

    keynote-version: 2
    comment: This is an example of a policy delegating to a key.
    authorizer: "POLICY"
    licensees: "x509-base64:        MIIBsTCCARoCAQAwDQYJKoZIhvcNAQEEBQAwITELMAkGA1UEBhMCc2UxEjAQBgNV        BAMTCUlLRUxBQiBDQTAeFw0wMDAxMjgxNzQyMTZaFw0wMTAxMjcxNzQyMTZaMCEx        CzA               This would be the CA certificate          AQEB        BQA                                                         IUuz        eOW8P5UGJUH2JVkiA2CTDryFf0CHYwd2P003dtVYw5RvET7XLMpRZiCcWtBdxneW        ct+016zUBP/cQMMl+KownxAUq9ezA8GvTyUWC97SOMOgoVj/QR3FHmEjpUi3AgMB        AAEwDQYJKoZIhvcNAQEEBQADgYEALGShaAxHvGncev0iFnKrJI4x5T4vlaMP1ad+        iWLV5q9H3wickVGN0NPerq0YLwx/VA9WaecYN8V+ALtNKYPuDiT11zwvE8GQeaai        NuzgmQ9hh3GifEgN9VEiC3j4kTytonKr0Q+vTLM7xYzheOxvrtUErRwZ9Xs1KzHe        yiXHSU8="
    conditions: app_domain == "IPsec policy" &&
                esp_present == "yes" &&
                esp_enc_alg != "null" -> "true";
    

    Thus the above policy is a simple example of a policy that delegates to a CA. Thus any user that has a certificate that is signed by the CA that has this certificate and otherwise comply to other conditions set by the policy and the configuration file would be authorized.

     

    Almost secure...is not secure!

    Now, to be really safe, this is not enough unfortunately. There are ways to attack a security gateway that is configured in this way. If you really don't want the details, skip a to the next section now. To everyone else, let's try to understand why this is not secure. It's not hard.

    Consider what information one of the isakmpds has access to at this stage. From the configuration file, isakmpd knows which IP-address its peer will send from (in the [Phase 1] section). From the information it gets at the phase 1 negotiation it knows the ID that the peer presents itself with and the certificate it gets from the peer proves that the peer really have this ID. Looks fine so far?

    Well, if the ID information was the IP (the default situation if we do not provide a phase 1 ID section) everything would be fine. The CA would have tied the IP to the cert and the IP in the configuration would be all information we need. It would be possible for an imposter to use the same IP from another computer in some cases (e.g. if both computers were on the same local network and the computer that usually have this IP is down for some reason). It should however not be possible for an imposter to be able to have a certificate and a corresponding private key that (falsely) proves that this IP belongs to the imposter.

    If that ever happened, the imposter would have managed to either steal the private key from the real owner of the IP, or the imposter would have managed to fool the CA into issuing a certificate containing false information somehow. If any of these things happened, then either the private key had not been protected well enough, the CA had failed to check the identity of the imposter well enough (or the ID info for the cert) or the CA private key had not been well enough protected. Since all these are prerequisites for security to work at all, none of these situations can be allowed to ever occur.

    Now, in our example the situation is different. Here we actually have an FQDN in the certificate instead of an IP address. Since we still have an IP address in the [Phase 1] section this will result in a possible security problem. What now would happen during an ISAKMP phase 1 negotiation would be that we could check that the peer was sending from the expected IP (but as explained earlier that could possibly be forged in some situations). We could check that the ID our peer presents actually belongs to our peer. But what we can not check now is if that ID really is the ID we expect our peer to have, because isakmpd have never been told what ID that should be.

    Someone now might say that the DNS system ties the IP to the FQDN for the host. That is true, however today's DNS system is not secure and can, under some circumstances, be fooled to give out false information (or, it could be subject to a denial of service (DoS) attack by an attacker, and the attacker's computer might be able to fake the DNS server's answer). Secure DNS will come in the future, but it is not here yet (at least most DNS servers are not secure yet), thus today, using DNS to check if the FQDN in the cert corresponds to the expected IP is no guarantee. In fact isakmpd does not check this with DNS. Even if DNS was secure, checking this would not help in the case of using an UFQDN.

    Thus in the case of having an FQDN as ID, it could be possible for an attacker to get an own private key and having this key signed by the same CA that we use (but with the attacker's own FQDN, of course). Then launch a DoS attack on our peer so that it goes down (in fact, there are some flaws in the ISAKMP protocol itself that possibly could be used to launch a remote DoS against the peer an make it go down, although I don't know how sensitive isakmpd is to those attacks). Then the attacker could configure its own computer in the same way as our peer, connect it to our peers network and try to connect using its own ID, private key and certificate.

    Since our own isakmpd has not been informed about what ID to our peer (and it is because the attacker is identically configured as our peer besides the certificate, ID and private key). Further our isakmpd can check that the certificate was signed by the same CA (but most CAs sign lots of certs, a cert might not be hard to get), and that the presented ID is the same as the ID in the cert. However it would not, with the configuration presented so far, check that this ID is the expected ID. Thus the attacker would be allowed to connect.

     

    Preventing the attack.

    The question now thus is, how can we inform isakmpd about what ID to expect? This is fortunately easy, and documented in the isakmpd.policy(5). We must do the check in the policy. Like this:

     

    keynote-version: 2
    comment: This is an example of a policy delegating to a key.
    authorizer: "POLICY"
    licensees: "x509-base64:        MIIBsTCCARoCAQAwDQYJKoZIhvcNAQEEBQAwITELMAkGA1UEBhMCc2UxEjAQBgNV        BAMTCUlLRUxBQiBDQTAeFw0wMDAxMjgxNzQyMTZaFw0wMTAxMjcxNzQyMTZaMCEx        CzA               This would be the CA certificate          AQEB        BQA                                                         IUuz        eOW8P5UGJUH2JVkiA2CTDryFf0CHYwd2P003dtVYw5RvET7XLMpRZiCcWtBdxneW        ct+016zUBP/cQMMl+KownxAUq9ezA8GvTyUWC97SOMOgoVj/QR3FHmEjpUi3AgMB        AAEwDQYJKoZIhvcNAQEEBQADgYEALGShaAxHvGncev0iFnKrJI4x5T4vlaMP1ad+        iWLV5q9H3wickVGN0NPerq0YLwx/VA9WaecYN8V+ALtNKYPuDiT11zwvE8GQeaai        NuzgmQ9hh3GifEgN9VEiC3j4kTytonKr0Q+vTLM7xYzheOxvrtUErRwZ9Xs1KzHe        yiXHSU8="
    conditions: app_domain == "IPsec policy" &&
                esp_present == "yes" &&
                esp_enc_alg != "null" &&
                remote_id == "gw.worksite.se" -> "true";
    

    Now only gw.worksite.se should be able to get an IPsec connection. More allowed IDs could easily be added by adding more alternative remote_id checks, e.g. by having conditions like these in the policy:

     

    conditions: app_domain == "IPsec policy" &&
                esp_present == "yes" &&
                esp_enc_alg != "null" &&
                (remote_id == "gw.worksite.se"  ||
                   remote_id == "gw.whatsite.se") -> "true";
    

    With this policy either of gw.worksite.se, gw.somesite.se or gw.whatsite.se could connect.

    Some might say that is unfortunate that there has to be entire certificates inserted in the policy. It requires some work to reformat the certificates into the format in the policy and it makes the policy rather unreadable. If someone by mistake replaced a user certificate with the corresponding CA certificate somewhere in a complex policy it might cause unauthorized users to be allowed to connect in some cases and worse, it would not be easily detectable by reading through the policy file (since X.509 certificates are not in a human readable format).

    Now, for the really bleeding edge people out there a solution to this problem is available. It is now possible to use the certificate Distinguished Name (DN) instead of a certificate in the policy (the corresponding certificate must of course be available from the certs or ca directories on disk so that isakmpd can find it). With this format the policy above might look like something like this instead:

     

      
    keynote-version: 2
    comment: This is an example of a policy delegating to a key.
    authorizer: "POLICY"
    licensees: "DN:/C=se/CN=IKELAB CA"
    conditions: app_domain == "IPsec policy" &&
                esp_present == "yes" &&
                esp_enc_alg != "null" &&
                (remote_id == "gw.worksite.se"  ||
                 remote_id == "gw.somesite.se"  ||
                 remote_id == "gw.whatsite.se") -> "true";
    

    Much more readable, isn't it? The information about what the exact DN for a certificate is can be found by looking at the certificate using the openssl utility. Something like:

     

    $ openssl x509 -text < ca.crt

    More complicated policy configurations are of course possible but this is a start anyway, and there are another example in the next section.

    This should provide the necessary information about the certificate in ca.crt. Now this is good as long as we have a small or at least reasonably small policy. It is however still not too great if we have a gigantic site with lots of users that should be allowed to connect.

    Multiuser configurations and/or centrally managed authorization.

    Now, lets look at some really cool features of isakmpd. Previously we assumed that the expected peer was well known and had a static IP address. This is not always the case. Lots of people use dynamically assigned IPs or use many different computers. In other cases (like for a server) we might not know for sure who wants to connect.

    Therefor one very nice feature of isakmpd is the ability to use a default tag instead of an IP in the [Phase 1] section, thus allowing isakmpd negotiations from any IP. This might thus look something like this:

     

    [phase 1]
    Default=        work-gw
    

    First, it should be said that this configuration might not be secure from DoS attacks. As said before, there are some flaws in the ISAKMP/IKE protocols. Anyway, using a default [phase 1] section also enable us to use a kind of "authorization certificates" instead.

    Consider the case where we have a lot of authorized users but when we would not accept just any user. Like at a company. We would like company employees to be allowed to connect but nobody else. Now, imagine a big company where there might be thousands of employees. We might like them to all be able to connect from any computer (not only from within the company network) but everyone should not be allowed to do anything. It should now be possible to write a policy like this:

     

    keynote-version: 2
    authorizer: "POLICY"
    licensees: "telnet@work" || "telnet@lab" || "pop3@work" 
    conditions: app_domain == "IPsec policy" &&
                esp_present == "yes" &&
                esp_enc_alg != "null" &&
                remote_id_type == "UFQDN" &&
                (remote_id == "telnet@worksite.se"  ||
                 remote_id == "pop3@worksite.se"  ||
                 remote_id == "telnet@lab.worksite.se") -> "true";
    
    authorizer: "telnet@work"
    licensees: "DN:/C=se/CN=IKELAB CA"
    conditions: remote_id == "telnet@worksite.se" &&
                local_filter_type == "IPv4 address" &&
                local_filter_port == "23" &&
                local_filter == "192.168.002.003"
    
    authorizer: "telnet@lab"
    licensees: "DN:/C=se/CN=IKELAB CA"
    conditions: remote_id == "telnet@lab.worksite.se" &&
                local_filter_type == "IPv4 address" &&
                local_filter_port == "23" &&
                local_filter == "192.168.002.002" -> "true";
    
    authorizer: "pop3@work"
    licensees: "DN:/C=se/CN=IKELAB CA"
    conditions: local_filter_type == "IPv4 address" &&
                local_filter_port == "110" &&
                local_filter == "192.168.002.003" &&
                remote_id == "telnet@worksite.se" -> "true";
    
    

    This might not be exactly how it should be. This is as far as I know completely untested (in fact, these filter conditions might not work at all as I expect). Also, a policy such as this one (in fact any with default as peer IP), would require rewrites of the isakmpd.conf file too. This would have some security implications too. Further, for this kind of connections where anyone should be allowed to connect, it would probably be desirable to log the DN of anyone who connected. Isakmpd does not yet support that to my knowledge. Also this probably could have other security implications. You are on your own, you have been warned. The basic idea should be clear anyway.

    Just in case someone missed the really interesting possibilities this would have. If all computers using ISAKMP/IKE this way had a standard set of conditions for all services the users might like to use from remote, the CA could actually authorize users by just putting the right SubjectAltName extensions in their certificates. Further, the expiration time for such certificates could be set to expire relatively often although the users would be able to download new reissued certificates when their current certificate is getting old. If the users misuse their authorizations, just stop reissuing the certificates and they won't get in more after it has expired. No need to change policy files on all computers just because an employee e.g. quits their job. The same scheme should work for other purposes than ISAKMP/IPsec too (including authorization for off-line systems!) although that would require special software. In any case, any organization doing this would probably want to be their own CA.

    Multiuser configurations (mobile users) like these are possible with pre-shared keys too, but then it is required that AGGRESSIVE mode is used instead of ID_PROT mode since we then must be able to choose the right password phrase based on ID since we do not know that from what the IP is in this case (in AGGRESSIVE mode the ID is sent over at an earlier stage of the negotiation, but it is sent unencrypted, thus AGGRESSIVE mode is faster because it needs fewer message exchanges, but it also is a bit less secure since the ID is sent in clear).

    13.10 - What IKE clients are compatible with isakmpd?

    isakmpd is the ISAKMP/Oakley key management daemon that comes with OpenBSD. We suspect that it interoperates, at least partially, with most ISAKMP implementations, but the following have actually been tested. Note that some isakmp software out there are actually based on the OpenBSD isakmp daemon.

    The following MS-Windows clients have been reported to be compatible:

    The following gateways/routers have been reported to be compatible:

    13.11 - Troubleshooting IPSec/VPN

    Your first tool for troubleshooting IPSec is tcpdump(8). Use tcpdump to look for several things.

    First, if you are using tcpdump from OpenBSD, you have an enhanced version of tcpdump which can show some information about ESP and AH packets. If you are using tcpdump from OpenBSD 2.5 or on another operating system, chances are you have an older version that will simply show the protocol number for AH or ESP. (ESP is IP protocol 50, AH is 51)

     

    With tcpdump, look and see if traffic is using AH/ESP or cleartext. If your traffic is in cleartext, then your flows are setup incorrectly or your isakmp is not negotiating properly. Use ping(8) to generate simple traffic.

     

    • For instance, I have two hosts, 208.1.1.1 and 208.2.2.2. Logged in to 208.2.2.2, I am doing this:
    vpn# ping -c 3 208.1.1.1
    PING esp.mil (208.1.1.1): 56 data bytes
    64 bytes from 208.1.1.1: icmp_seq=0 ttl=255 time=190.155 ms
    64 bytes from 208.1.1.1: icmp_seq=1 ttl=255 time=201.040 ms
    64 bytes from 208.1.1.1: icmp_seq=2 ttl=255 time=165.481 ms
    --- esp.mil ping statistics ---
    3 packets transmitted, 3 packets received, 0% packet loss
    round-trip min/avg/max = 165.481/185.558/201.040 ms
    
    And in another session, I can see my encapsulated pings:
    vpn# tcpdump -ni fxp7 host 208.1.1.1
    tcpdump: listening on fxp7
    14:12:19.630274 esp 208.2.2.2 > 208.1.1.1 spi 0x00001000 seq 4535 len 116
    14:12:19.813519 esp 208.1.1.1 > 208.2.2.2 spi 0x00001001 seq 49313 len 116
    14:12:20.630277 esp 208.2.2.2 > 208.1.1.1 spi 0x00001000 seq 4536 len 116
    14:12:20.832458 esp 208.1.1.1 > 208.2.2.2 spi 0x00001001 seq 49314 len 116
    14:12:21.630273 esp 208.2.2.2 > 208.1.1.1 spi 0x00001000 seq 4537 len 116
    ^C
    1831 packets received by filter
    0 packets dropped by kernel
    

     

    ISAKMP runs on UDP port 500. If this is locked out through a firewall or packet filter, then you need to change it!
    # Passing in ISAKMP traffic from the security gateways
    pass in on ne0 proto udp from gatewB/32 port = 500 to gatewA/32 port = 500
    pass out on ne0 proto udp from gatewA/32 port = 500 to gatewB/32 port = 500
    
    # Passing in encrypted traffic from security gateways
    pass in proto esp from gatewB/32 to gatewA/32
    pass out proto esp from gatewA/32 to gatewB/32
    

     

    Photuris runs on UDP port 468. Same considerations, but the protocol is ah.
    # Passing in Photuris traffic from the security gateways
    pass in on ne0 proto udp from gatewB/32 port = 468 to gatewA/32 port = 468
    pass out on ne0 proto udp from gatewA/32 port = 468 to gatewB/32 port = 468
    
    # Passing in encrypted traffic from security gateways
    pass in proto ah from gatewB/32 to gatewA/32
    pass out proto ah from gatewA/32 to gatewB/32
    

     

    To turn on all debugging in isakmpd, start it as

     

    # /sbin/isakmpd -d -DA=99

    or (to skip the most detailed timer debug info)

     

    # /sbin/isakmpd -d -DA=99 -D1=70

     

    You need to allow traffic which has been processed by IPSec from netB into your local firewalled netA.
    # Passing in traffic from the designated subnets.
    pass in on enc0 from netB/netBmask to netA/netAmask
    

     

    With tcpdump on OpenBSD, you can decode most cleartext parts of Internet Key Exchange sessions. Tcpdump will also show AH payload data.

     

    Mount a /kern filesystem (if you don't use one by default already.)

     

    # mkdir /kern; mount -t kernfs /kern /kern

    In /kern, there is a table of current SA/SPIs, including which have flows (outgoing SAs) or not (incoming SAs). There are also traffic counters which you can use to see what traffic is going where.

     

    Finally, you can use netstat(1) to see your SAs.
    vpn% netstat -rn -f encap
    Routing tables
    
    Encap:
    Source             Port  Destination        Port  Proto SA(Address/SPI/Proto) 
    0.0.0.0/32         0     192.168.99/24      0     0     208.1.1.1/00001000/50
    0.0.0.0/32         0     208.1.1.1/32       0     0     208.1.1.1/00001000/50
    208.1.2.0/24       0     192.168.99/24      0     0     208.1.1.1/00001000/50
    208.1.2.0/24       0     208.1.1.1/32       0     0     208.1.1.1/00001000/50
    208.1.5.0/24       0     192.168.99/24      0     0     208.1.1.1/00001000/50
    208.1.5.0/24       0     208.1.1.1/32       0     0     208.1.1.1/00001000/50
    208.2.2.2/32       0     192.168.99/24      0     0     208.1.1.1/00001000/50
    208.2.2.2/32       0     208.1.1.1/32       0     0     208.1.1.1/00001000/50
    

     

    If all else fails, recompile your kernel with option ENCDEBUG. Then, set the sysctl net.inet.ip.encdebug to 1. Look in your dmesg for warnings or errors, and report them using sendbug to the OpenBSD developers.
    展开全文
  • OGRE 所有版本 (SDK 及 源码) 下载地址http://zh.sourceforge.jp/projects/sfnet_ogre/releases/Latest 5 files Ogre_iOS_4.3_Dependencies_20110411.dmg application/octet-stream; charset=binary 45.7 MB 2011-04...
  • C++ IO流

    2017-11-24 15:49:20
    IO流 1.流类库结构 ...程序的输入指的是从输入文件将数据传送给程序,程序的输出指的是从程序将数据传送给输出文件。...以外存磁盘文件为对象进行输入和输出,即从磁盘文件输入数据,数据输出到磁盘文件。...
  • 23IO流

    2017-06-20 12:09:09
    IO流IO流 流类库结构 标准IO 1标准输入 2标准输出 文件IO 1文件流及其对象 2文件的基本操作 3对ASCII文件的操作 4对二进制文件的操作 1.流类库结构程序的输入指的是从输入文件将数据传送给程序,程序的输出指的是从...
  • 3兼容性测试

    2019-09-26 23:22:57
    定义:软件兼容性测试是指检查软件之间是否正确地交互和共享信息。 移动兼容性测试:App 在不同的硬件设备(厂商)、系统版本、ROM、分辨率上的表现,在不同情况下不会出现 Crash、ANR、UI 显示问题。...
  • 苹果客服电话

    2015-07-11 14:30:45
    https://devforums.apple.com/thread/239351 https://devforums.apple.com/message/1063293#1063293    NSLog(@"设备ID:%@",[[UIDevice currentDevice] uniqueIdentifier]);...中国区苹果开发者客服电
  • 原文地址:http://web.jobbole.com/91578/ 在Web应用中,实现动画效果的方法比较多,Javascript 中可以通过定时器 setTimeout 来实现,css3 可以使用 transition 和 animation 来实现,html5 中的 canvas 也可以实现...
  • 在Web应用中,实现动画效果的方法比较多,Javascript 中可以通过定时器 setTimeout 来实现,css3 可以使用 transition 和 animation 来实现,html5 中的 canvas 也可以实现。... 为了深入理解 requestAni...
  • 前言 在Web应用中,实现动画效果的方法比较多,Javascript 中可以通过定时器 setTimeout 来实现,css3 可以使用 transition 和 animation 来实现,html5 中的 canvas 也可以实现。... 为了深入理解 request...
  • requestAnimationFrame 知多少? 在Web应用中,实现动画效果的方法比较多,JavaScript 中可以通过定时器setTimeout来实现,css3 可以使用 transition 和 animation 来实现,html5 中的 canvas 也可以实现。...
  • 为什么要梯度下降,因为在机器学习与视觉SLAM中,有关目标函数的最优值求解过程,都会涉及到目标函数求解,这个过程需要梯度下降。今天我们从最简单,最古老,最经典的最小二乘开始。本文以线性最小二乘为例子,至于...
  • requestAnimationFrame

    2019-08-01 15:23:13
    目录 前言 1. 屏幕绘制频率 2. CSS 动画原理 3. setTimeout 3.1 卡顿、抖动的现象的产生有两个原因: 3.2 为什么步调不一致就会引起丢帧呢 4. requestAnimationFrame ...
1 2
收藏数 32
精华内容 12
热门标签
关键字:

13.3 crt证书 ios