├── .gitignore ├── Helper ├── .gitignore ├── CMakeLists.txt ├── build.gradle ├── libs │ ├── guava-23.0-android.jar │ └── jsr305-3.0.2.jar ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── cpp │ ├── connections.cpp │ ├── connections.h │ ├── hints.cpp │ ├── hints.h │ ├── kernel_info.cpp │ ├── kernel_info.h │ ├── pipe.cpp │ ├── pipe.h │ ├── proxy.cpp │ ├── proxy.h │ ├── proxy_setting.cpp │ ├── proxy_setting.h │ ├── subflow.cpp │ ├── subflow.h │ ├── tools.cpp │ └── tools.h │ ├── ic_launcher-web.png │ ├── java │ ├── edu │ │ └── robustnet │ │ │ └── xiao │ │ │ └── mpbondhel │ │ │ ├── Helper.java │ │ │ ├── MainActivity.java │ │ │ ├── http │ │ │ ├── ConnectivityNetworkCallback.java │ │ │ ├── CustomInputStream.java │ │ │ ├── HttpHelper.java │ │ │ └── HttpListener.java │ │ │ └── util │ │ │ ├── BluetoothListener.java │ │ │ ├── Constants.java │ │ │ ├── LocalConn.java │ │ │ ├── NetEnabler.java │ │ │ ├── Pipe.java │ │ │ ├── Subflow.java │ │ │ └── WiFiListener.java │ └── myokhttp │ │ ├── Address.java │ │ ├── Authenticator.java │ │ ├── Cache.java │ │ ├── CacheControl.java │ │ ├── Call.java │ │ ├── Callback.java │ │ ├── CertificatePinner.java │ │ ├── Challenge.java │ │ ├── CipherSuite.java │ │ ├── Connection.java │ │ ├── ConnectionPool.java │ │ ├── ConnectionSpec.java │ │ ├── Cookie.java │ │ ├── CookieJar.java │ │ ├── Credentials.java │ │ ├── Dispatcher.java │ │ ├── Dns.java │ │ ├── EventListener.java │ │ ├── FormBody.java │ │ ├── Handshake.java │ │ ├── Headers.java │ │ ├── HttpUrl.java │ │ ├── Interceptor.java │ │ ├── MediaType.java │ │ ├── MultipartBody.java │ │ ├── OkHttpClient.java │ │ ├── Protocol.java │ │ ├── RealCall.java │ │ ├── Request.java │ │ ├── RequestBody.java │ │ ├── Response.java │ │ ├── ResponseBody.java │ │ ├── Route.java │ │ ├── TlsVersion.java │ │ ├── WebSocket.java │ │ ├── WebSocketListener.java │ │ ├── internal │ │ ├── Internal.java │ │ ├── NamedRunnable.java │ │ ├── Util.java │ │ ├── Version.java │ │ ├── cache │ │ │ ├── CacheInterceptor.java │ │ │ ├── CacheRequest.java │ │ │ ├── CacheStrategy.java │ │ │ ├── DiskLruCache.java │ │ │ ├── FaultHidingSink.java │ │ │ └── InternalCache.java │ │ ├── cache2 │ │ │ ├── FileOperator.java │ │ │ └── Relay.java │ │ ├── connection │ │ │ ├── ConnectInterceptor.java │ │ │ ├── ConnectionSpecSelector.java │ │ │ ├── RealConnection.java │ │ │ ├── RouteDatabase.java │ │ │ ├── RouteException.java │ │ │ ├── RouteSelector.java │ │ │ └── StreamAllocation.java │ │ ├── http │ │ │ ├── BridgeInterceptor.java │ │ │ ├── CallServerInterceptor.java │ │ │ ├── HttpCodec.java │ │ │ ├── HttpDate.java │ │ │ ├── HttpHeaders.java │ │ │ ├── HttpMethod.java │ │ │ ├── RealInterceptorChain.java │ │ │ ├── RealResponseBody.java │ │ │ ├── RequestLine.java │ │ │ ├── RetryAndFollowUpInterceptor.java │ │ │ ├── StatusLine.java │ │ │ └── UnrepeatableRequestBody.java │ │ ├── http1 │ │ │ └── Http1Codec.java │ │ ├── http2 │ │ │ ├── ConnectionShutdownException.java │ │ │ ├── ErrorCode.java │ │ │ ├── Header.java │ │ │ ├── Hpack.java │ │ │ ├── Http2.java │ │ │ ├── Http2Codec.java │ │ │ ├── Http2Connection.java │ │ │ ├── Http2Reader.java │ │ │ ├── Http2Stream.java │ │ │ ├── Http2Writer.java │ │ │ ├── Huffman.java │ │ │ ├── Ping.java │ │ │ ├── PushObserver.java │ │ │ ├── Settings.java │ │ │ └── StreamResetException.java │ │ ├── io │ │ │ └── FileSystem.java │ │ ├── platform │ │ │ ├── AndroidPlatform.java │ │ │ ├── Jdk9Platform.java │ │ │ ├── JdkWithJettyBootPlatform.java │ │ │ ├── OptionalMethod.java │ │ │ └── Platform.java │ │ ├── publicsuffix │ │ │ └── PublicSuffixDatabase.java │ │ ├── tls │ │ │ ├── BasicCertificateChainCleaner.java │ │ │ ├── BasicTrustRootIndex.java │ │ │ ├── CertificateChainCleaner.java │ │ │ ├── DistinguishedNameParser.java │ │ │ ├── OkHostnameVerifier.java │ │ │ └── TrustRootIndex.java │ │ └── ws │ │ │ ├── RealWebSocket.java │ │ │ ├── WebSocketProtocol.java │ │ │ ├── WebSocketReader.java │ │ │ └── WebSocketWriter.java │ │ └── package-info.java │ └── res │ ├── drawable │ └── ic_launcher_background.xml │ ├── layout │ └── activity_main.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── values │ ├── ic_launcher_background.xml │ └── strings.xml │ └── xml │ └── network_security_config.xml ├── Primary ├── .gitignore ├── CMakeLists.txt ├── build.gradle ├── libs │ ├── guava-23.0-android.jar │ └── jsr305-3.0.2.jar ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── edu │ │ └── robustnet │ │ └── xiao │ │ └── mpbondpri │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── cpp │ │ ├── connections.cpp │ │ ├── connections.h │ │ ├── hints.cpp │ │ ├── hints.h │ │ ├── kernel_info.cpp │ │ ├── kernel_info.h │ │ ├── monitor.c │ │ ├── pipe.cpp │ │ ├── pipe.h │ │ ├── proxy.cpp │ │ ├── proxy.h │ │ ├── proxy_setting.cpp │ │ ├── proxy_setting.h │ │ ├── scheduler.cpp │ │ ├── scheduler.h │ │ ├── subflow.cpp │ │ ├── subflow.h │ │ ├── tools.cpp │ │ └── tools.h │ ├── ic_launcher-web.png │ ├── java │ │ ├── edu │ │ │ └── robustnet │ │ │ │ └── xiao │ │ │ │ └── mpbondpri │ │ │ │ ├── MainActivity.java │ │ │ │ ├── Primary.java │ │ │ │ ├── http │ │ │ │ ├── ConnectivityNetworkCallback.java │ │ │ │ ├── CustomInputStream.java │ │ │ │ ├── HttpListener.java │ │ │ │ └── HttpPrimary.java │ │ │ │ └── util │ │ │ │ ├── BluetoothConnector.java │ │ │ │ ├── Constants.java │ │ │ │ ├── LocalConn.java │ │ │ │ ├── NetEnabler.java │ │ │ │ ├── Pipe.java │ │ │ │ ├── PipeMsg.java │ │ │ │ ├── Subflow.java │ │ │ │ └── WiFiConnector.java │ │ └── myokhttp │ │ │ ├── Address.java │ │ │ ├── Authenticator.java │ │ │ ├── Cache.java │ │ │ ├── CacheControl.java │ │ │ ├── Call.java │ │ │ ├── Callback.java │ │ │ ├── CertificatePinner.java │ │ │ ├── Challenge.java │ │ │ ├── CipherSuite.java │ │ │ ├── Connection.java │ │ │ ├── ConnectionPool.java │ │ │ ├── ConnectionSpec.java │ │ │ ├── Cookie.java │ │ │ ├── CookieJar.java │ │ │ ├── Credentials.java │ │ │ ├── Dispatcher.java │ │ │ ├── Dns.java │ │ │ ├── EventListener.java │ │ │ ├── FormBody.java │ │ │ ├── Handshake.java │ │ │ ├── Headers.java │ │ │ ├── HttpUrl.java │ │ │ ├── Interceptor.java │ │ │ ├── MediaType.java │ │ │ ├── MultipartBody.java │ │ │ ├── OkHttpClient.java │ │ │ ├── Protocol.java │ │ │ ├── RealCall.java │ │ │ ├── Request.java │ │ │ ├── RequestBody.java │ │ │ ├── Response.java │ │ │ ├── ResponseBody.java │ │ │ ├── Route.java │ │ │ ├── TlsVersion.java │ │ │ ├── WebSocket.java │ │ │ ├── WebSocketListener.java │ │ │ ├── internal │ │ │ ├── Internal.java │ │ │ ├── NamedRunnable.java │ │ │ ├── Util.java │ │ │ ├── Version.java │ │ │ ├── cache │ │ │ │ ├── CacheInterceptor.java │ │ │ │ ├── CacheRequest.java │ │ │ │ ├── CacheStrategy.java │ │ │ │ ├── DiskLruCache.java │ │ │ │ ├── FaultHidingSink.java │ │ │ │ └── InternalCache.java │ │ │ ├── cache2 │ │ │ │ ├── FileOperator.java │ │ │ │ └── Relay.java │ │ │ ├── connection │ │ │ │ ├── ConnectInterceptor.java │ │ │ │ ├── ConnectionSpecSelector.java │ │ │ │ ├── RealConnection.java │ │ │ │ ├── RouteDatabase.java │ │ │ │ ├── RouteException.java │ │ │ │ ├── RouteSelector.java │ │ │ │ └── StreamAllocation.java │ │ │ ├── http │ │ │ │ ├── BridgeInterceptor.java │ │ │ │ ├── CallServerInterceptor.java │ │ │ │ ├── HttpCodec.java │ │ │ │ ├── HttpDate.java │ │ │ │ ├── HttpHeaders.java │ │ │ │ ├── HttpMethod.java │ │ │ │ ├── RealInterceptorChain.java │ │ │ │ ├── RealResponseBody.java │ │ │ │ ├── RequestLine.java │ │ │ │ ├── RetryAndFollowUpInterceptor.java │ │ │ │ ├── StatusLine.java │ │ │ │ └── UnrepeatableRequestBody.java │ │ │ ├── http1 │ │ │ │ └── Http1Codec.java │ │ │ ├── http2 │ │ │ │ ├── ConnectionShutdownException.java │ │ │ │ ├── ErrorCode.java │ │ │ │ ├── Header.java │ │ │ │ ├── Hpack.java │ │ │ │ ├── Http2.java │ │ │ │ ├── Http2Codec.java │ │ │ │ ├── Http2Connection.java │ │ │ │ ├── Http2Reader.java │ │ │ │ ├── Http2Stream.java │ │ │ │ ├── Http2Writer.java │ │ │ │ ├── Huffman.java │ │ │ │ ├── Ping.java │ │ │ │ ├── PushObserver.java │ │ │ │ ├── Settings.java │ │ │ │ └── StreamResetException.java │ │ │ ├── io │ │ │ │ └── FileSystem.java │ │ │ ├── platform │ │ │ │ ├── AndroidPlatform.java │ │ │ │ ├── Jdk9Platform.java │ │ │ │ ├── JdkWithJettyBootPlatform.java │ │ │ │ ├── OptionalMethod.java │ │ │ │ └── Platform.java │ │ │ ├── publicsuffix │ │ │ │ └── PublicSuffixDatabase.java │ │ │ ├── tls │ │ │ │ ├── BasicCertificateChainCleaner.java │ │ │ │ ├── BasicTrustRootIndex.java │ │ │ │ ├── CertificateChainCleaner.java │ │ │ │ ├── DistinguishedNameParser.java │ │ │ │ ├── OkHostnameVerifier.java │ │ │ │ └── TrustRootIndex.java │ │ │ └── ws │ │ │ │ ├── RealWebSocket.java │ │ │ │ ├── WebSocketProtocol.java │ │ │ │ ├── WebSocketReader.java │ │ │ │ └── WebSocketWriter.java │ │ │ └── package-info.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── values │ │ ├── colors.xml │ │ ├── ic_launcher_background.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ └── network_security_config.xml │ └── test │ └── java │ └── edu │ └── robustnet │ └── xiao │ └── mpbondpri │ └── ExampleUnitTest.java ├── README.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── server ├── Makefile ├── Storage.cpp ├── Storage.h ├── connections.cpp ├── connections.h ├── hints.cpp ├── hints.h ├── kernel_info.cpp ├── kernel_info.h ├── meta_buffer.cpp ├── meta_buffer.h ├── proxy.cpp ├── proxy.h ├── proxy_setting.cpp ├── proxy_setting.h ├── scheduler.cpp ├── scheduler.h ├── scripts │ ├── run_rp_minrtt.sh │ └── run_rp_pams.sh ├── ss.c ├── ss.mod.c ├── stdafx.cpp ├── stdafx.h ├── subflows.cpp ├── subflows.h ├── tools.cpp └── tools.h └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ 2 | /server/*.o 3 | /server/*.ko 4 | /server/Module.symvers 5 | /server/*.cmd 6 | /server/modules.order 7 | /server/dmm_proxy 8 | /server/.tmp_versions 9 | /server/log/ 10 | /server/*.txt 11 | /server/*.out 12 | /server/*.dat 13 | 14 | # Android Studio 15 | *.iml 16 | .idea/ 17 | .gradle/ 18 | local.properties 19 | build/ 20 | .externalNativeBuild 21 | /*/build 22 | /*/*.iml 23 | -------------------------------------------------------------------------------- /Helper/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Helper/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Sets the minimum version of CMake required to build your native library. 2 | # This ensures that a certain set of CMake features is available to 3 | # your build. 4 | 5 | cmake_minimum_required(VERSION 3.4.1) 6 | 7 | # Specifies a library name, specifies whether the library is STATIC or 8 | # SHARED, and provides relative paths to the source code. You can 9 | # define multiple libraries by adding multiple add_library() commands, 10 | # and CMake builds them for you. When you build your app, Gradle 11 | # automatically packages shared libraries with your APK. 12 | 13 | include_directories(src/main/cpp/) 14 | 15 | 16 | add_library(proxy SHARED src/main/cpp/proxy.cpp) 17 | add_library(proxy_setting STATIC src/main/cpp/proxy_setting.cpp) 18 | add_library(tools STATIC src/main/cpp/tools.cpp) 19 | add_library(kernel_info STATIC src/main/cpp/kernel_info.cpp) 20 | add_library(hints STATIC src/main/cpp/hints.cpp) 21 | add_library(subflow STATIC src/main/cpp/subflow.cpp) 22 | add_library(connections STATIC src/main/cpp/connections.cpp) 23 | add_library(pipe STATIC src/main/cpp/pipe.cpp) 24 | 25 | target_link_libraries(subflow android log connections hints kernel_info) 26 | target_link_libraries(proxy connections subflow tools proxy_setting pipe) 27 | target_link_libraries(connections android log tools subflow kernel_info) 28 | -------------------------------------------------------------------------------- /Helper/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 29 5 | buildToolsVersion "29.0.1" 6 | defaultConfig { 7 | applicationId "edu.robustnet.xiao.mpbondhel" 8 | minSdkVersion 23 9 | targetSdkVersion 29 10 | versionCode 1 11 | versionName "1.0" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | externalNativeBuild { 20 | cmake { 21 | path 'CMakeLists.txt' 22 | } 23 | } 24 | } 25 | 26 | dependencies { 27 | implementation fileTree(dir: 'libs', include: ['*.jar']) 28 | implementation 'com.google.android.support:wearable:2.3.0' 29 | compileOnly 'com.google.android.wearable:wearable:2.3.0' 30 | implementation 'com.google.android.gms:play-services-wearable:15.0.1' 31 | implementation 'com.android.support:percent:27.1.1' 32 | implementation 'com.android.support:appcompat-v7:27.1.1' 33 | implementation 'com.android.support:recyclerview-v7:27.1.1' 34 | implementation 'com.google.android.gms:play-services-wearable:+' 35 | implementation 'androidx.appcompat:appcompat:1.0.2' 36 | implementation 'com.squareup.okio:okio:1.13.0' 37 | implementation 'androidx.annotation:annotation:1.1.0' 38 | implementation 'javax.annotation:javax.annotation-api:1.2-b01' 39 | implementation files('libs/guava-23.0-android.jar') 40 | implementation files('libs/jsr305-3.0.2.jar') 41 | } 42 | -------------------------------------------------------------------------------- /Helper/libs/guava-23.0-android.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Helper/libs/guava-23.0-android.jar -------------------------------------------------------------------------------- /Helper/libs/jsr305-3.0.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Helper/libs/jsr305-3.0.2.jar -------------------------------------------------------------------------------- /Helper/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /Helper/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 27 | 28 | 29 | android:windowSoftInputMode="stateHidden" 30 | 31 | 32 | 33 | 34 | 35 | 38 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Helper/src/main/cpp/hints.cpp: -------------------------------------------------------------------------------- 1 | #include "hints.h" 2 | #include "tools.h" 3 | 4 | int HINT_ENTRY::matchEntry(DWORD serverIP, WORD serverPort) { 5 | if (this->serverIP >> (32-ipPrefix) == serverIP >> (32-ipPrefix) 6 | && this->serverPort == serverPort) 7 | return 1; 8 | return 0; 9 | } 10 | 11 | DWORD HINT_ENTRY::getHints() { 12 | DWORD value = 0; 13 | value += ((DWORD) sched << 24); 14 | value += ((DWORD) timeType << 22); 15 | value += ((DWORD) timeValue << 16); 16 | value += ((DWORD) energyType << 14); 17 | value += ((DWORD) energyValue << 8); 18 | value += ((DWORD) dataType << 6); 19 | value += ((DWORD) dataValue); 20 | return value; 21 | } 22 | 23 | DWORD HINTS::getHints(DWORD serverIP, WORD serverPort) { 24 | DWORD value = 0xFFFFFFFF; 25 | LOGD("Get Hints for: %u %u", serverIP, serverPort); 26 | for (int i = 0; i <= maxHint; i++) { 27 | if (entries[i].matchEntry(serverIP, serverPort)) { 28 | value = entries[i].getHints(); 29 | break; 30 | } 31 | } 32 | return value; 33 | } 34 | 35 | void HINTS::print() { 36 | for (int i = 0; i <= maxHint; i++) { 37 | LOGD("Rule %d: serverIP=%u ipPrefix=%d serverPort=%u " 38 | "sched=%d time=%d/%d energy=%d/%d data=%d/%d", 39 | i, entries[i].serverIP, entries[i].ipPrefix, entries[i].serverPort, 40 | entries[i].sched, entries[i].timeType, entries[i].timeValue, 41 | entries[i].energyType, entries[i].energyValue, 42 | entries[i].dataType, entries[i].dataValue); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Helper/src/main/cpp/hints.h: -------------------------------------------------------------------------------- 1 | #ifndef DMM_HINTS_H 2 | #define DMM_HINTS_H 3 | 4 | #include "proxy.h" 5 | 6 | #define MAX_HINT 100 7 | 8 | struct HINT_ENTRY { 9 | DWORD serverIP; 10 | int ipPrefix; 11 | WORD serverPort; 12 | 13 | int sched; // 8 bit 14 | int timeType, timeValue; // 2 bit + 6 bit 15 | int energyType, energyValue; // 2 bit + 6 bit 16 | int dataType, dataValue; // 2 bit + 6 bit 17 | 18 | int matchEntry(DWORD serverIP, WORD serverPort); 19 | DWORD getHints(); 20 | }; 21 | 22 | struct HINTS { 23 | int maxHint; 24 | HINT_ENTRY entries[MAX_HINT]; 25 | DWORD getHints(DWORD serverIP, WORD serverPort); 26 | void print(); 27 | }; 28 | 29 | #endif //DMM_HINTS_H -------------------------------------------------------------------------------- /Helper/src/main/cpp/kernel_info.cpp: -------------------------------------------------------------------------------- 1 | #include "kernel_info.h" 2 | #include "connections.h" 3 | #include "tools.h" 4 | 5 | extern struct CONNECTIONS conns; 6 | extern struct KERNEL_INFO kernelInfo; 7 | 8 | void KERNEL_INFO::Setup() { 9 | infoSize = sizeof(pipeinfo[0]); 10 | for (int i = 1; i < MAX_PIPES; i++) { 11 | fd[i] = conns.peers[i].fd; 12 | } 13 | nTCP = PROXY_SETTINGS::nTCPPipes; 14 | 15 | // DMM 16 | for (int i = 1; i < MAX_PIPES; i++) { 17 | pipeBW[i] = 0; 18 | pipeRTT[i] = 0; 19 | bytesInPipe[i] = 0; 20 | bytesOnDevice[i] = 0; 21 | } 22 | } 23 | 24 | void KERNEL_INFO::UpdatePipeInfo(int pipeNo) { 25 | int r = 0; 26 | if (pipeNo > 0 && pipeNo < MAX_PIPES) { 27 | r = getsockopt(fd[pipeNo], IPPROTO_TCP, TCP_INFO, 28 | &pipeinfo[pipeNo], (socklen_t *)&infoSize); 29 | MyAssert(r == 0, 9110); 30 | } else { 31 | for (int i = 1; i <= 2; i++) { 32 | if (fd[i] >= 0) { 33 | r = getsockopt(fd[i], IPPROTO_TCP, TCP_INFO, 34 | &pipeinfo[i], (socklen_t *)&infoSize); 35 | MyAssert(r == 0, 9111); 36 | } 37 | } 38 | } 39 | } 40 | 41 | // currently not available 42 | int KERNEL_INFO::GetTCPAvailableSpace(int pipeNo) { 43 | if (pipeNo >= 1 && pipeNo <= nTCP) 44 | return space[pipeNo]; 45 | return 0; 46 | } 47 | 48 | unsigned int KERNEL_INFO::GetSendCwnd(int pipeNo) { 49 | return pipeinfo[pipeNo].tcpi_snd_cwnd; 50 | } 51 | 52 | unsigned int KERNEL_INFO::GetSndMss(int pipeNo) { 53 | return pipeinfo[pipeNo].tcpi_snd_mss; 54 | } 55 | 56 | // bytes 57 | int KERNEL_INFO::GetInFlightSize(int pipeNo) { 58 | return (pipeinfo[pipeNo].tcpi_unacked - pipeinfo[pipeNo].tcpi_sacked 59 | - pipeinfo[pipeNo].tcpi_lost + pipeinfo[pipeNo].tcpi_retrans) * GetSndMss(pipeNo); 60 | } 61 | 62 | // us 63 | int KERNEL_INFO::GetSRTT(int pipeNo) { 64 | return pipeinfo[pipeNo].tcpi_rtt; 65 | } 66 | 67 | DWORD KERNEL_INFO::GetSndBuffer(int subflowNo) { 68 | int buf_size = 0; 69 | ioctl(fd[subflowNo], TIOCOUTQ, &buf_size); 70 | return buf_size; 71 | } 72 | -------------------------------------------------------------------------------- /Helper/src/main/cpp/kernel_info.h: -------------------------------------------------------------------------------- 1 | #ifndef DMM_KERNEL_INFO_H 2 | #define DMM_KERNEL_INFO_H 3 | 4 | #include "proxy_setting.h" 5 | 6 | struct KERNEL_INFO { 7 | struct tcp_info pipeinfo[MAX_PIPES]; 8 | int space[MAX_PIPES]; 9 | 10 | int fd[MAX_PIPES]; 11 | int infoSize; 12 | int nTCP; 13 | 14 | // DMM 15 | int pipeBW[MAX_PIPES]; // in kbps 16 | int pipeRTT[MAX_PIPES]; 17 | int bytesInPipe[MAX_PIPES]; 18 | int bytesOnDevice[MAX_PIPES]; 19 | 20 | void Setup(); 21 | void UpdatePipeInfo(int pipeNo); 22 | 23 | int GetTCPAvailableSpace(int pipeNo); 24 | unsigned int GetSendCwnd(int pipeNo); 25 | unsigned int GetSndMss(int pipeNo); 26 | int GetInFlightSize(int pipeNo); 27 | int GetSRTT(int pipeNo); 28 | DWORD GetSndBuffer(int subflowNo); 29 | }; 30 | 31 | #endif //DMM_KERNEL_INFO_H 32 | -------------------------------------------------------------------------------- /Helper/src/main/cpp/pipe.h: -------------------------------------------------------------------------------- 1 | #ifndef DMM_PIPE_H 2 | #define DMM_PIPE_H 3 | 4 | #include "proxy_setting.h" 5 | 6 | struct PIPE_MSG { 7 | BYTE * pData; 8 | int len = 0; 9 | 10 | void Set(BYTE * buf, int len); 11 | int Get(); 12 | void Setup(); 13 | }; 14 | 15 | struct PIPE { 16 | 17 | int n; 18 | int localListenFD; 19 | int localListenFDSide; 20 | int feedbackFD; 21 | int fd[MAX_PIPES]; 22 | // distinguish different secondary devices in DMM 23 | int secNo; 24 | int nextSubflow; 25 | 26 | int Setup(const char * localIP, const char * remoteIP, int secNo, int nSubflow); 27 | void Accept(); 28 | void SetCongestionControl(int fd, const char * tcpVar); 29 | void Feedback(); 30 | void SendPipeInformedACK(); 31 | void Write2Pipe(); 32 | 33 | }; 34 | 35 | #endif //DMM_PIPE_H 36 | -------------------------------------------------------------------------------- /Helper/src/main/cpp/proxy.h: -------------------------------------------------------------------------------- 1 | #ifndef DMM_PROXY_H 2 | #define DMM_PROXY_H 3 | 4 | //transport protocol 1=TCP, 2=UDP, 3=SCTP 5 | #define TRANS 1 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include //for SIOCOUTQ 35 | 36 | #include 37 | #include 38 | 39 | #include "proxy_setting.h" 40 | 41 | #define R_SUCC 1 42 | #define R_FAIL 0 43 | 44 | typedef unsigned char BYTE; 45 | typedef unsigned int DWORD; 46 | typedef unsigned short WORD; 47 | 48 | 49 | #define PROXY_MODE_LOCAL 1 50 | #define PROXY_MODE_REMOTE 2 51 | 52 | //using namespace std; 53 | 54 | int ProxyMain(); 55 | 56 | #endif //DMM_PROXY_H 57 | -------------------------------------------------------------------------------- /Helper/src/main/cpp/tools.cpp: -------------------------------------------------------------------------------- 1 | #include "tools.h" 2 | struct timespec tms; 3 | uint64_t millis; 4 | 5 | const char * ConvertDWORDToIP(DWORD ip) { 6 | static char ipstr[5][128]; 7 | static int count = 0; 8 | 9 | int i = count++; 10 | if (count == 5) count = 0; 11 | sprintf(ipstr[i], "%d.%d.%d.%d", 12 | (ip & 0x000000FF), 13 | (ip & 0x0000FF00) >> 8, 14 | (ip & 0x00FF0000) >> 16, 15 | (ip & 0xFF000000) >> 24 16 | ); 17 | return ipstr[i]; 18 | } 19 | 20 | void SetNonBlockIO(int fd) { 21 | int val = fcntl(fd, F_GETFL, 0); 22 | if (fcntl(fd, F_SETFL, val | O_NONBLOCK) != 0) { 23 | MyAssert(0, 1616); 24 | } 25 | } 26 | 27 | #if TRANS == 1 28 | void SetQuickACK(int fd) { 29 | static int enable = 1; 30 | int r = setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, &enable, sizeof(int)); 31 | MyAssert(r == 0, 2040); 32 | } 33 | #endif 34 | 35 | uint64_t get_current_millisecond(){ 36 | if (clock_gettime(CLOCK_REALTIME,&tms)) { 37 | return 0; 38 | } 39 | millis = tms.tv_sec; 40 | millis *= 1000; 41 | millis += (tms.tv_nsec+500000)/1000000; 42 | return millis; 43 | } 44 | 45 | void SetSocketNoDelay_TCP(int fd) { 46 | static int enable = 1; 47 | int r = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &enable,sizeof(int)); 48 | MyAssert(r == 0, 1768); 49 | } 50 | 51 | void SetSocketBuffer(int fd, int readBufSize, int writeBufSize) { 52 | int r1 = 0; 53 | int r2 = 0; 54 | if (readBufSize != 0) { 55 | r1 = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &readBufSize, sizeof(int)); MyAssert(r1 == 0, 1786); 56 | } 57 | 58 | if (writeBufSize != 0) { 59 | r2 = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &writeBufSize, sizeof(int)); MyAssert(r2 == 0, 1787); 60 | } 61 | 62 | /* 63 | socklen_t s1, s2; 64 | s1 = s2 = 4; 65 | r1 = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &readBufSize, &s1); 66 | r2 = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &writeBufSize, &s2); 67 | */ 68 | 69 | MyAssert(r1 == 0 && r2 == 0, 1769); 70 | 71 | //InfoMessage("*** %d %d readBufSize=%d writeBufSize=%d ***", (int)s1, (int)s2, readBufSize, writeBufSize); 72 | } 73 | 74 | int GetSendBufSpace(int fd){ 75 | 76 | int r; 77 | // ioctl(fd, TIOCOUTQ, &r); 78 | LOGD("About to GetSendBufSpace"); 79 | ioctl(fd, SIOCOUTQ, &r); 80 | LOGD("GetSendBufSpace"); 81 | return r; 82 | } 83 | 84 | int GetRecvBufSpace(int fd){ 85 | 86 | int r; 87 | ioctl(fd, FIONREAD, &r); 88 | // ioctl(fd, SIOCINQ, &r); 89 | return r; 90 | } 91 | 92 | double GetMillisecondTS() { 93 | #ifndef VS_SIMULATION 94 | struct timeval tv; 95 | gettimeofday(&tv, NULL); 96 | return tv.tv_sec + tv.tv_usec * 1e-6 ; 97 | #else 98 | return 0.0f; 99 | #endif 100 | } 101 | 102 | extern unsigned long highResTimestampBase; 103 | 104 | unsigned long GetHighResTimestamp() { 105 | #ifndef VS_SIMULATION 106 | struct timeval tv; 107 | gettimeofday(&tv, NULL); 108 | unsigned long tNow = tv.tv_sec * 1000000 + tv.tv_usec; 109 | 110 | return tNow - highResTimestampBase; 111 | #else 112 | return 0; 113 | #endif 114 | } -------------------------------------------------------------------------------- /Helper/src/main/cpp/tools.h: -------------------------------------------------------------------------------- 1 | #ifndef DMM_TOOLS_H 2 | #define DMM_TOOLS_H 3 | 4 | #define TAG "Shawn-JNI" 5 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__) 6 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__) 7 | 8 | #include 9 | #include "proxy.h" 10 | 11 | const char * ConvertDWORDToIP(DWORD ip); 12 | 13 | void SetNonBlockIO(int fd); 14 | 15 | uint64_t get_current_millisecond(); 16 | 17 | void SetQuickACK(int fd); 18 | void SetSocketNoDelay_TCP(int fd); 19 | 20 | void SetSocketBuffer(int fd, int readBufSize, int writeBufSize); 21 | 22 | int GetSendBufSpace(int fd); 23 | int GetRecvBufSpace(int fd); 24 | 25 | inline void MyAssert(int x, int assertID) {} 26 | /* 27 | { 28 | #ifdef DEBUG_ENABLE_ASSERTION 29 | if (!x) { 30 | fprintf(stderr, "Assertion failure: %d\n", assertID); 31 | fprintf(stderr, "errno = %d (%s)\n", errno, strerror(errno)); 32 | fclose(ofsOWD); 33 | fclose(owd_proc_f); 34 | fclose(owd1_proc_f); 35 | fclose(owd2_proc_f); 36 | fclose(ack1_proc_f); 37 | fclose(ack2_proc_f); 38 | shutdown(pipes.fd[0], 2); 39 | shutdown(pipes.fd[1], 2); 40 | printf("exit.\n"); 41 | exit(-1); 42 | } 43 | #endif 44 | } 45 | */ 46 | double GetMillisecondTS(); 47 | static inline WORD ReverseWORD(WORD x) { 48 | return 49 | (x & 0xFF) << 8 | 50 | (x & 0xFF00) >> 8; 51 | } 52 | 53 | unsigned long GetHighResTimestamp(); 54 | 55 | #define TCPSOCKET_2_PIPEBUFFER 1 56 | #define PIPEBUFFER_2_PIPESOCKET 2 57 | #define PIPESOCKET_2_TCPBUFFER 3 58 | #define TCPBUFFER_2_TCPSOCKET 4 59 | 60 | inline unsigned long GetLogicTime() { 61 | static unsigned long l = 100; 62 | return l++; 63 | } 64 | 65 | 66 | #endif //DMM_TOOLS_H 67 | -------------------------------------------------------------------------------- /Helper/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Helper/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /Helper/src/main/java/edu/robustnet/xiao/mpbondhel/http/ConnectivityNetworkCallback.java: -------------------------------------------------------------------------------- 1 | package edu.robustnet.xiao.mpbondhel.http; 2 | 3 | import android.net.ConnectivityManager; 4 | import android.net.Network; 5 | 6 | import java.util.concurrent.CountDownLatch; 7 | 8 | public class ConnectivityNetworkCallback extends ConnectivityManager.NetworkCallback{ 9 | private CountDownLatch latch; 10 | private ConnectivityManager cm; 11 | private Network network; 12 | public ConnectivityNetworkCallback(CountDownLatch l, ConnectivityManager cm){ 13 | this.latch=l; 14 | this.cm=cm; 15 | } 16 | 17 | public ConnectivityManager getConnectivityManager(){ 18 | return this.cm; 19 | } 20 | public Network getNetwork(){ 21 | return this.network; 22 | } 23 | @Override 24 | public void onAvailable(Network network) { 25 | super.onAvailable(network); 26 | // cm.bindProcessToNetwork(network); 27 | this.latch.countDown(); 28 | this.network= network; 29 | // this.cm.unregisterNetworkCallback(this); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Helper/src/main/java/edu/robustnet/xiao/mpbondhel/http/HttpListener.java: -------------------------------------------------------------------------------- 1 | package edu.robustnet.xiao.mpbondhel.http; 2 | 3 | public interface HttpListener { 4 | // void onTransferEnd(HttpHelper.NetType netType, int byteRangeStart, int byteRangeEnd); 5 | void onBytesTransferred(byte b[], int offset, int len, HttpHelper.NetType netType, int byteRangeStart, int byteRangeEnd); 6 | } 7 | -------------------------------------------------------------------------------- /Helper/src/main/java/edu/robustnet/xiao/mpbondhel/util/Constants.java: -------------------------------------------------------------------------------- 1 | package edu.robustnet.xiao.mpbondhel.util; 2 | 3 | public final class Constants { 4 | // Secondary 5 | public static final int BT_CHANNEL = 0; 6 | public static final int BLE_CHANNEL = 1; 7 | public static final int WIFI_CHANNEL = 2; 8 | public static final int LTE_CHANNEL = 3; 9 | public static final String TAG = "Shawn-Helper"; 10 | public static final boolean isPipeInJava = true; 11 | public static final int rateLimit = 0; // in kbps, limit pipe bandwidth 12 | public static final int secNo = 2; // id of subflow, e.g., the first secondary device maps to subflow 2 13 | public static final boolean hasPipeMeasurement = true; 14 | public static final int feedbackType = 1; // 0: no feedback; 1: always-on; 2: on-demand 15 | 16 | public static final int proxyPort = 1303; 17 | public static final int proxyPortSide = 1304; 18 | public static final String proxyIP = "127.0.0.1"; 19 | public static final int serverPort = 5000; 20 | public static final int serverPortSide = 5501; 21 | 22 | // WiFiListener 23 | public static final String WiFiListenerTAG = "Shawn-WiFiListener"; 24 | } 25 | -------------------------------------------------------------------------------- /Helper/src/main/java/edu/robustnet/xiao/mpbondhel/util/LocalConn.java: -------------------------------------------------------------------------------- 1 | package edu.robustnet.xiao.mpbondhel.util; 2 | 3 | public class LocalConn { 4 | 5 | public native String connSetupFromJNI(); 6 | static { 7 | System.loadLibrary("proxy"); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /Helper/src/main/java/edu/robustnet/xiao/mpbondhel/util/NetEnabler.java: -------------------------------------------------------------------------------- 1 | package edu.robustnet.xiao.mpbondhel.util; 2 | 3 | import android.app.IntentService; 4 | import android.content.*; 5 | import android.net.*; 6 | import android.util.Log; 7 | 8 | public class NetEnabler extends IntentService { 9 | 10 | private static final String TAG = "OpenNet"; 11 | private ConnectivityManager mConnectivityManager; 12 | private ConnectivityManager.NetworkCallback networkCallback = null; 13 | private int networkCapabilities = NetworkCapabilities.TRANSPORT_CELLULAR; 14 | 15 | @Override 16 | protected void onHandleIntent(Intent intent) { 17 | 18 | String network = intent.getStringExtra("type"); 19 | mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 20 | enableNet(network); 21 | } 22 | 23 | private void enableNet(String value) { 24 | if (networkCallback != null) { 25 | return; 26 | } 27 | if (value == "WiFi") { 28 | networkCapabilities = NetworkCapabilities.TRANSPORT_WIFI; 29 | } 30 | else if (value == "Cell") { 31 | networkCapabilities = NetworkCapabilities.TRANSPORT_CELLULAR; 32 | } 33 | 34 | networkCallback = 35 | new ConnectivityManager.NetworkCallback() { 36 | @Override 37 | public void onAvailable(Network network) { 38 | Log.d(TAG, "LTE Network available."); 39 | } 40 | }; 41 | NetworkRequest request = new NetworkRequest.Builder() 42 | .addTransportType(networkCapabilities) 43 | .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 44 | .build(); 45 | mConnectivityManager.requestNetwork(request, networkCallback); 46 | } 47 | 48 | public NetEnabler() { 49 | super("MyIntentService"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Helper/src/main/java/edu/robustnet/xiao/mpbondhel/util/Pipe.java: -------------------------------------------------------------------------------- 1 | package edu.robustnet.xiao.mpbondhel.util; 2 | 3 | public class Pipe { 4 | 5 | public native String pipeSetupFromJNI(String subflowIP, String rpIP, int secNo, boolean isJava, int nSubflow); 6 | static { 7 | System.loadLibrary("proxy"); 8 | } 9 | 10 | private byte[] data; 11 | private long seq; 12 | private int len; 13 | private long time; 14 | 15 | public byte[] getData(){ 16 | return data; 17 | } 18 | 19 | public void setData(byte [] data) 20 | { 21 | this.data = data; 22 | this.len = data.length; 23 | } 24 | 25 | public void setData(byte [] data, long time, long seq) 26 | { 27 | this.data = data; 28 | this.seq = seq; 29 | this.time = time; 30 | this.len = data.length; 31 | } 32 | 33 | public long getTime(){return time;} 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /Helper/src/main/java/edu/robustnet/xiao/mpbondhel/util/Subflow.java: -------------------------------------------------------------------------------- 1 | package edu.robustnet.xiao.mpbondhel.util; 2 | 3 | public class Subflow { 4 | 5 | public native String subflowFromJNI(String subflowIP, String rpIP, int feedbackType, int subflowId, int nSubflow); 6 | static { 7 | System.loadLibrary("proxy"); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/Authenticator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp; 17 | 18 | import java.io.IOException; 19 | import javax.annotation.Nullable; 20 | 21 | /** 22 | * Responds to an authentication challenge from either a remote web server or a proxy server. 23 | * Implementations may either attempt to satisfy the challenge by returning a request that includes 24 | * an authorization header, or they may refuse the challenge by returning null. In this case the 25 | * unauthenticated response will be returned to the caller that triggered it. 26 | * 27 | *

Implementations should check if the initial request already included an attempt to 28 | * authenticate. If so it is likely that further attempts will not be useful and the authenticator 29 | * should give up. 30 | * 31 | *

When authentication is requested by an origin server, the response code is 401 and the 32 | * implementation should respond with a new request that sets the "Authorization" header. 33 | *

   {@code
34 |  *
35 |  *    if (response.request().header("Authorization") != null) {
36 |  *      return null; // Give up, we've already failed to authenticate.
37 |  *    }
38 |  *
39 |  *    String credential = Credentials.basic(...)
40 |  *    return response.request().newBuilder()
41 |  *        .header("Authorization", credential)
42 |  *        .build();
43 |  * }
44 | * 45 | *

When authentication is requested by a proxy server, the response code is 407 and the 46 | * implementation should respond with a new request that sets the "Proxy-Authorization" header. 47 | *

   {@code
48 |  *
49 |  *    if (response.request().header("Proxy-Authorization") != null) {
50 |  *      return null; // Give up, we've already failed to authenticate.
51 |  *    }
52 |  *
53 |  *    String credential = Credentials.basic(...)
54 |  *    return response.request().newBuilder()
55 |  *        .header("Proxy-Authorization", credential)
56 |  *        .build();
57 |  * }
58 | * 59 | *

Applications may configure OkHttp with an authenticator for origin servers, or proxy servers, 60 | * or both. 61 | */ 62 | public interface Authenticator { 63 | /** An authenticator that knows no credentials and makes no attempt to authenticate. */ 64 | Authenticator NONE = new Authenticator() { 65 | @Override public Request authenticate(Route route, Response response) { 66 | return null; 67 | } 68 | }; 69 | 70 | /** 71 | * Returns a request that includes a credential to satisfy an authentication challenge in {@code 72 | * response}. Returns null if the challenge cannot be satisfied. 73 | */ 74 | @Nullable Request authenticate(Route route, Response response) throws IOException; 75 | } 76 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/Callback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp; 17 | 18 | import java.io.IOException; 19 | 20 | public interface Callback { 21 | /** 22 | * Called when the request could not be executed due to cancellation, a connectivity problem or 23 | * timeout. Because networks can fail during an exchange, it is possible that the remote server 24 | * accepted the request before the failure. 25 | */ 26 | void onFailure(Call call, IOException e); 27 | 28 | /** 29 | * Called when the HTTP response was successfully returned by the remote server. The callback may 30 | * proceed to read the response body with {@link Response#body}. The response is still live until 31 | * its response body is {@linkplain ResponseBody closed}. The recipient of the callback may 32 | * consume the response body on another thread. 33 | * 34 | *

Note that transport-layer success (receiving a HTTP response code, headers and body) does 35 | * not necessarily indicate application-layer success: {@code response} may still indicate an 36 | * unhappy HTTP response code like 404 or 500. 37 | */ 38 | void onResponse(Call call, Response response) throws IOException; 39 | } 40 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/Challenge.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp; 17 | 18 | import java.nio.charset.Charset; 19 | import javax.annotation.Nullable; 20 | 21 | import static myokhttp.internal.Util.ISO_8859_1; 22 | 23 | /** An RFC 7617 challenge. */ 24 | public final class Challenge { 25 | private final String scheme; 26 | private final String realm; 27 | private final Charset charset; 28 | 29 | public Challenge(String scheme, String realm) { 30 | this(scheme, realm, ISO_8859_1); 31 | } 32 | 33 | private Challenge(String scheme, String realm, Charset charset) { 34 | if (scheme == null) throw new NullPointerException("scheme == null"); 35 | if (realm == null) throw new NullPointerException("realm == null"); 36 | if (charset == null) throw new NullPointerException("charset == null"); 37 | this.scheme = scheme; 38 | this.realm = realm; 39 | this.charset = charset; 40 | } 41 | 42 | /** Returns a copy of this charset that expects a credential encoded with {@code charset}. */ 43 | public Challenge withCharset(Charset charset) { 44 | return new Challenge(scheme, realm, charset); 45 | } 46 | 47 | /** Returns the authentication scheme, like {@code Basic}. */ 48 | public String scheme() { 49 | return scheme; 50 | } 51 | 52 | /** Returns the protection space. */ 53 | public String realm() { 54 | return realm; 55 | } 56 | 57 | /** Returns the charset that should be used to encode the credential. */ 58 | public Charset charset() { 59 | return charset; 60 | } 61 | 62 | @Override public boolean equals(@Nullable Object other) { 63 | return other instanceof Challenge 64 | && ((Challenge) other).scheme.equals(scheme) 65 | && ((Challenge) other).realm.equals(realm) 66 | && ((Challenge) other).charset.equals(charset); 67 | } 68 | 69 | @Override public int hashCode() { 70 | int result = 29; 71 | result = 31 * result + realm.hashCode(); 72 | result = 31 * result + scheme.hashCode(); 73 | result = 31 * result + charset.hashCode(); 74 | return result; 75 | } 76 | 77 | @Override public String toString() { 78 | return scheme 79 | + " realm=\"" + realm + "\"" 80 | + " charset=\"" + charset + "\""; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/CookieJar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp; 17 | 18 | import java.util.Collections; 19 | import java.util.List; 20 | 21 | /** 22 | * Provides policy and persistence for HTTP cookies. 23 | * 24 | *

As policy, implementations of this interface are responsible for selecting which cookies to 25 | * accept and which to reject. A reasonable policy is to reject all cookies, though that may 26 | * interfere with session-based authentication schemes that require cookies. 27 | * 28 | *

As persistence, implementations of this interface must also provide storage of cookies. Simple 29 | * implementations may store cookies in memory; sophisticated ones may use the file system or 30 | * database to hold accepted cookies. The cookie storage model specifies 32 | * policies for updating and expiring cookies. 33 | */ 34 | public interface CookieJar { 35 | /** A cookie jar that never accepts any cookies. */ 36 | CookieJar NO_COOKIES = new CookieJar() { 37 | @Override public void saveFromResponse(HttpUrl url, List cookies) { 38 | } 39 | 40 | @Override public List loadForRequest(HttpUrl url) { 41 | return Collections.emptyList(); 42 | } 43 | }; 44 | 45 | /** 46 | * Saves {@code cookies} from an HTTP response to this store according to this jar's policy. 47 | * 48 | *

Note that this method may be called a second time for a single HTTP response if the response 49 | * includes a trailer. For this obscure HTTP feature, {@code cookies} contains only the trailer's 50 | * cookies. 51 | */ 52 | void saveFromResponse(HttpUrl url, List cookies); 53 | 54 | /** 55 | * Load cookies from the jar for an HTTP request to {@code url}. This method returns a possibly 56 | * empty list of cookies for the network request. 57 | * 58 | *

Simple implementations will return the accepted cookies that have not yet expired and that 59 | * {@linkplain Cookie#matches match} {@code url}. 60 | */ 61 | List loadForRequest(HttpUrl url); 62 | } 63 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/Credentials.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp; 17 | 18 | import java.nio.charset.Charset; 19 | import okio.ByteString; 20 | 21 | import static myokhttp.internal.Util.ISO_8859_1; 22 | 23 | /** Factory for HTTP authorization credentials. */ 24 | public final class Credentials { 25 | private Credentials() { 26 | } 27 | 28 | /** Returns an auth credential for the Basic scheme. */ 29 | public static String basic(String userName, String password) { 30 | return basic(userName, password, ISO_8859_1); 31 | } 32 | 33 | public static String basic(String userName, String password, Charset charset) { 34 | String usernameAndPassword = userName + ":" + password; 35 | String encoded = ByteString.encodeString(usernameAndPassword, charset).base64(); 36 | return "Basic " + encoded; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/Dns.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp; 17 | 18 | import java.net.InetAddress; 19 | import java.net.UnknownHostException; 20 | import java.util.Arrays; 21 | import java.util.List; 22 | 23 | /** 24 | * A domain name service that resolves IP addresses for host names. Most applications will use the 25 | * {@linkplain #SYSTEM system DNS service}, which is the default. Some applications may provide 26 | * their own implementation to use a different DNS server, to prefer IPv6 addresses, to prefer IPv4 27 | * addresses, or to force a specific known IP address. 28 | * 29 | *

Implementations of this interface must be safe for concurrent use. 30 | */ 31 | public interface Dns { 32 | /** 33 | * A DNS that uses {@link InetAddress#getAllByName} to ask the underlying operating system to 34 | * lookup IP addresses. Most custom {@link Dns} implementations should delegate to this instance. 35 | */ 36 | Dns SYSTEM = new Dns() { 37 | @Override public List lookup(String hostname) throws UnknownHostException { 38 | if (hostname == null) throw new UnknownHostException("hostname == null"); 39 | try { 40 | return Arrays.asList(InetAddress.getAllByName(hostname)); 41 | } catch (NullPointerException e) { 42 | UnknownHostException unknownHostException = 43 | new UnknownHostException("Broken system behaviour for dns lookup of " + hostname); 44 | unknownHostException.initCause(e); 45 | throw unknownHostException; 46 | } 47 | } 48 | }; 49 | 50 | /** 51 | * Returns the IP addresses of {@code hostname}, in the order they will be attempted by OkHttp. If 52 | * a connection to an address fails, OkHttp will retry the connection with the next address until 53 | * either a connection is made, the set of IP addresses is exhausted, or a limit is exceeded. 54 | */ 55 | List lookup(String hostname) throws UnknownHostException; 56 | } 57 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/Interceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp; 17 | 18 | import java.io.IOException; 19 | import java.util.concurrent.TimeUnit; 20 | import javax.annotation.Nullable; 21 | 22 | /** 23 | * Observes, modifies, and potentially short-circuits requests going out and the corresponding 24 | * responses coming back in. Typically interceptors add, remove, or transform headers on the request 25 | * or response. 26 | */ 27 | public interface Interceptor { 28 | Response intercept(Chain chain) throws IOException; 29 | 30 | interface Chain { 31 | Request request(); 32 | 33 | Response proceed(Request request) throws IOException; 34 | 35 | /** 36 | * Returns the connection the request will be executed on. This is only available in the chains 37 | * of network interceptors; for application interceptors this is always null. 38 | */ 39 | @Nullable Connection connection(); 40 | 41 | Call call(); 42 | 43 | int connectTimeoutMillis(); 44 | 45 | Chain withConnectTimeout(int timeout, TimeUnit unit); 46 | 47 | int readTimeoutMillis(); 48 | 49 | Chain withReadTimeout(int timeout, TimeUnit unit); 50 | 51 | int writeTimeoutMillis(); 52 | 53 | Chain withWriteTimeout(int timeout, TimeUnit unit); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/TlsVersion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp; 17 | 18 | import java.util.ArrayList; 19 | import java.util.Collections; 20 | import java.util.List; 21 | 22 | /** 23 | * Versions of TLS that can be offered when negotiating a secure socket. See {@link 24 | * javax.net.ssl.SSLSocket#setEnabledProtocols}. 25 | */ 26 | public enum TlsVersion { 27 | TLS_1_3("TLSv1.3"), // 2016. 28 | TLS_1_2("TLSv1.2"), // 2008. 29 | TLS_1_1("TLSv1.1"), // 2006. 30 | TLS_1_0("TLSv1"), // 1999. 31 | SSL_3_0("SSLv3"), // 1996. 32 | ; 33 | 34 | final String javaName; 35 | 36 | TlsVersion(String javaName) { 37 | this.javaName = javaName; 38 | } 39 | 40 | public static TlsVersion forJavaName(String javaName) { 41 | switch (javaName) { 42 | case "TLSv1.3": 43 | return TLS_1_3; 44 | case "TLSv1.2": 45 | return TLS_1_2; 46 | case "TLSv1.1": 47 | return TLS_1_1; 48 | case "TLSv1": 49 | return TLS_1_0; 50 | case "SSLv3": 51 | return SSL_3_0; 52 | } 53 | throw new IllegalArgumentException("Unexpected TLS version: " + javaName); 54 | } 55 | 56 | static List forJavaNames(String... tlsVersions) { 57 | List result = new ArrayList<>(tlsVersions.length); 58 | for (String tlsVersion : tlsVersions) { 59 | result.add(forJavaName(tlsVersion)); 60 | } 61 | return Collections.unmodifiableList(result); 62 | } 63 | 64 | public String javaName() { 65 | return javaName; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/WebSocketListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp; 17 | 18 | import javax.annotation.Nullable; 19 | import okio.ByteString; 20 | 21 | public abstract class WebSocketListener { 22 | /** 23 | * Invoked when a web socket has been accepted by the remote peer and may begin transmitting 24 | * messages. 25 | */ 26 | public void onOpen(WebSocket webSocket, Response response) { 27 | } 28 | 29 | /** Invoked when a text (type {@code 0x1}) message has been received. */ 30 | public void onMessage(WebSocket webSocket, String text) { 31 | } 32 | 33 | /** Invoked when a binary (type {@code 0x2}) message has been received. */ 34 | public void onMessage(WebSocket webSocket, ByteString bytes) { 35 | } 36 | 37 | /** 38 | * Invoked when the remote peer has indicated that no more incoming messages will be 39 | * transmitted. 40 | */ 41 | public void onClosing(WebSocket webSocket, int code, String reason) { 42 | } 43 | 44 | /** 45 | * Invoked when both peers have indicated that no more messages will be transmitted and the 46 | * connection has been successfully released. No further calls to this listener will be made. 47 | */ 48 | public void onClosed(WebSocket webSocket, int code, String reason) { 49 | } 50 | 51 | /** 52 | * Invoked when a web socket has been closed due to an error reading from or writing to the 53 | * network. Both outgoing and incoming messages may have been lost. No further calls to this 54 | * listener will be made. 55 | */ 56 | public void onFailure(WebSocket webSocket, Throwable t, @Nullable Response response) { 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/Internal.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal; 17 | 18 | import java.net.MalformedURLException; 19 | import java.net.Socket; 20 | import java.net.UnknownHostException; 21 | import javax.net.ssl.SSLSocket; 22 | import myokhttp.Address; 23 | import myokhttp.Call; 24 | import myokhttp.ConnectionPool; 25 | import myokhttp.ConnectionSpec; 26 | import myokhttp.Headers; 27 | import myokhttp.HttpUrl; 28 | import myokhttp.OkHttpClient; 29 | import myokhttp.Request; 30 | import myokhttp.Response; 31 | import myokhttp.Route; 32 | import myokhttp.internal.cache.InternalCache; 33 | import myokhttp.internal.connection.RealConnection; 34 | import myokhttp.internal.connection.RouteDatabase; 35 | import myokhttp.internal.connection.StreamAllocation; 36 | 37 | /** 38 | * Escalate internal APIs in {@code okhttp3} so they can be used from OkHttp's implementation 39 | * packages. The only implementation of this interface is in {@link OkHttpClient}. 40 | */ 41 | public abstract class Internal { 42 | 43 | public static void initializeInstanceForTests() { 44 | // Needed in tests to ensure that the instance is actually pointing to something. 45 | new OkHttpClient(); 46 | } 47 | 48 | public static Internal instance; 49 | 50 | public abstract void addLenient(Headers.Builder builder, String line); 51 | 52 | public abstract void addLenient(Headers.Builder builder, String name, String value); 53 | 54 | public abstract void setCache(OkHttpClient.Builder builder, InternalCache internalCache); 55 | 56 | public abstract RealConnection get(ConnectionPool pool, Address address, 57 | StreamAllocation streamAllocation, Route route); 58 | 59 | public abstract boolean equalsNonHost(Address a, Address b); 60 | 61 | public abstract Socket deduplicate( 62 | ConnectionPool pool, Address address, StreamAllocation streamAllocation); 63 | 64 | public abstract void put(ConnectionPool pool, RealConnection connection); 65 | 66 | public abstract boolean connectionBecameIdle(ConnectionPool pool, RealConnection connection); 67 | 68 | public abstract RouteDatabase routeDatabase(ConnectionPool connectionPool); 69 | 70 | public abstract int code(Response.Builder responseBuilder); 71 | 72 | public abstract void apply(ConnectionSpec tlsConfiguration, SSLSocket sslSocket, 73 | boolean isFallback); 74 | 75 | public abstract HttpUrl getHttpUrlChecked(String url) 76 | throws MalformedURLException, UnknownHostException; 77 | 78 | public abstract StreamAllocation streamAllocation(Call call); 79 | 80 | public abstract Call newWebSocketCall(OkHttpClient client, Request request); 81 | } 82 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/NamedRunnable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal; 17 | 18 | /** 19 | * Runnable implementation which always sets its thread name. 20 | */ 21 | public abstract class NamedRunnable implements Runnable { 22 | protected final String name; 23 | 24 | public NamedRunnable(String format, Object... args) { 25 | this.name = Util.format(format, args); 26 | } 27 | 28 | @Override public final void run() { 29 | String oldName = Thread.currentThread().getName(); 30 | Thread.currentThread().setName(name); 31 | try { 32 | execute(); 33 | } finally { 34 | Thread.currentThread().setName(oldName); 35 | } 36 | } 37 | 38 | protected abstract void execute(); 39 | } 40 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/Version.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal; 17 | 18 | public final class Version { 19 | public static String userAgent() { 20 | return "okhttp/${project.version}"; 21 | } 22 | 23 | private Version() { 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/cache/CacheRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.cache; 17 | 18 | import java.io.IOException; 19 | import okio.Sink; 20 | 21 | public interface CacheRequest { 22 | Sink body() throws IOException; 23 | 24 | void abort(); 25 | } 26 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/cache/FaultHidingSink.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.cache; 17 | 18 | import java.io.IOException; 19 | import okio.Buffer; 20 | import okio.ForwardingSink; 21 | import okio.Sink; 22 | 23 | /** A sink that never throws IOExceptions, even if the underlying sink does. */ 24 | class FaultHidingSink extends ForwardingSink { 25 | private boolean hasErrors; 26 | 27 | FaultHidingSink(Sink delegate) { 28 | super(delegate); 29 | } 30 | 31 | @Override public void write(Buffer source, long byteCount) throws IOException { 32 | if (hasErrors) { 33 | source.skip(byteCount); 34 | return; 35 | } 36 | try { 37 | super.write(source, byteCount); 38 | } catch (IOException e) { 39 | hasErrors = true; 40 | onException(e); 41 | } 42 | } 43 | 44 | @Override public void flush() throws IOException { 45 | if (hasErrors) return; 46 | try { 47 | super.flush(); 48 | } catch (IOException e) { 49 | hasErrors = true; 50 | onException(e); 51 | } 52 | } 53 | 54 | @Override public void close() throws IOException { 55 | if (hasErrors) return; 56 | try { 57 | super.close(); 58 | } catch (IOException e) { 59 | hasErrors = true; 60 | onException(e); 61 | } 62 | } 63 | 64 | protected void onException(IOException e) { 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/cache/InternalCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.cache; 17 | 18 | import java.io.IOException; 19 | import myokhttp.Request; 20 | import myokhttp.Response; 21 | 22 | /** 23 | * OkHttp's internal cache interface. Applications shouldn't implement this: instead use {@link 24 | * myokhttp.Cache}. 25 | */ 26 | public interface InternalCache { 27 | Response get(Request request) throws IOException; 28 | 29 | CacheRequest put(Response response) throws IOException; 30 | 31 | /** 32 | * Remove any cache entries for the supplied {@code request}. This is invoked when the client 33 | * invalidates the cache, such as when making POST requests. 34 | */ 35 | void remove(Request request) throws IOException; 36 | 37 | /** 38 | * Handles a conditional request hit by updating the stored cache response with the headers from 39 | * {@code network}. The cached response body is not updated. If the stored response has changed 40 | * since {@code cached} was returned, this does nothing. 41 | */ 42 | void update(Response cached, Response network); 43 | 44 | /** Track an conditional GET that was satisfied by this cache. */ 45 | void trackConditionalCacheHit(); 46 | 47 | /** Track an HTTP response being satisfied with {@code cacheStrategy}. */ 48 | void trackResponse(CacheStrategy cacheStrategy); 49 | } 50 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/connection/ConnectInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package myokhttp.internal.connection; 18 | 19 | import java.io.IOException; 20 | import myokhttp.Interceptor; 21 | import myokhttp.OkHttpClient; 22 | import myokhttp.Request; 23 | import myokhttp.Response; 24 | import myokhttp.internal.http.HttpCodec; 25 | import myokhttp.internal.http.RealInterceptorChain; 26 | 27 | /** Opens a connection to the target server and proceeds to the next interceptor. */ 28 | public final class ConnectInterceptor implements Interceptor { 29 | public final OkHttpClient client; 30 | 31 | public ConnectInterceptor(OkHttpClient client) { 32 | this.client = client; 33 | } 34 | 35 | @Override public Response intercept(Chain chain) throws IOException { 36 | RealInterceptorChain realChain = (RealInterceptorChain) chain; 37 | Request request = realChain.request(); 38 | StreamAllocation streamAllocation = realChain.streamAllocation(); 39 | 40 | // We need the network to satisfy this request. Possibly for validating a conditional GET. 41 | boolean doExtensiveHealthChecks = !request.method().equals("GET"); 42 | HttpCodec httpCodec = streamAllocation.newStream(client, chain, doExtensiveHealthChecks); 43 | RealConnection connection = streamAllocation.connection(); 44 | 45 | return realChain.proceed(request, streamAllocation, httpCodec, connection); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/connection/RouteDatabase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.connection; 17 | 18 | import java.util.LinkedHashSet; 19 | import java.util.Set; 20 | import myokhttp.Route; 21 | 22 | /** 23 | * A blacklist of failed routes to avoid when creating a new connection to a target address. This is 24 | * used so that OkHttp can learn from its mistakes: if there was a failure attempting to connect to 25 | * a specific IP address or proxy server, that failure is remembered and alternate routes are 26 | * preferred. 27 | */ 28 | public final class RouteDatabase { 29 | private final Set failedRoutes = new LinkedHashSet<>(); 30 | 31 | /** Records a failure connecting to {@code failedRoute}. */ 32 | public synchronized void failed(Route failedRoute) { 33 | failedRoutes.add(failedRoute); 34 | } 35 | 36 | /** Records success connecting to {@code route}. */ 37 | public synchronized void connected(Route route) { 38 | failedRoutes.remove(route); 39 | } 40 | 41 | /** Returns true if {@code route} has failed recently and should be avoided. */ 42 | public synchronized boolean shouldPostpone(Route route) { 43 | return failedRoutes.contains(route); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/connection/RouteException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.connection; 17 | 18 | import java.io.IOException; 19 | import java.lang.reflect.InvocationTargetException; 20 | import java.lang.reflect.Method; 21 | 22 | /** 23 | * An exception thrown to indicate a problem connecting via a single Route. Multiple attempts may 24 | * have been made with alternative protocols, none of which were successful. 25 | */ 26 | public final class RouteException extends RuntimeException { 27 | private static final Method addSuppressedExceptionMethod; 28 | 29 | static { 30 | Method m; 31 | try { 32 | m = Throwable.class.getDeclaredMethod("addSuppressed", Throwable.class); 33 | } catch (Exception e) { 34 | m = null; 35 | } 36 | addSuppressedExceptionMethod = m; 37 | } 38 | 39 | private IOException lastException; 40 | 41 | public RouteException(IOException cause) { 42 | super(cause); 43 | lastException = cause; 44 | } 45 | 46 | public IOException getLastConnectException() { 47 | return lastException; 48 | } 49 | 50 | public void addConnectException(IOException e) { 51 | addSuppressedIfPossible(e, lastException); 52 | lastException = e; 53 | } 54 | 55 | private void addSuppressedIfPossible(IOException e, IOException suppressed) { 56 | if (addSuppressedExceptionMethod != null) { 57 | try { 58 | addSuppressedExceptionMethod.invoke(e, suppressed); 59 | } catch (InvocationTargetException | IllegalAccessException ignored) { 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/http/HttpCodec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http; 17 | 18 | import java.io.IOException; 19 | import myokhttp.Request; 20 | import myokhttp.Response; 21 | import myokhttp.ResponseBody; 22 | import okio.Sink; 23 | 24 | /** Encodes HTTP requests and decodes HTTP responses. */ 25 | public interface HttpCodec { 26 | /** 27 | * The timeout to use while discarding a stream of input data. Since this is used for connection 28 | * reuse, this timeout should be significantly less than the time it takes to establish a new 29 | * connection. 30 | */ 31 | int DISCARD_STREAM_TIMEOUT_MILLIS = 100; 32 | 33 | /** Returns an output stream where the request body can be streamed. */ 34 | Sink createRequestBody(Request request, long contentLength); 35 | 36 | /** This should update the HTTP engine's sentRequestMillis field. */ 37 | void writeRequestHeaders(Request request) throws IOException; 38 | 39 | /** Flush the request to the underlying socket. */ 40 | void flushRequest() throws IOException; 41 | 42 | /** Flush the request to the underlying socket and signal no more bytes will be transmitted. */ 43 | void finishRequest() throws IOException; 44 | 45 | /** 46 | * Parses bytes of a response header from an HTTP transport. 47 | * 48 | * @param expectContinue true to return null if this is an intermediate response with a "100" 49 | * response code. Otherwise this method never returns null. 50 | */ 51 | Response.Builder readResponseHeaders(boolean expectContinue) throws IOException; 52 | 53 | /** Returns a stream that reads the response body. */ 54 | ResponseBody openResponseBody(Response response) throws IOException; 55 | 56 | /** 57 | * Cancel this stream. Resources held by this stream will be cleaned up, though not synchronously. 58 | * That may happen later by the connection pool thread. 59 | */ 60 | void cancel(); 61 | } 62 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/http/HttpMethod.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http; 17 | 18 | public final class HttpMethod { 19 | public static boolean invalidatesCache(String method) { 20 | return method.equals("POST") 21 | || method.equals("PATCH") 22 | || method.equals("PUT") 23 | || method.equals("DELETE") 24 | || method.equals("MOVE"); // WebDAV 25 | } 26 | 27 | public static boolean requiresRequestBody(String method) { 28 | return method.equals("POST") 29 | || method.equals("PUT") 30 | || method.equals("PATCH") 31 | || method.equals("PROPPATCH") // WebDAV 32 | || method.equals("REPORT"); // CalDAV/CardDAV (defined in WebDAV Versioning) 33 | } 34 | 35 | public static boolean permitsRequestBody(String method) { 36 | return requiresRequestBody(method) 37 | || method.equals("OPTIONS") 38 | || method.equals("DELETE") // Permitted as spec is ambiguous. 39 | || method.equals("PROPFIND") // (WebDAV) without body: request 40 | || method.equals("MKCOL") // (WebDAV) may contain a body, but behaviour is unspecified 41 | || method.equals("LOCK"); // (WebDAV) body: create lock, without body: refresh lock 42 | } 43 | 44 | public static boolean redirectsWithBody(String method) { 45 | return method.equals("PROPFIND"); // (WebDAV) redirects should also maintain the request body 46 | } 47 | 48 | public static boolean redirectsToGet(String method) { 49 | // All requests but PROPFIND should redirect to a GET request. 50 | return !method.equals("PROPFIND"); 51 | } 52 | 53 | private HttpMethod() { 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/http/RealResponseBody.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http; 17 | 18 | import javax.annotation.Nullable; 19 | import myokhttp.MediaType; 20 | import myokhttp.ResponseBody; 21 | import okio.BufferedSource; 22 | 23 | public final class RealResponseBody extends ResponseBody { 24 | /** 25 | * Use a string to avoid parsing the content type until needed. This also defers problems caused 26 | * by malformed content types. 27 | */ 28 | private final @Nullable String contentTypeString; 29 | private final long contentLength; 30 | private final BufferedSource source; 31 | 32 | public RealResponseBody( 33 | @Nullable String contentTypeString, long contentLength, BufferedSource source) { 34 | this.contentTypeString = contentTypeString; 35 | this.contentLength = contentLength; 36 | this.source = source; 37 | } 38 | 39 | @Override public MediaType contentType() { 40 | return contentTypeString != null ? MediaType.parse(contentTypeString) : null; 41 | } 42 | 43 | @Override public long contentLength() { 44 | return contentLength; 45 | } 46 | 47 | @Override public BufferedSource source() { 48 | return source; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/http/RequestLine.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http; 17 | 18 | import java.net.HttpURLConnection; 19 | import java.net.Proxy; 20 | import myokhttp.HttpUrl; 21 | import myokhttp.Request; 22 | 23 | public final class RequestLine { 24 | private RequestLine() { 25 | } 26 | 27 | /** 28 | * Returns the request status line, like "GET / HTTP/1.1". This is exposed to the application by 29 | * {@link HttpURLConnection#getHeaderFields}, so it needs to be set even if the transport is 30 | * HTTP/2. 31 | */ 32 | public static String get(Request request, Proxy.Type proxyType) { 33 | StringBuilder result = new StringBuilder(); 34 | result.append(request.method()); 35 | result.append(' '); 36 | 37 | if (includeAuthorityInRequestLine(request, proxyType)) { 38 | result.append(request.url()); 39 | } else { 40 | result.append(requestPath(request.url())); 41 | } 42 | 43 | result.append(" HTTP/1.1"); 44 | return result.toString(); 45 | } 46 | 47 | /** 48 | * Returns true if the request line should contain the full URL with host and port (like "GET 49 | * http://android.com/foo HTTP/1.1") or only the path (like "GET /foo HTTP/1.1"). 50 | */ 51 | private static boolean includeAuthorityInRequestLine(Request request, Proxy.Type proxyType) { 52 | return !request.isHttps() && proxyType == Proxy.Type.HTTP; 53 | } 54 | 55 | /** 56 | * Returns the path to request, like the '/' in 'GET / HTTP/1.1'. Never empty, even if the request 57 | * URL is. Includes the query component if it exists. 58 | */ 59 | public static String requestPath(HttpUrl url) { 60 | String path = url.encodedPath(); 61 | String query = url.encodedQuery(); 62 | return query != null ? (path + '?' + query) : path; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/http/UnrepeatableRequestBody.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http; 17 | 18 | public interface UnrepeatableRequestBody { 19 | } 20 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/http2/ConnectionShutdownException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http2; 17 | 18 | import java.io.IOException; 19 | 20 | /** 21 | * Thrown when an HTTP/2 connection is shutdown (either explicitly or if the peer has sent a GOAWAY 22 | * frame) and an attempt is made to use the connection. 23 | */ 24 | public final class ConnectionShutdownException extends IOException { 25 | } 26 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/http2/ErrorCode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http2; 17 | 18 | // http://tools.ietf.org/html/draft-ietf-httpbis-http2-17#section-7 19 | public enum ErrorCode { 20 | /** Not an error! */ 21 | NO_ERROR(0), 22 | 23 | PROTOCOL_ERROR(1), 24 | 25 | INTERNAL_ERROR(2), 26 | 27 | FLOW_CONTROL_ERROR(3), 28 | 29 | REFUSED_STREAM(7), 30 | 31 | CANCEL(8); 32 | 33 | public final int httpCode; 34 | 35 | ErrorCode(int httpCode) { 36 | this.httpCode = httpCode; 37 | } 38 | 39 | public static ErrorCode fromHttp2(int code) { 40 | for (ErrorCode errorCode : ErrorCode.values()) { 41 | if (errorCode.httpCode == code) return errorCode; 42 | } 43 | return null; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/http2/Header.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http2; 17 | 18 | import myokhttp.internal.Util; 19 | import okio.ByteString; 20 | 21 | /** HTTP header: the name is an ASCII string, but the value can be UTF-8. */ 22 | public final class Header { 23 | // Special header names defined in HTTP/2 spec. 24 | public static final ByteString PSEUDO_PREFIX = ByteString.encodeUtf8(":"); 25 | public static final ByteString RESPONSE_STATUS = ByteString.encodeUtf8(":status"); 26 | public static final ByteString TARGET_METHOD = ByteString.encodeUtf8(":method"); 27 | public static final ByteString TARGET_PATH = ByteString.encodeUtf8(":path"); 28 | public static final ByteString TARGET_SCHEME = ByteString.encodeUtf8(":scheme"); 29 | public static final ByteString TARGET_AUTHORITY = ByteString.encodeUtf8(":authority"); 30 | 31 | /** Name in case-insensitive ASCII encoding. */ 32 | public final ByteString name; 33 | /** Value in UTF-8 encoding. */ 34 | public final ByteString value; 35 | final int hpackSize; 36 | 37 | // TODO: search for toLowerCase and consider moving logic here. 38 | public Header(String name, String value) { 39 | this(ByteString.encodeUtf8(name), ByteString.encodeUtf8(value)); 40 | } 41 | 42 | public Header(ByteString name, String value) { 43 | this(name, ByteString.encodeUtf8(value)); 44 | } 45 | 46 | public Header(ByteString name, ByteString value) { 47 | this.name = name; 48 | this.value = value; 49 | this.hpackSize = 32 + name.size() + value.size(); 50 | } 51 | 52 | @Override public boolean equals(Object other) { 53 | if (other instanceof Header) { 54 | Header that = (Header) other; 55 | return this.name.equals(that.name) 56 | && this.value.equals(that.value); 57 | } 58 | return false; 59 | } 60 | 61 | @Override public int hashCode() { 62 | int result = 17; 63 | result = 31 * result + name.hashCode(); 64 | result = 31 * result + value.hashCode(); 65 | return result; 66 | } 67 | 68 | @Override public String toString() { 69 | return Util.format("%s: %s", name.utf8(), value.utf8()); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/http2/Ping.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http2; 17 | 18 | import java.util.concurrent.CountDownLatch; 19 | import java.util.concurrent.TimeUnit; 20 | 21 | /** 22 | * A locally-originated ping. 23 | */ 24 | public final class Ping { 25 | private final CountDownLatch latch = new CountDownLatch(1); 26 | private long sent = -1; 27 | private long received = -1; 28 | 29 | Ping() { 30 | } 31 | 32 | void send() { 33 | if (sent != -1) throw new IllegalStateException(); 34 | sent = System.nanoTime(); 35 | } 36 | 37 | void receive() { 38 | if (received != -1 || sent == -1) throw new IllegalStateException(); 39 | received = System.nanoTime(); 40 | latch.countDown(); 41 | } 42 | 43 | void cancel() { 44 | if (received != -1 || sent == -1) throw new IllegalStateException(); 45 | received = sent - 1; 46 | latch.countDown(); 47 | } 48 | 49 | /** 50 | * Returns the round trip time for this ping in nanoseconds, waiting for the response to arrive if 51 | * necessary. Returns -1 if the response was canceled. 52 | */ 53 | public long roundTripTime() throws InterruptedException { 54 | latch.await(); 55 | return received - sent; 56 | } 57 | 58 | /** 59 | * Returns the round trip time for this ping in nanoseconds, or -1 if the response was canceled, 60 | * or -2 if the timeout elapsed before the round trip completed. 61 | */ 62 | public long roundTripTime(long timeout, TimeUnit unit) throws InterruptedException { 63 | if (latch.await(timeout, unit)) { 64 | return received - sent; 65 | } else { 66 | return -2; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/http2/StreamResetException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http2; 17 | 18 | import java.io.IOException; 19 | 20 | /** Thrown when an HTTP/2 stream is canceled without damage to the socket that carries it. */ 21 | public final class StreamResetException extends IOException { 22 | public final ErrorCode errorCode; 23 | 24 | public StreamResetException(ErrorCode errorCode) { 25 | super("stream was reset: " + errorCode); 26 | this.errorCode = errorCode; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/tls/BasicTrustRootIndex.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.tls; 17 | 18 | import java.security.PublicKey; 19 | import java.security.cert.X509Certificate; 20 | import java.util.LinkedHashMap; 21 | import java.util.LinkedHashSet; 22 | import java.util.Map; 23 | import java.util.Set; 24 | import javax.security.auth.x500.X500Principal; 25 | 26 | /** A simple index that of trusted root certificates that have been loaded into memory. */ 27 | public final class BasicTrustRootIndex implements TrustRootIndex { 28 | private final Map> subjectToCaCerts; 29 | 30 | public BasicTrustRootIndex(X509Certificate... caCerts) { 31 | subjectToCaCerts = new LinkedHashMap<>(); 32 | for (X509Certificate caCert : caCerts) { 33 | X500Principal subject = caCert.getSubjectX500Principal(); 34 | Set subjectCaCerts = subjectToCaCerts.get(subject); 35 | if (subjectCaCerts == null) { 36 | subjectCaCerts = new LinkedHashSet<>(1); 37 | subjectToCaCerts.put(subject, subjectCaCerts); 38 | } 39 | subjectCaCerts.add(caCert); 40 | } 41 | } 42 | 43 | @Override public X509Certificate findByIssuerAndSignature(X509Certificate cert) { 44 | X500Principal issuer = cert.getIssuerX500Principal(); 45 | Set subjectCaCerts = subjectToCaCerts.get(issuer); 46 | if (subjectCaCerts == null) return null; 47 | 48 | for (X509Certificate caCert : subjectCaCerts) { 49 | PublicKey publicKey = caCert.getPublicKey(); 50 | try { 51 | cert.verify(publicKey); 52 | return caCert; 53 | } catch (Exception ignored) { 54 | } 55 | } 56 | 57 | return null; 58 | } 59 | 60 | @Override public boolean equals(Object other) { 61 | if (other == this) return true; 62 | return other instanceof myokhttp.internal.tls.BasicTrustRootIndex 63 | && ((myokhttp.internal.tls.BasicTrustRootIndex) other).subjectToCaCerts.equals( 64 | subjectToCaCerts); 65 | } 66 | 67 | @Override public int hashCode() { 68 | return subjectToCaCerts.hashCode(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/tls/CertificateChainCleaner.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package myokhttp.internal.tls; 18 | 19 | import java.security.cert.Certificate; 20 | import java.security.cert.X509Certificate; 21 | import java.util.List; 22 | import javax.net.ssl.SSLPeerUnverifiedException; 23 | import javax.net.ssl.X509TrustManager; 24 | import myokhttp.internal.platform.Platform; 25 | 26 | /** 27 | * Computes the effective certificate chain from the raw array returned by Java's built in TLS APIs. 28 | * Cleaning a chain returns a list of certificates where the first element is {@code chain[0]}, each 29 | * certificate is signed by the certificate that follows, and the last certificate is a trusted CA 30 | * certificate. 31 | * 32 | *

Use of the chain cleaner is necessary to omit unexpected certificates that aren't relevant to 33 | * the TLS handshake and to extract the trusted CA certificate for the benefit of certificate 34 | * pinning. 35 | */ 36 | public abstract class CertificateChainCleaner { 37 | public abstract List clean(List chain, String hostname) 38 | throws SSLPeerUnverifiedException; 39 | 40 | public static CertificateChainCleaner get(X509TrustManager trustManager) { 41 | return Platform.get().buildCertificateChainCleaner(trustManager); 42 | } 43 | 44 | public static CertificateChainCleaner get(X509Certificate... caCerts) { 45 | return new BasicCertificateChainCleaner(new BasicTrustRootIndex(caCerts)); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/internal/tls/TrustRootIndex.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.tls; 17 | 18 | import java.security.cert.X509Certificate; 19 | 20 | public interface TrustRootIndex { 21 | /** Returns the trusted CA certificate that signed {@code cert}. */ 22 | X509Certificate findByIssuerAndSignature(X509Certificate cert); 23 | } 24 | -------------------------------------------------------------------------------- /Helper/src/main/java/myokhttp/package-info.java: -------------------------------------------------------------------------------- 1 | /** An HTTP+HTTP/2 client for Android and Java applications. */ 2 | @javax.annotation.ParametersAreNonnullByDefault 3 | package myokhttp; 4 | -------------------------------------------------------------------------------- /Helper/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Helper/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Helper/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Helper/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Helper/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Helper/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /Helper/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Helper/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Helper/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Helper/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Helper/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Helper/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /Helper/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Helper/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Helper/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Helper/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Helper/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Helper/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /Helper/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Helper/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Helper/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Helper/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Helper/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Helper/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /Helper/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Helper/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Helper/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Helper/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Helper/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Helper/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /Helper/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Helper/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Helper/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #5652A6 4 | -------------------------------------------------------------------------------- /Helper/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | DMM 3 | 4 | -------------------------------------------------------------------------------- /Helper/src/main/res/xml/network_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Primary/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Primary/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Sets the minimum version of CMake required to build your native library. 2 | # This ensures that a certain set of CMake features is available to 3 | # your build. 4 | 5 | cmake_minimum_required(VERSION 3.4.1) 6 | 7 | # Specifies a path to native header files. 8 | include_directories(src/main/cpp/) 9 | 10 | add_library(proxy SHARED src/main/cpp/proxy.cpp) 11 | add_library(proxy_setting STATIC src/main/cpp/proxy_setting.cpp) 12 | add_library(tools STATIC src/main/cpp/tools.cpp) 13 | add_library(kernel_info STATIC src/main/cpp/kernel_info.cpp) 14 | add_library(hints STATIC src/main/cpp/hints.cpp) 15 | add_library(subflow STATIC src/main/cpp/subflow.cpp) 16 | add_library(connections STATIC src/main/cpp/connections.cpp) 17 | add_library(pipe STATIC src/main/cpp/pipe.cpp) 18 | target_link_libraries(subflow android log connections hints kernel_info) 19 | target_link_libraries(proxy connections subflow tools proxy_setting pipe) 20 | target_link_libraries(connections android log tools subflow kernel_info) 21 | -------------------------------------------------------------------------------- /Primary/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 29 5 | buildToolsVersion "29.0.1" 6 | defaultConfig { 7 | applicationId "edu.robustnet.xiao.mpbondpri" 8 | minSdkVersion 23 9 | targetSdkVersion 29 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | externalNativeBuild { 21 | cmake { 22 | path 'CMakeLists.txt' 23 | } 24 | } 25 | } 26 | 27 | dependencies { 28 | implementation fileTree(dir: 'libs', include: ['*.jar']) 29 | implementation 'androidx.appcompat:appcompat:1.0.2' 30 | testImplementation 'junit:junit:4.12' 31 | androidTestImplementation 'androidx.test:runner:1.2.0' 32 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 33 | // wearApp project(':Primary') 34 | implementation 'com.google.android.gms:play-services-wearable:+' 35 | implementation 'com.squareup.okio:okio:1.13.0' 36 | implementation 'androidx.annotation:annotation:1.1.0' 37 | implementation 'javax.annotation:javax.annotation-api:1.2-b01' 38 | implementation files('libs/guava-23.0-android.jar') 39 | implementation files('libs/jsr305-3.0.2.jar') 40 | } 41 | -------------------------------------------------------------------------------- /Primary/libs/guava-23.0-android.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Primary/libs/guava-23.0-android.jar -------------------------------------------------------------------------------- /Primary/libs/jsr305-3.0.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Primary/libs/jsr305-3.0.2.jar -------------------------------------------------------------------------------- /Primary/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /Primary/src/androidTest/java/edu/robustnet/xiao/mpbondpri/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package edu.robustnet.xiao.mpbondpri; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("edu.robustnet.xiao.dmm", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Primary/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 30 | 31 | android:windowSoftInputMode="stateHidden" 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 42 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Primary/src/main/cpp/hints.cpp: -------------------------------------------------------------------------------- 1 | #include "hints.h" 2 | #include "tools.h" 3 | 4 | int HINT_ENTRY::matchEntry(DWORD serverIP, WORD serverPort) { 5 | if (this->serverIP >> (32-ipPrefix) == serverIP >> (32-ipPrefix) 6 | && this->serverPort == serverPort) 7 | return 1; 8 | return 0; 9 | } 10 | 11 | DWORD HINT_ENTRY::getHints() { 12 | DWORD value = 0; 13 | value += ((DWORD) sched << 24); 14 | value += ((DWORD) timeType << 22); 15 | value += ((DWORD) timeValue << 16); 16 | value += ((DWORD) energyType << 14); 17 | value += ((DWORD) energyValue << 8); 18 | value += ((DWORD) dataType << 6); 19 | value += ((DWORD) dataValue); 20 | return value; 21 | } 22 | 23 | DWORD HINTS::getHints(DWORD serverIP, WORD serverPort) { 24 | DWORD value = 0xFFFFFFFF; 25 | LOGD("Get Hints for: %u %u", serverIP, serverPort); 26 | for (int i = 0; i <= maxHint; i++) { 27 | if (entries[i].matchEntry(serverIP, serverPort)) { 28 | value = entries[i].getHints(); 29 | break; 30 | } 31 | } 32 | return value; 33 | } 34 | 35 | void HINTS::print() { 36 | for (int i = 0; i <= maxHint; i++) { 37 | LOGD("Rule %d: serverIP=%u ipPrefix=%d serverPort=%u " 38 | "sched=%d time=%d/%d energy=%d/%d data=%d/%d", 39 | i, entries[i].serverIP, entries[i].ipPrefix, entries[i].serverPort, 40 | entries[i].sched, entries[i].timeType, entries[i].timeValue, 41 | entries[i].energyType, entries[i].energyValue, 42 | entries[i].dataType, entries[i].dataValue); 43 | } 44 | } -------------------------------------------------------------------------------- /Primary/src/main/cpp/hints.h: -------------------------------------------------------------------------------- 1 | #ifndef MPBOND_HINTS_H 2 | #define MPBOND_HINTS_H 3 | 4 | #include "proxy.h" 5 | 6 | #define MAX_HINT 100 7 | 8 | struct HINT_ENTRY { 9 | DWORD serverIP; 10 | int ipPrefix; 11 | WORD serverPort; 12 | 13 | int sched; // 8 bit 14 | int timeType, timeValue; // 2 bit + 6 bit 15 | int energyType, energyValue; // 2 bit + 6 bit 16 | int dataType, dataValue; // 2 bit + 6 bit 17 | 18 | int matchEntry(DWORD serverIP, WORD serverPort); 19 | DWORD getHints(); 20 | }; 21 | 22 | struct HINTS { 23 | int maxHint; 24 | HINT_ENTRY entries[MAX_HINT]; 25 | DWORD getHints(DWORD serverIP, WORD serverPort); 26 | void print(); 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /Primary/src/main/cpp/kernel_info.cpp: -------------------------------------------------------------------------------- 1 | #include "kernel_info.h" 2 | #include "connections.h" 3 | #include "tools.h" 4 | 5 | extern struct CONNECTIONS conns; 6 | extern struct KERNEL_INFO kernelInfo; 7 | 8 | void KERNEL_INFO::Setup() { 9 | infoSize = sizeof(pipeinfo[0]); 10 | for (int i = 1; i < MAX_PIPES; i++) { 11 | fd[i] = conns.peers[i].fd; 12 | } 13 | nTCP = PROXY_SETTINGS::nTCPPipes; 14 | 15 | // MPBond 16 | for (int i = 1; i < MAX_PIPES; i++) { 17 | pipeBW[i] = 0; 18 | pipeRTT[i] = 0; 19 | bytesInPipe[i] = 0; 20 | bytesOnDevice[i] = 0; 21 | } 22 | expectedSeq = 0; 23 | } 24 | 25 | void KERNEL_INFO::UpdatePipeInfo(int pipeNo) { 26 | int r = 0; 27 | if (pipeNo > 0 && pipeNo < MAX_PIPES) { 28 | r = getsockopt(fd[pipeNo], IPPROTO_TCP, TCP_INFO, 29 | &pipeinfo[pipeNo], (socklen_t *)&infoSize); 30 | MyAssert(r == 0, 9110); 31 | } else { 32 | for (int i = 1; i <= nTCP; i++) { 33 | if (fd[i] >= 0) { 34 | r = getsockopt(fd[i], IPPROTO_TCP, TCP_INFO, 35 | &pipeinfo[i], (socklen_t *)&infoSize); 36 | MyAssert(r == 0, 9111); 37 | } 38 | } 39 | } 40 | } 41 | 42 | // currently not available 43 | int KERNEL_INFO::GetTCPAvailableSpace(int pipeNo) { 44 | if (pipeNo >= 1 && pipeNo <= nTCP) 45 | return space[pipeNo]; 46 | return 0; 47 | } 48 | 49 | unsigned int KERNEL_INFO::GetSendCwnd(int pipeNo) { 50 | return pipeinfo[pipeNo].tcpi_snd_cwnd; 51 | } 52 | 53 | 54 | unsigned int KERNEL_INFO::GetSndMss(int pipeNo) { 55 | return pipeinfo[pipeNo].tcpi_snd_mss; 56 | } 57 | 58 | // bytes 59 | int KERNEL_INFO::GetInFlightSize(int pipeNo) { 60 | return (pipeinfo[pipeNo].tcpi_unacked - pipeinfo[pipeNo].tcpi_sacked 61 | - pipeinfo[pipeNo].tcpi_lost + pipeinfo[pipeNo].tcpi_retrans) * GetSndMss(pipeNo); 62 | } 63 | 64 | 65 | // us 66 | int KERNEL_INFO::GetSRTT(int pipeNo) { 67 | return pipeinfo[pipeNo].tcpi_rtt; 68 | } 69 | 70 | -------------------------------------------------------------------------------- /Primary/src/main/cpp/kernel_info.h: -------------------------------------------------------------------------------- 1 | #ifndef MPBOND_KERNEL_INFO_H 2 | #define MPBOND_KERNEL_INFO_H 3 | 4 | #include "proxy_setting.h" 5 | 6 | struct KERNEL_INFO { 7 | struct tcp_info pipeinfo[MAX_PIPES]; 8 | int space[MAX_PIPES]; 9 | 10 | int fd[MAX_PIPES]; 11 | int infoSize; 12 | int nTCP; 13 | // MPBond 14 | int pipeBW[MAX_PIPES]; // in kbps 15 | int pipeRTT[MAX_PIPES]; 16 | int bytesInPipe[MAX_PIPES]; 17 | int bytesOnDevice[MAX_PIPES]; 18 | DWORD expectedSeq; 19 | 20 | void Setup(); 21 | void UpdatePipeInfo(int pipeNo); 22 | 23 | int GetTCPAvailableSpace(int pipeNo); 24 | unsigned int GetSendCwnd(int pipeNo); 25 | unsigned int GetSndMss(int pipeNo); 26 | int GetInFlightSize(int pipeNo); 27 | int GetSRTT(int pipeNo); 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /Primary/src/main/cpp/pipe.h: -------------------------------------------------------------------------------- 1 | #ifndef MPBOND_PIPE_H 2 | #define MPBOND_PIPE_H 3 | 4 | #include "proxy_setting.h" 5 | 6 | struct PIPE_MSG { 7 | 8 | }; 9 | 10 | struct PIPE { 11 | 12 | int n; 13 | int localListenFD; 14 | int feedbackFD; 15 | int fd[MAX_PIPES]; 16 | int Setup(bool isTether, int n, const char * rIP); 17 | void Accept(); 18 | void SetCongestionControl(int fd, const char * tcpVar); 19 | void SendPipeInformedACK(); 20 | 21 | // following for sec 22 | int secNo; 23 | int localListenFDSide; 24 | int secSetup(const char * localIP, const char * remoteIP, int secNo); 25 | }; 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /Primary/src/main/cpp/proxy.h: -------------------------------------------------------------------------------- 1 | #ifndef MPBOND_PROXY_H 2 | #define MPBOND_PROXY_H 3 | 4 | //transport protocol 1=TCP, 2=UDP, 3=SCTP 5 | #define TRANS 1 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include //for SIOCOUTQ 35 | 36 | #include 37 | #include 38 | 39 | #include "proxy_setting.h" 40 | 41 | #define R_SUCC 1 42 | #define R_FAIL 0 43 | 44 | typedef unsigned char BYTE; 45 | typedef unsigned int DWORD; 46 | typedef unsigned short WORD; 47 | 48 | 49 | #define PROXY_MODE_LOCAL 1 50 | #define PROXY_MODE_REMOTE 2 51 | 52 | //using namespace std; 53 | 54 | int ProxyMain(); 55 | 56 | #endif 57 | 58 | -------------------------------------------------------------------------------- /Primary/src/main/cpp/scheduler.h: -------------------------------------------------------------------------------- 1 | #ifndef MPBOND_SCHEDULER_H 2 | #define MPBOND_SCHEDULER_H 3 | 4 | #include "subflow.h" 5 | 6 | /* Number of scheduling algorithms to consider 7 | * (size of schedulerSeq). 8 | * When adding new schedulers, the corresponding scheduler ID must be 9 | * added to schedulerSeq. 10 | */ 11 | #define SCHED_SEQ_NUM 12 12 | 13 | struct SCHEDULER; 14 | 15 | typedef SUBFLOW_MSG * (SCHEDULER::*SelectPipeFunc)(); 16 | 17 | struct SCHEDULER { 18 | double * pkt_delay; 19 | int schedulerSeq[SCHED_SEQ_NUM]; 20 | // mapping between schedNo (scheduler ID) and meta buffer index for different schedulers 21 | int schedulerQ[16 * 2]; 22 | int indexSeq; 23 | int nTCP; 24 | int twoWayWiFi, twoWayLTE; 25 | 26 | void Setup(); 27 | 28 | int schedHasPackets(int sched); 29 | int getNextSchedNo(); 30 | int getNextSchedNo2(); 31 | 32 | // SelectPipeFunc DefaultSelectPipe; 33 | int defaultScheduler; 34 | 35 | SelectPipeFunc SelectPipe[MAX_SCHEDULER]; 36 | 37 | static const char * getSchedulerName(int sched); 38 | int getSchedNormalQueue(int sched); 39 | int getSchedFirstQueue(int sched); 40 | int getSchedLastQueue(int sched); 41 | 42 | void printPktDelay(); 43 | void clearPktDelay(); 44 | 45 | SUBFLOW_MSG * SelectPipe_ControlMsg(); 46 | 47 | private: 48 | //pipe selection algorithms 49 | SUBFLOW_MSG * SelectPipe_WithBinding(); 50 | //SUBFLOW_MSG * SelectPipe_MinimumBuf(); //this is the classic algorithm 51 | //SUBFLOW_MSG * SelectPipe_RoundRobin(); 52 | //SUBFLOW_MSG * SelectPipe_Random(); 53 | //SUBFLOW_MSG * SelectPipe_RoundRobinChunk(); 54 | //SUBFLOW_MSG * SelectPipe_Fixed(); 55 | //SUBFLOW_MSG * SelectPipe_MinRTT(); 56 | 57 | SUBFLOW_MSG * SelectPipe_TwoWay_Base(int saveBytes, int schedNo); 58 | SUBFLOW_MSG * SelectPipe_TwoWay(); 59 | SUBFLOW_MSG * SelectPipe_TwoWay_Naive(); 60 | SUBFLOW_MSG * SelectPipe_TwoWay_Balance(); 61 | SUBFLOW_MSG * SelectPipe_NewTxDelay(); 62 | SUBFLOW_MSG * SelectPipe_NewTxDelayBase(int queueNo); 63 | SUBFLOW_MSG * SelectPipe_MinRTT_Kernel(); 64 | SUBFLOW_MSG * SelectPipe_TxDelay(); 65 | SUBFLOW_MSG * SelectPipe_TxDelayPlus(); 66 | SUBFLOW_MSG * SelectPipe_RoundRobin(); 67 | SUBFLOW_MSG * SelectPipe_ReMP(); 68 | SUBFLOW_MSG * SelectPipe_Wifi(); 69 | SUBFLOW_MSG * SelectPipe_LTE(); 70 | SUBFLOW_MSG * SelectPipe_BBS(); 71 | SUBFLOW_MSG * SelectPipe_BBS_MRT(); 72 | SUBFLOW_MSG * SelectPipe_EMPTCP(); 73 | SUBFLOW_MSG * SelectPipe_Block(); 74 | SUBFLOW_MSG * SelectPipe_UDP(); 75 | 76 | SUBFLOW_MSG * SearchPacketForLargeRTTPath(int large_rtt_i, int small_rtt_i, int queueNo); 77 | SUBFLOW_MSG * GetMessageForPipe(int pipeNo, int queueNo, int other, int isSmallRTT, int saveBytes, uint64_t currt); 78 | }; 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /Primary/src/main/cpp/tools.cpp: -------------------------------------------------------------------------------- 1 | #include "tools.h" 2 | struct timespec tms; 3 | uint64_t millis; 4 | 5 | const char * ConvertDWORDToIP(DWORD ip) { 6 | static char ipstr[5][128]; 7 | static int count = 0; 8 | 9 | int i = count++; 10 | if (count == 5) count = 0; 11 | sprintf(ipstr[i], "%d.%d.%d.%d", 12 | (ip & 0x000000FF), 13 | (ip & 0x0000FF00) >> 8, 14 | (ip & 0x00FF0000) >> 16, 15 | (ip & 0xFF000000) >> 24 16 | ); 17 | return ipstr[i]; 18 | } 19 | 20 | void SetNonBlockIO(int fd) { 21 | int val = fcntl(fd, F_GETFL, 0); 22 | if (fcntl(fd, F_SETFL, val | O_NONBLOCK) != 0) { 23 | MyAssert(0, 1616); 24 | } 25 | } 26 | 27 | #if TRANS == 1 28 | void SetQuickACK(int fd) { 29 | static int enable = 1; 30 | int r = setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, &enable, sizeof(int)); 31 | MyAssert(r == 0, 2040); 32 | } 33 | #endif 34 | 35 | uint64_t get_current_millisecond(){ 36 | if (clock_gettime(CLOCK_REALTIME,&tms)) { 37 | return 0; 38 | } 39 | millis = tms.tv_sec; 40 | millis *= 1000; 41 | millis += (tms.tv_nsec+500000) / 1000000; 42 | return millis; 43 | } 44 | 45 | void SetSocketNoDelay_TCP(int fd) { 46 | static int enable = 1; 47 | int r = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &enable,sizeof(int)); 48 | MyAssert(r == 0, 1768); 49 | } 50 | 51 | void SetSocketBuffer(int fd, int readBufSize, int writeBufSize) { 52 | int r1 = 0; 53 | int r2 = 0; 54 | if (readBufSize != 0) { 55 | r1 = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &readBufSize, sizeof(int)); MyAssert(r1 == 0, 1786); 56 | } 57 | 58 | if (writeBufSize != 0) { 59 | r2 = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &writeBufSize, sizeof(int)); MyAssert(r2 == 0, 1787); 60 | } 61 | 62 | /* 63 | socklen_t s1, s2; 64 | s1 = s2 = 4; 65 | r1 = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &readBufSize, &s1); 66 | r2 = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &writeBufSize, &s2); 67 | */ 68 | 69 | MyAssert(r1 == 0 && r2 == 0, 1769); 70 | 71 | //InfoMessage("*** %d %d readBufSize=%d writeBufSize=%d ***", (int)s1, (int)s2, readBufSize, writeBufSize); 72 | } 73 | 74 | double GetMillisecondTS() { 75 | #ifndef VS_SIMULATION 76 | struct timeval tv; 77 | gettimeofday(&tv, NULL); 78 | return tv.tv_sec + tv.tv_usec * 1e-6 ; 79 | #else 80 | return 0.0f; 81 | #endif 82 | } 83 | 84 | extern unsigned long highResTimestampBase; 85 | 86 | unsigned long GetHighResTimestamp() { 87 | #ifndef VS_SIMULATION 88 | struct timeval tv; 89 | gettimeofday(&tv, NULL); 90 | unsigned long tNow = tv.tv_sec * 1000000 + tv.tv_usec; 91 | 92 | return tNow - highResTimestampBase; 93 | #else 94 | return 0; 95 | #endif 96 | } 97 | 98 | -------------------------------------------------------------------------------- /Primary/src/main/cpp/tools.h: -------------------------------------------------------------------------------- 1 | #ifndef MPBOND_TOOLS_H 2 | #define MPBOND_TOOLS_H 3 | 4 | #define TAG "Shawn-JNI" 5 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__) 6 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__) 7 | 8 | #include 9 | #include "proxy.h" 10 | 11 | const char * ConvertDWORDToIP(DWORD ip); 12 | 13 | void SetNonBlockIO(int fd); 14 | 15 | uint64_t get_current_millisecond(); 16 | 17 | void SetQuickACK(int fd); 18 | void SetSocketNoDelay_TCP(int fd); 19 | 20 | void SetSocketBuffer(int fd, int readBufSize, int writeBufSize); 21 | 22 | inline void MyAssert(int x, int assertID) { 23 | #ifdef DEBUG_ENABLE_ASSERTION 24 | if (!x) { 25 | fprintf(stderr, "Assertion failure: %d\n", assertID); 26 | fprintf(stderr, "errno = %d (%s)\n", errno, strerror(errno)); 27 | fclose(ofsOWD); 28 | fclose(owd_proc_f); 29 | fclose(owd1_proc_f); 30 | fclose(owd2_proc_f); 31 | fclose(ack1_proc_f); 32 | fclose(ack2_proc_f); 33 | shutdown(pipes.fd[0], 2); 34 | shutdown(pipes.fd[1], 2); 35 | printf("exit.\n"); 36 | exit(-1); 37 | } 38 | #endif 39 | } 40 | double GetMillisecondTS(); 41 | static inline WORD ReverseWORD(WORD x) { 42 | return 43 | (x & 0xFF) << 8 | 44 | (x & 0xFF00) >> 8; 45 | } 46 | 47 | unsigned long GetHighResTimestamp(); 48 | 49 | #define TCPSOCKET_2_PIPEBUFFER 1 50 | #define PIPEBUFFER_2_PIPESOCKET 2 51 | #define PIPESOCKET_2_TCPBUFFER 3 52 | #define TCPBUFFER_2_TCPSOCKET 4 53 | 54 | 55 | inline unsigned long GetLogicTime() { 56 | static unsigned long l = 100; 57 | return l++; 58 | } 59 | 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /Primary/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Primary/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /Primary/src/main/java/edu/robustnet/xiao/mpbondpri/http/ConnectivityNetworkCallback.java: -------------------------------------------------------------------------------- 1 | package edu.robustnet.xiao.mpbondpri.http; 2 | 3 | import android.net.ConnectivityManager; 4 | import android.net.Network; 5 | 6 | import java.util.concurrent.CountDownLatch; 7 | 8 | public class ConnectivityNetworkCallback extends ConnectivityManager.NetworkCallback{ 9 | private CountDownLatch latch; 10 | private ConnectivityManager cm; 11 | private Network network; 12 | public ConnectivityNetworkCallback(CountDownLatch l, ConnectivityManager cm){ 13 | this.latch=l; 14 | this.cm=cm; 15 | } 16 | 17 | public ConnectivityManager getConnectivityManager(){ 18 | return this.cm; 19 | } 20 | public Network getNetwork(){ 21 | return this.network; 22 | } 23 | @Override 24 | public void onAvailable(Network network) { 25 | super.onAvailable(network); 26 | // cm.bindProcessToNetwork(network); 27 | this.latch.countDown(); 28 | this.network= network; 29 | // this.cm.unregisterNetworkCallback(this); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Primary/src/main/java/edu/robustnet/xiao/mpbondpri/http/HttpListener.java: -------------------------------------------------------------------------------- 1 | package edu.robustnet.xiao.mpbondpri.http; 2 | 3 | import java.io.InputStream; 4 | import java.io.OutputStream; 5 | 6 | public interface HttpListener { 7 | void onTransferEnd(HttpPrimary.NetType netType); 8 | void onPipeTransferEnd(HttpPrimary.NetType netType, int byteRangeStart, int byteRangeEnd, InputStream pipeInputStream, OutputStream pipeOutputStream); 9 | void onBytesTransferred(byte b[], int offset, int len, HttpPrimary.NetType netType, int byteRangeStart, int byteRangeEnd); 10 | } 11 | -------------------------------------------------------------------------------- /Primary/src/main/java/edu/robustnet/xiao/mpbondpri/util/Constants.java: -------------------------------------------------------------------------------- 1 | package edu.robustnet.xiao.mpbondpri.util; 2 | 3 | public final class Constants { 4 | public static final int BT_CHANNEL = 0; 5 | public static final int BLE_CHANNEL = 1; 6 | public static final int WIFI_CHANNEL = 2; 7 | public static final int LTE_CHANNEL = 3; 8 | public static final String TAG = "Shawn-Primary"; 9 | public static final boolean hasPipeMeasurement = true; 10 | public static final int feedbackType = 0; // 0: no feedback; 2: on-demand 11 | 12 | public static final boolean isPipeInJava = true; 13 | // public static final boolean isTether = false; 14 | // public static int nSec = 1; 15 | 16 | public static final String proxyIP = "127.0.0.1"; 17 | public static final int proxyPort = 1303; 18 | public static final int proxyPortSide = 1304; 19 | public static final int serverPort = 5000; 20 | public static final int serverPortSide = 5501; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Primary/src/main/java/edu/robustnet/xiao/mpbondpri/util/LocalConn.java: -------------------------------------------------------------------------------- 1 | package edu.robustnet.xiao.mpbondpri.util; 2 | 3 | public class LocalConn { 4 | 5 | private static final String TAG = "LocalConn"; 6 | 7 | // @Override 8 | // public void run() { 9 | // Log.d(TAG, connFromJNI()); 10 | // } 11 | 12 | public native String connSetupFromJNI(); 13 | static { 14 | System.loadLibrary("proxy"); 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /Primary/src/main/java/edu/robustnet/xiao/mpbondpri/util/NetEnabler.java: -------------------------------------------------------------------------------- 1 | package edu.robustnet.xiao.mpbondpri.util; 2 | 3 | import android.app.IntentService; 4 | import android.content.*; 5 | import android.net.*; 6 | import android.util.Log; 7 | 8 | public class NetEnabler extends IntentService { 9 | 10 | private static final String TAG = "OpenNet"; 11 | private ConnectivityManager mConnectivityManager; 12 | private ConnectivityManager.NetworkCallback networkCallback = null; 13 | private int networkCapabilities = NetworkCapabilities.TRANSPORT_CELLULAR; 14 | 15 | @Override 16 | protected void onHandleIntent(Intent intent) { 17 | Log.d(TAG, "onHandleIntent"); 18 | String network = intent.getStringExtra("type"); 19 | mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 20 | 21 | enableNet(network); 22 | } 23 | 24 | private void enableNet(String value) { 25 | if (networkCallback != null) { 26 | return; 27 | } 28 | if (value == "WiFi") { 29 | networkCapabilities = NetworkCapabilities.TRANSPORT_WIFI; 30 | } 31 | else if (value == "Cell") { 32 | networkCapabilities = NetworkCapabilities.TRANSPORT_CELLULAR; 33 | } 34 | 35 | networkCallback = 36 | new ConnectivityManager.NetworkCallback() { 37 | @Override 38 | public void onAvailable(Network network) { 39 | Log.d(TAG, "Network available."); 40 | } 41 | }; 42 | NetworkRequest request = new NetworkRequest.Builder() 43 | .addTransportType(networkCapabilities) 44 | .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 45 | .build(); 46 | mConnectivityManager.requestNetwork(request, networkCallback); 47 | } 48 | 49 | public NetEnabler() { 50 | super("MyIntentService"); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Primary/src/main/java/edu/robustnet/xiao/mpbondpri/util/Pipe.java: -------------------------------------------------------------------------------- 1 | package edu.robustnet.xiao.mpbondpri.util; 2 | 3 | public class Pipe { 4 | 5 | public native String pipeSetupFromJNI(boolean isTether, int n, boolean isJava, String remoteIP, String rpIP); 6 | 7 | static { 8 | System.loadLibrary("proxy"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Primary/src/main/java/edu/robustnet/xiao/mpbondpri/util/PipeMsg.java: -------------------------------------------------------------------------------- 1 | package edu.robustnet.xiao.mpbondpri.util; 2 | 3 | public class PipeMsg { 4 | 5 | private byte[] data; 6 | 7 | public byte[] getData(){ 8 | return data; 9 | } 10 | 11 | public void setData(byte [] data){ 12 | this.data = data; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /Primary/src/main/java/edu/robustnet/xiao/mpbondpri/util/Subflow.java: -------------------------------------------------------------------------------- 1 | package edu.robustnet.xiao.mpbondpri.util; 2 | 3 | public class Subflow { 4 | 5 | private static final String TAG = "Subflow"; 6 | 7 | public native String subflowFromJNI(String rpIP, int feedbackType); 8 | static { 9 | System.loadLibrary("proxy"); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/Authenticator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp; 17 | 18 | import java.io.IOException; 19 | import javax.annotation.Nullable; 20 | 21 | /** 22 | * Responds to an authentication challenge from either a remote web server or a proxy server. 23 | * Implementations may either attempt to satisfy the challenge by returning a request that includes 24 | * an authorization header, or they may refuse the challenge by returning null. In this case the 25 | * unauthenticated response will be returned to the caller that triggered it. 26 | * 27 | *

Implementations should check if the initial request already included an attempt to 28 | * authenticate. If so it is likely that further attempts will not be useful and the authenticator 29 | * should give up. 30 | * 31 | *

When authentication is requested by an origin server, the response code is 401 and the 32 | * implementation should respond with a new request that sets the "Authorization" header. 33 | *

   {@code
34 |  *
35 |  *    if (response.request().header("Authorization") != null) {
36 |  *      return null; // Give up, we've already failed to authenticate.
37 |  *    }
38 |  *
39 |  *    String credential = Credentials.basic(...)
40 |  *    return response.request().newBuilder()
41 |  *        .header("Authorization", credential)
42 |  *        .build();
43 |  * }
44 | * 45 | *

When authentication is requested by a proxy server, the response code is 407 and the 46 | * implementation should respond with a new request that sets the "Proxy-Authorization" header. 47 | *

   {@code
48 |  *
49 |  *    if (response.request().header("Proxy-Authorization") != null) {
50 |  *      return null; // Give up, we've already failed to authenticate.
51 |  *    }
52 |  *
53 |  *    String credential = Credentials.basic(...)
54 |  *    return response.request().newBuilder()
55 |  *        .header("Proxy-Authorization", credential)
56 |  *        .build();
57 |  * }
58 | * 59 | *

Applications may configure OkHttp with an authenticator for origin servers, or proxy servers, 60 | * or both. 61 | */ 62 | public interface Authenticator { 63 | /** An authenticator that knows no credentials and makes no attempt to authenticate. */ 64 | Authenticator NONE = new Authenticator() { 65 | @Override public Request authenticate(Route route, Response response) { 66 | return null; 67 | } 68 | }; 69 | 70 | /** 71 | * Returns a request that includes a credential to satisfy an authentication challenge in {@code 72 | * response}. Returns null if the challenge cannot be satisfied. 73 | */ 74 | @Nullable Request authenticate(Route route, Response response) throws IOException; 75 | } 76 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/Callback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp; 17 | 18 | import java.io.IOException; 19 | 20 | public interface Callback { 21 | /** 22 | * Called when the request could not be executed due to cancellation, a connectivity problem or 23 | * timeout. Because networks can fail during an exchange, it is possible that the remote server 24 | * accepted the request before the failure. 25 | */ 26 | void onFailure(Call call, IOException e); 27 | 28 | /** 29 | * Called when the HTTP response was successfully returned by the remote server. The callback may 30 | * proceed to read the response body with {@link Response#body}. The response is still live until 31 | * its response body is {@linkplain ResponseBody closed}. The recipient of the callback may 32 | * consume the response body on another thread. 33 | * 34 | *

Note that transport-layer success (receiving a HTTP response code, headers and body) does 35 | * not necessarily indicate application-layer success: {@code response} may still indicate an 36 | * unhappy HTTP response code like 404 or 500. 37 | */ 38 | void onResponse(Call call, Response response) throws IOException; 39 | } 40 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/Challenge.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp; 17 | 18 | import java.nio.charset.Charset; 19 | import javax.annotation.Nullable; 20 | 21 | import static myokhttp.internal.Util.ISO_8859_1; 22 | 23 | /** An RFC 7617 challenge. */ 24 | public final class Challenge { 25 | private final String scheme; 26 | private final String realm; 27 | private final Charset charset; 28 | 29 | public Challenge(String scheme, String realm) { 30 | this(scheme, realm, ISO_8859_1); 31 | } 32 | 33 | private Challenge(String scheme, String realm, Charset charset) { 34 | if (scheme == null) throw new NullPointerException("scheme == null"); 35 | if (realm == null) throw new NullPointerException("realm == null"); 36 | if (charset == null) throw new NullPointerException("charset == null"); 37 | this.scheme = scheme; 38 | this.realm = realm; 39 | this.charset = charset; 40 | } 41 | 42 | /** Returns a copy of this charset that expects a credential encoded with {@code charset}. */ 43 | public Challenge withCharset(Charset charset) { 44 | return new Challenge(scheme, realm, charset); 45 | } 46 | 47 | /** Returns the authentication scheme, like {@code Basic}. */ 48 | public String scheme() { 49 | return scheme; 50 | } 51 | 52 | /** Returns the protection space. */ 53 | public String realm() { 54 | return realm; 55 | } 56 | 57 | /** Returns the charset that should be used to encode the credential. */ 58 | public Charset charset() { 59 | return charset; 60 | } 61 | 62 | @Override public boolean equals(@Nullable Object other) { 63 | return other instanceof Challenge 64 | && ((Challenge) other).scheme.equals(scheme) 65 | && ((Challenge) other).realm.equals(realm) 66 | && ((Challenge) other).charset.equals(charset); 67 | } 68 | 69 | @Override public int hashCode() { 70 | int result = 29; 71 | result = 31 * result + realm.hashCode(); 72 | result = 31 * result + scheme.hashCode(); 73 | result = 31 * result + charset.hashCode(); 74 | return result; 75 | } 76 | 77 | @Override public String toString() { 78 | return scheme 79 | + " realm=\"" + realm + "\"" 80 | + " charset=\"" + charset + "\""; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/CookieJar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp; 17 | 18 | import java.util.Collections; 19 | import java.util.List; 20 | 21 | /** 22 | * Provides policy and persistence for HTTP cookies. 23 | * 24 | *

As policy, implementations of this interface are responsible for selecting which cookies to 25 | * accept and which to reject. A reasonable policy is to reject all cookies, though that may 26 | * interfere with session-based authentication schemes that require cookies. 27 | * 28 | *

As persistence, implementations of this interface must also provide storage of cookies. Simple 29 | * implementations may store cookies in memory; sophisticated ones may use the file system or 30 | * database to hold accepted cookies. The cookie storage model specifies 32 | * policies for updating and expiring cookies. 33 | */ 34 | public interface CookieJar { 35 | /** A cookie jar that never accepts any cookies. */ 36 | CookieJar NO_COOKIES = new CookieJar() { 37 | @Override public void saveFromResponse(HttpUrl url, List cookies) { 38 | } 39 | 40 | @Override public List loadForRequest(HttpUrl url) { 41 | return Collections.emptyList(); 42 | } 43 | }; 44 | 45 | /** 46 | * Saves {@code cookies} from an HTTP response to this store according to this jar's policy. 47 | * 48 | *

Note that this method may be called a second time for a single HTTP response if the response 49 | * includes a trailer. For this obscure HTTP feature, {@code cookies} contains only the trailer's 50 | * cookies. 51 | */ 52 | void saveFromResponse(HttpUrl url, List cookies); 53 | 54 | /** 55 | * Load cookies from the jar for an HTTP request to {@code url}. This method returns a possibly 56 | * empty list of cookies for the network request. 57 | * 58 | *

Simple implementations will return the accepted cookies that have not yet expired and that 59 | * {@linkplain Cookie#matches match} {@code url}. 60 | */ 61 | List loadForRequest(HttpUrl url); 62 | } 63 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/Credentials.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp; 17 | 18 | import java.nio.charset.Charset; 19 | import okio.ByteString; 20 | 21 | import static myokhttp.internal.Util.ISO_8859_1; 22 | 23 | /** Factory for HTTP authorization credentials. */ 24 | public final class Credentials { 25 | private Credentials() { 26 | } 27 | 28 | /** Returns an auth credential for the Basic scheme. */ 29 | public static String basic(String userName, String password) { 30 | return basic(userName, password, ISO_8859_1); 31 | } 32 | 33 | public static String basic(String userName, String password, Charset charset) { 34 | String usernameAndPassword = userName + ":" + password; 35 | String encoded = ByteString.encodeString(usernameAndPassword, charset).base64(); 36 | return "Basic " + encoded; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/Dns.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp; 17 | 18 | import java.net.InetAddress; 19 | import java.net.UnknownHostException; 20 | import java.util.Arrays; 21 | import java.util.List; 22 | 23 | /** 24 | * A domain name service that resolves IP addresses for host names. Most applications will use the 25 | * {@linkplain #SYSTEM system DNS service}, which is the default. Some applications may provide 26 | * their own implementation to use a different DNS server, to prefer IPv6 addresses, to prefer IPv4 27 | * addresses, or to force a specific known IP address. 28 | * 29 | *

Implementations of this interface must be safe for concurrent use. 30 | */ 31 | public interface Dns { 32 | /** 33 | * A DNS that uses {@link InetAddress#getAllByName} to ask the underlying operating system to 34 | * lookup IP addresses. Most custom {@link Dns} implementations should delegate to this instance. 35 | */ 36 | Dns SYSTEM = new Dns() { 37 | @Override public List lookup(String hostname) throws UnknownHostException { 38 | if (hostname == null) throw new UnknownHostException("hostname == null"); 39 | try { 40 | return Arrays.asList(InetAddress.getAllByName(hostname)); 41 | } catch (NullPointerException e) { 42 | UnknownHostException unknownHostException = 43 | new UnknownHostException("Broken system behaviour for dns lookup of " + hostname); 44 | unknownHostException.initCause(e); 45 | throw unknownHostException; 46 | } 47 | } 48 | }; 49 | 50 | /** 51 | * Returns the IP addresses of {@code hostname}, in the order they will be attempted by OkHttp. If 52 | * a connection to an address fails, OkHttp will retry the connection with the next address until 53 | * either a connection is made, the set of IP addresses is exhausted, or a limit is exceeded. 54 | */ 55 | List lookup(String hostname) throws UnknownHostException; 56 | } 57 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/Interceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp; 17 | 18 | import java.io.IOException; 19 | import java.util.concurrent.TimeUnit; 20 | import javax.annotation.Nullable; 21 | 22 | /** 23 | * Observes, modifies, and potentially short-circuits requests going out and the corresponding 24 | * responses coming back in. Typically interceptors add, remove, or transform headers on the request 25 | * or response. 26 | */ 27 | public interface Interceptor { 28 | Response intercept(Chain chain) throws IOException; 29 | 30 | interface Chain { 31 | Request request(); 32 | 33 | Response proceed(Request request) throws IOException; 34 | 35 | /** 36 | * Returns the connection the request will be executed on. This is only available in the chains 37 | * of network interceptors; for application interceptors this is always null. 38 | */ 39 | @Nullable Connection connection(); 40 | 41 | Call call(); 42 | 43 | int connectTimeoutMillis(); 44 | 45 | Chain withConnectTimeout(int timeout, TimeUnit unit); 46 | 47 | int readTimeoutMillis(); 48 | 49 | Chain withReadTimeout(int timeout, TimeUnit unit); 50 | 51 | int writeTimeoutMillis(); 52 | 53 | Chain withWriteTimeout(int timeout, TimeUnit unit); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/TlsVersion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp; 17 | 18 | import java.util.ArrayList; 19 | import java.util.Collections; 20 | import java.util.List; 21 | 22 | /** 23 | * Versions of TLS that can be offered when negotiating a secure socket. See {@link 24 | * javax.net.ssl.SSLSocket#setEnabledProtocols}. 25 | */ 26 | public enum TlsVersion { 27 | TLS_1_3("TLSv1.3"), // 2016. 28 | TLS_1_2("TLSv1.2"), // 2008. 29 | TLS_1_1("TLSv1.1"), // 2006. 30 | TLS_1_0("TLSv1"), // 1999. 31 | SSL_3_0("SSLv3"), // 1996. 32 | ; 33 | 34 | final String javaName; 35 | 36 | TlsVersion(String javaName) { 37 | this.javaName = javaName; 38 | } 39 | 40 | public static TlsVersion forJavaName(String javaName) { 41 | switch (javaName) { 42 | case "TLSv1.3": 43 | return TLS_1_3; 44 | case "TLSv1.2": 45 | return TLS_1_2; 46 | case "TLSv1.1": 47 | return TLS_1_1; 48 | case "TLSv1": 49 | return TLS_1_0; 50 | case "SSLv3": 51 | return SSL_3_0; 52 | } 53 | throw new IllegalArgumentException("Unexpected TLS version: " + javaName); 54 | } 55 | 56 | static List forJavaNames(String... tlsVersions) { 57 | List result = new ArrayList<>(tlsVersions.length); 58 | for (String tlsVersion : tlsVersions) { 59 | result.add(forJavaName(tlsVersion)); 60 | } 61 | return Collections.unmodifiableList(result); 62 | } 63 | 64 | public String javaName() { 65 | return javaName; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/WebSocketListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp; 17 | 18 | import javax.annotation.Nullable; 19 | import okio.ByteString; 20 | 21 | public abstract class WebSocketListener { 22 | /** 23 | * Invoked when a web socket has been accepted by the remote peer and may begin transmitting 24 | * messages. 25 | */ 26 | public void onOpen(WebSocket webSocket, Response response) { 27 | } 28 | 29 | /** Invoked when a text (type {@code 0x1}) message has been received. */ 30 | public void onMessage(WebSocket webSocket, String text) { 31 | } 32 | 33 | /** Invoked when a binary (type {@code 0x2}) message has been received. */ 34 | public void onMessage(WebSocket webSocket, ByteString bytes) { 35 | } 36 | 37 | /** 38 | * Invoked when the remote peer has indicated that no more incoming messages will be 39 | * transmitted. 40 | */ 41 | public void onClosing(WebSocket webSocket, int code, String reason) { 42 | } 43 | 44 | /** 45 | * Invoked when both peers have indicated that no more messages will be transmitted and the 46 | * connection has been successfully released. No further calls to this listener will be made. 47 | */ 48 | public void onClosed(WebSocket webSocket, int code, String reason) { 49 | } 50 | 51 | /** 52 | * Invoked when a web socket has been closed due to an error reading from or writing to the 53 | * network. Both outgoing and incoming messages may have been lost. No further calls to this 54 | * listener will be made. 55 | */ 56 | public void onFailure(WebSocket webSocket, Throwable t, @Nullable Response response) { 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/Internal.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal; 17 | 18 | import java.net.MalformedURLException; 19 | import java.net.Socket; 20 | import java.net.UnknownHostException; 21 | import javax.net.ssl.SSLSocket; 22 | import myokhttp.Address; 23 | import myokhttp.Call; 24 | import myokhttp.ConnectionPool; 25 | import myokhttp.ConnectionSpec; 26 | import myokhttp.Headers; 27 | import myokhttp.HttpUrl; 28 | import myokhttp.OkHttpClient; 29 | import myokhttp.Request; 30 | import myokhttp.Response; 31 | import myokhttp.Route; 32 | import myokhttp.internal.cache.InternalCache; 33 | import myokhttp.internal.connection.RealConnection; 34 | import myokhttp.internal.connection.RouteDatabase; 35 | import myokhttp.internal.connection.StreamAllocation; 36 | 37 | /** 38 | * Escalate internal APIs in {@code okhttp3} so they can be used from OkHttp's implementation 39 | * packages. The only implementation of this interface is in {@link OkHttpClient}. 40 | */ 41 | public abstract class Internal { 42 | 43 | public static void initializeInstanceForTests() { 44 | // Needed in tests to ensure that the instance is actually pointing to something. 45 | new OkHttpClient(); 46 | } 47 | 48 | public static Internal instance; 49 | 50 | public abstract void addLenient(Headers.Builder builder, String line); 51 | 52 | public abstract void addLenient(Headers.Builder builder, String name, String value); 53 | 54 | public abstract void setCache(OkHttpClient.Builder builder, InternalCache internalCache); 55 | 56 | public abstract RealConnection get(ConnectionPool pool, Address address, 57 | StreamAllocation streamAllocation, Route route); 58 | 59 | public abstract boolean equalsNonHost(Address a, Address b); 60 | 61 | public abstract Socket deduplicate( 62 | ConnectionPool pool, Address address, StreamAllocation streamAllocation); 63 | 64 | public abstract void put(ConnectionPool pool, RealConnection connection); 65 | 66 | public abstract boolean connectionBecameIdle(ConnectionPool pool, RealConnection connection); 67 | 68 | public abstract RouteDatabase routeDatabase(ConnectionPool connectionPool); 69 | 70 | public abstract int code(Response.Builder responseBuilder); 71 | 72 | public abstract void apply(ConnectionSpec tlsConfiguration, SSLSocket sslSocket, 73 | boolean isFallback); 74 | 75 | public abstract HttpUrl getHttpUrlChecked(String url) 76 | throws MalformedURLException, UnknownHostException; 77 | 78 | public abstract StreamAllocation streamAllocation(Call call); 79 | 80 | public abstract Call newWebSocketCall(OkHttpClient client, Request request); 81 | } 82 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/NamedRunnable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal; 17 | 18 | /** 19 | * Runnable implementation which always sets its thread name. 20 | */ 21 | public abstract class NamedRunnable implements Runnable { 22 | protected final String name; 23 | 24 | public NamedRunnable(String format, Object... args) { 25 | this.name = Util.format(format, args); 26 | } 27 | 28 | @Override public final void run() { 29 | String oldName = Thread.currentThread().getName(); 30 | Thread.currentThread().setName(name); 31 | try { 32 | execute(); 33 | } finally { 34 | Thread.currentThread().setName(oldName); 35 | } 36 | } 37 | 38 | protected abstract void execute(); 39 | } 40 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/Version.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal; 17 | 18 | public final class Version { 19 | public static String userAgent() { 20 | return "okhttp/${project.version}"; 21 | } 22 | 23 | private Version() { 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/cache/CacheRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.cache; 17 | 18 | import java.io.IOException; 19 | import okio.Sink; 20 | 21 | public interface CacheRequest { 22 | Sink body() throws IOException; 23 | 24 | void abort(); 25 | } 26 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/cache/FaultHidingSink.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.cache; 17 | 18 | import java.io.IOException; 19 | import okio.Buffer; 20 | import okio.ForwardingSink; 21 | import okio.Sink; 22 | 23 | /** A sink that never throws IOExceptions, even if the underlying sink does. */ 24 | class FaultHidingSink extends ForwardingSink { 25 | private boolean hasErrors; 26 | 27 | FaultHidingSink(Sink delegate) { 28 | super(delegate); 29 | } 30 | 31 | @Override public void write(Buffer source, long byteCount) throws IOException { 32 | if (hasErrors) { 33 | source.skip(byteCount); 34 | return; 35 | } 36 | try { 37 | super.write(source, byteCount); 38 | } catch (IOException e) { 39 | hasErrors = true; 40 | onException(e); 41 | } 42 | } 43 | 44 | @Override public void flush() throws IOException { 45 | if (hasErrors) return; 46 | try { 47 | super.flush(); 48 | } catch (IOException e) { 49 | hasErrors = true; 50 | onException(e); 51 | } 52 | } 53 | 54 | @Override public void close() throws IOException { 55 | if (hasErrors) return; 56 | try { 57 | super.close(); 58 | } catch (IOException e) { 59 | hasErrors = true; 60 | onException(e); 61 | } 62 | } 63 | 64 | protected void onException(IOException e) { 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/cache/InternalCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.cache; 17 | 18 | import java.io.IOException; 19 | import myokhttp.Request; 20 | import myokhttp.Response; 21 | 22 | /** 23 | * OkHttp's internal cache interface. Applications shouldn't implement this: instead use {@link 24 | * myokhttp.Cache}. 25 | */ 26 | public interface InternalCache { 27 | Response get(Request request) throws IOException; 28 | 29 | CacheRequest put(Response response) throws IOException; 30 | 31 | /** 32 | * Remove any cache entries for the supplied {@code request}. This is invoked when the client 33 | * invalidates the cache, such as when making POST requests. 34 | */ 35 | void remove(Request request) throws IOException; 36 | 37 | /** 38 | * Handles a conditional request hit by updating the stored cache response with the headers from 39 | * {@code network}. The cached response body is not updated. If the stored response has changed 40 | * since {@code cached} was returned, this does nothing. 41 | */ 42 | void update(Response cached, Response network); 43 | 44 | /** Track an conditional GET that was satisfied by this cache. */ 45 | void trackConditionalCacheHit(); 46 | 47 | /** Track an HTTP response being satisfied with {@code cacheStrategy}. */ 48 | void trackResponse(CacheStrategy cacheStrategy); 49 | } 50 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/connection/ConnectInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package myokhttp.internal.connection; 18 | 19 | import java.io.IOException; 20 | import myokhttp.Interceptor; 21 | import myokhttp.OkHttpClient; 22 | import myokhttp.Request; 23 | import myokhttp.Response; 24 | import myokhttp.internal.http.HttpCodec; 25 | import myokhttp.internal.http.RealInterceptorChain; 26 | 27 | /** Opens a connection to the target server and proceeds to the next interceptor. */ 28 | public final class ConnectInterceptor implements Interceptor { 29 | public final OkHttpClient client; 30 | 31 | public ConnectInterceptor(OkHttpClient client) { 32 | this.client = client; 33 | } 34 | 35 | @Override public Response intercept(Chain chain) throws IOException { 36 | RealInterceptorChain realChain = (RealInterceptorChain) chain; 37 | Request request = realChain.request(); 38 | StreamAllocation streamAllocation = realChain.streamAllocation(); 39 | 40 | // We need the network to satisfy this request. Possibly for validating a conditional GET. 41 | boolean doExtensiveHealthChecks = !request.method().equals("GET"); 42 | HttpCodec httpCodec = streamAllocation.newStream(client, chain, doExtensiveHealthChecks); 43 | RealConnection connection = streamAllocation.connection(); 44 | 45 | return realChain.proceed(request, streamAllocation, httpCodec, connection); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/connection/RouteDatabase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.connection; 17 | 18 | import java.util.LinkedHashSet; 19 | import java.util.Set; 20 | import myokhttp.Route; 21 | 22 | /** 23 | * A blacklist of failed routes to avoid when creating a new connection to a target address. This is 24 | * used so that OkHttp can learn from its mistakes: if there was a failure attempting to connect to 25 | * a specific IP address or proxy server, that failure is remembered and alternate routes are 26 | * preferred. 27 | */ 28 | public final class RouteDatabase { 29 | private final Set failedRoutes = new LinkedHashSet<>(); 30 | 31 | /** Records a failure connecting to {@code failedRoute}. */ 32 | public synchronized void failed(Route failedRoute) { 33 | failedRoutes.add(failedRoute); 34 | } 35 | 36 | /** Records success connecting to {@code route}. */ 37 | public synchronized void connected(Route route) { 38 | failedRoutes.remove(route); 39 | } 40 | 41 | /** Returns true if {@code route} has failed recently and should be avoided. */ 42 | public synchronized boolean shouldPostpone(Route route) { 43 | return failedRoutes.contains(route); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/connection/RouteException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.connection; 17 | 18 | import java.io.IOException; 19 | import java.lang.reflect.InvocationTargetException; 20 | import java.lang.reflect.Method; 21 | 22 | /** 23 | * An exception thrown to indicate a problem connecting via a single Route. Multiple attempts may 24 | * have been made with alternative protocols, none of which were successful. 25 | */ 26 | public final class RouteException extends RuntimeException { 27 | private static final Method addSuppressedExceptionMethod; 28 | 29 | static { 30 | Method m; 31 | try { 32 | m = Throwable.class.getDeclaredMethod("addSuppressed", Throwable.class); 33 | } catch (Exception e) { 34 | m = null; 35 | } 36 | addSuppressedExceptionMethod = m; 37 | } 38 | 39 | private IOException lastException; 40 | 41 | public RouteException(IOException cause) { 42 | super(cause); 43 | lastException = cause; 44 | } 45 | 46 | public IOException getLastConnectException() { 47 | return lastException; 48 | } 49 | 50 | public void addConnectException(IOException e) { 51 | addSuppressedIfPossible(e, lastException); 52 | lastException = e; 53 | } 54 | 55 | private void addSuppressedIfPossible(IOException e, IOException suppressed) { 56 | if (addSuppressedExceptionMethod != null) { 57 | try { 58 | addSuppressedExceptionMethod.invoke(e, suppressed); 59 | } catch (InvocationTargetException | IllegalAccessException ignored) { 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/http/HttpCodec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http; 17 | 18 | import java.io.IOException; 19 | import myokhttp.Request; 20 | import myokhttp.Response; 21 | import myokhttp.ResponseBody; 22 | import okio.Sink; 23 | 24 | /** Encodes HTTP requests and decodes HTTP responses. */ 25 | public interface HttpCodec { 26 | /** 27 | * The timeout to use while discarding a stream of input data. Since this is used for connection 28 | * reuse, this timeout should be significantly less than the time it takes to establish a new 29 | * connection. 30 | */ 31 | int DISCARD_STREAM_TIMEOUT_MILLIS = 100; 32 | 33 | /** Returns an output stream where the request body can be streamed. */ 34 | Sink createRequestBody(Request request, long contentLength); 35 | 36 | /** This should update the HTTP engine's sentRequestMillis field. */ 37 | void writeRequestHeaders(Request request) throws IOException; 38 | 39 | /** Flush the request to the underlying socket. */ 40 | void flushRequest() throws IOException; 41 | 42 | /** Flush the request to the underlying socket and signal no more bytes will be transmitted. */ 43 | void finishRequest() throws IOException; 44 | 45 | /** 46 | * Parses bytes of a response header from an HTTP transport. 47 | * 48 | * @param expectContinue true to return null if this is an intermediate response with a "100" 49 | * response code. Otherwise this method never returns null. 50 | */ 51 | Response.Builder readResponseHeaders(boolean expectContinue) throws IOException; 52 | 53 | /** Returns a stream that reads the response body. */ 54 | ResponseBody openResponseBody(Response response) throws IOException; 55 | 56 | /** 57 | * Cancel this stream. Resources held by this stream will be cleaned up, though not synchronously. 58 | * That may happen later by the connection pool thread. 59 | */ 60 | void cancel(); 61 | } 62 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/http/HttpMethod.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http; 17 | 18 | public final class HttpMethod { 19 | public static boolean invalidatesCache(String method) { 20 | return method.equals("POST") 21 | || method.equals("PATCH") 22 | || method.equals("PUT") 23 | || method.equals("DELETE") 24 | || method.equals("MOVE"); // WebDAV 25 | } 26 | 27 | public static boolean requiresRequestBody(String method) { 28 | return method.equals("POST") 29 | || method.equals("PUT") 30 | || method.equals("PATCH") 31 | || method.equals("PROPPATCH") // WebDAV 32 | || method.equals("REPORT"); // CalDAV/CardDAV (defined in WebDAV Versioning) 33 | } 34 | 35 | public static boolean permitsRequestBody(String method) { 36 | return requiresRequestBody(method) 37 | || method.equals("OPTIONS") 38 | || method.equals("DELETE") // Permitted as spec is ambiguous. 39 | || method.equals("PROPFIND") // (WebDAV) without body: request 40 | || method.equals("MKCOL") // (WebDAV) may contain a body, but behaviour is unspecified 41 | || method.equals("LOCK"); // (WebDAV) body: create lock, without body: refresh lock 42 | } 43 | 44 | public static boolean redirectsWithBody(String method) { 45 | return method.equals("PROPFIND"); // (WebDAV) redirects should also maintain the request body 46 | } 47 | 48 | public static boolean redirectsToGet(String method) { 49 | // All requests but PROPFIND should redirect to a GET request. 50 | return !method.equals("PROPFIND"); 51 | } 52 | 53 | private HttpMethod() { 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/http/RealResponseBody.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http; 17 | 18 | import javax.annotation.Nullable; 19 | import myokhttp.MediaType; 20 | import myokhttp.ResponseBody; 21 | import okio.BufferedSource; 22 | 23 | public final class RealResponseBody extends ResponseBody { 24 | /** 25 | * Use a string to avoid parsing the content type until needed. This also defers problems caused 26 | * by malformed content types. 27 | */ 28 | private final @Nullable String contentTypeString; 29 | private final long contentLength; 30 | private final BufferedSource source; 31 | 32 | public RealResponseBody( 33 | @Nullable String contentTypeString, long contentLength, BufferedSource source) { 34 | this.contentTypeString = contentTypeString; 35 | this.contentLength = contentLength; 36 | this.source = source; 37 | } 38 | 39 | @Override public MediaType contentType() { 40 | return contentTypeString != null ? MediaType.parse(contentTypeString) : null; 41 | } 42 | 43 | @Override public long contentLength() { 44 | return contentLength; 45 | } 46 | 47 | @Override public BufferedSource source() { 48 | return source; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/http/RequestLine.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http; 17 | 18 | import java.net.HttpURLConnection; 19 | import java.net.Proxy; 20 | import myokhttp.HttpUrl; 21 | import myokhttp.Request; 22 | 23 | public final class RequestLine { 24 | private RequestLine() { 25 | } 26 | 27 | /** 28 | * Returns the request status line, like "GET / HTTP/1.1". This is exposed to the application by 29 | * {@link HttpURLConnection#getHeaderFields}, so it needs to be set even if the transport is 30 | * HTTP/2. 31 | */ 32 | public static String get(Request request, Proxy.Type proxyType) { 33 | StringBuilder result = new StringBuilder(); 34 | result.append(request.method()); 35 | result.append(' '); 36 | 37 | if (includeAuthorityInRequestLine(request, proxyType)) { 38 | result.append(request.url()); 39 | } else { 40 | result.append(requestPath(request.url())); 41 | } 42 | 43 | result.append(" HTTP/1.1"); 44 | return result.toString(); 45 | } 46 | 47 | /** 48 | * Returns true if the request line should contain the full URL with host and port (like "GET 49 | * http://android.com/foo HTTP/1.1") or only the path (like "GET /foo HTTP/1.1"). 50 | */ 51 | private static boolean includeAuthorityInRequestLine(Request request, Proxy.Type proxyType) { 52 | return !request.isHttps() && proxyType == Proxy.Type.HTTP; 53 | } 54 | 55 | /** 56 | * Returns the path to request, like the '/' in 'GET / HTTP/1.1'. Never empty, even if the request 57 | * URL is. Includes the query component if it exists. 58 | */ 59 | public static String requestPath(HttpUrl url) { 60 | String path = url.encodedPath(); 61 | String query = url.encodedQuery(); 62 | return query != null ? (path + '?' + query) : path; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/http/UnrepeatableRequestBody.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http; 17 | 18 | public interface UnrepeatableRequestBody { 19 | } 20 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/http2/ConnectionShutdownException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http2; 17 | 18 | import java.io.IOException; 19 | 20 | /** 21 | * Thrown when an HTTP/2 connection is shutdown (either explicitly or if the peer has sent a GOAWAY 22 | * frame) and an attempt is made to use the connection. 23 | */ 24 | public final class ConnectionShutdownException extends IOException { 25 | } 26 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/http2/ErrorCode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http2; 17 | 18 | // http://tools.ietf.org/html/draft-ietf-httpbis-http2-17#section-7 19 | public enum ErrorCode { 20 | /** Not an error! */ 21 | NO_ERROR(0), 22 | 23 | PROTOCOL_ERROR(1), 24 | 25 | INTERNAL_ERROR(2), 26 | 27 | FLOW_CONTROL_ERROR(3), 28 | 29 | REFUSED_STREAM(7), 30 | 31 | CANCEL(8); 32 | 33 | public final int httpCode; 34 | 35 | ErrorCode(int httpCode) { 36 | this.httpCode = httpCode; 37 | } 38 | 39 | public static ErrorCode fromHttp2(int code) { 40 | for (ErrorCode errorCode : ErrorCode.values()) { 41 | if (errorCode.httpCode == code) return errorCode; 42 | } 43 | return null; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/http2/Header.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http2; 17 | 18 | import myokhttp.internal.Util; 19 | import okio.ByteString; 20 | 21 | /** HTTP header: the name is an ASCII string, but the value can be UTF-8. */ 22 | public final class Header { 23 | // Special header names defined in HTTP/2 spec. 24 | public static final ByteString PSEUDO_PREFIX = ByteString.encodeUtf8(":"); 25 | public static final ByteString RESPONSE_STATUS = ByteString.encodeUtf8(":status"); 26 | public static final ByteString TARGET_METHOD = ByteString.encodeUtf8(":method"); 27 | public static final ByteString TARGET_PATH = ByteString.encodeUtf8(":path"); 28 | public static final ByteString TARGET_SCHEME = ByteString.encodeUtf8(":scheme"); 29 | public static final ByteString TARGET_AUTHORITY = ByteString.encodeUtf8(":authority"); 30 | 31 | /** Name in case-insensitive ASCII encoding. */ 32 | public final ByteString name; 33 | /** Value in UTF-8 encoding. */ 34 | public final ByteString value; 35 | final int hpackSize; 36 | 37 | // TODO: search for toLowerCase and consider moving logic here. 38 | public Header(String name, String value) { 39 | this(ByteString.encodeUtf8(name), ByteString.encodeUtf8(value)); 40 | } 41 | 42 | public Header(ByteString name, String value) { 43 | this(name, ByteString.encodeUtf8(value)); 44 | } 45 | 46 | public Header(ByteString name, ByteString value) { 47 | this.name = name; 48 | this.value = value; 49 | this.hpackSize = 32 + name.size() + value.size(); 50 | } 51 | 52 | @Override public boolean equals(Object other) { 53 | if (other instanceof Header) { 54 | Header that = (Header) other; 55 | return this.name.equals(that.name) 56 | && this.value.equals(that.value); 57 | } 58 | return false; 59 | } 60 | 61 | @Override public int hashCode() { 62 | int result = 17; 63 | result = 31 * result + name.hashCode(); 64 | result = 31 * result + value.hashCode(); 65 | return result; 66 | } 67 | 68 | @Override public String toString() { 69 | return Util.format("%s: %s", name.utf8(), value.utf8()); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/http2/Ping.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http2; 17 | 18 | import java.util.concurrent.CountDownLatch; 19 | import java.util.concurrent.TimeUnit; 20 | 21 | /** 22 | * A locally-originated ping. 23 | */ 24 | public final class Ping { 25 | private final CountDownLatch latch = new CountDownLatch(1); 26 | private long sent = -1; 27 | private long received = -1; 28 | 29 | Ping() { 30 | } 31 | 32 | void send() { 33 | if (sent != -1) throw new IllegalStateException(); 34 | sent = System.nanoTime(); 35 | } 36 | 37 | void receive() { 38 | if (received != -1 || sent == -1) throw new IllegalStateException(); 39 | received = System.nanoTime(); 40 | latch.countDown(); 41 | } 42 | 43 | void cancel() { 44 | if (received != -1 || sent == -1) throw new IllegalStateException(); 45 | received = sent - 1; 46 | latch.countDown(); 47 | } 48 | 49 | /** 50 | * Returns the round trip time for this ping in nanoseconds, waiting for the response to arrive if 51 | * necessary. Returns -1 if the response was canceled. 52 | */ 53 | public long roundTripTime() throws InterruptedException { 54 | latch.await(); 55 | return received - sent; 56 | } 57 | 58 | /** 59 | * Returns the round trip time for this ping in nanoseconds, or -1 if the response was canceled, 60 | * or -2 if the timeout elapsed before the round trip completed. 61 | */ 62 | public long roundTripTime(long timeout, TimeUnit unit) throws InterruptedException { 63 | if (latch.await(timeout, unit)) { 64 | return received - sent; 65 | } else { 66 | return -2; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/http2/StreamResetException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.http2; 17 | 18 | import java.io.IOException; 19 | 20 | /** Thrown when an HTTP/2 stream is canceled without damage to the socket that carries it. */ 21 | public final class StreamResetException extends IOException { 22 | public final ErrorCode errorCode; 23 | 24 | public StreamResetException(ErrorCode errorCode) { 25 | super("stream was reset: " + errorCode); 26 | this.errorCode = errorCode; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/tls/BasicTrustRootIndex.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.tls; 17 | 18 | import java.security.PublicKey; 19 | import java.security.cert.X509Certificate; 20 | import java.util.LinkedHashMap; 21 | import java.util.LinkedHashSet; 22 | import java.util.Map; 23 | import java.util.Set; 24 | import javax.security.auth.x500.X500Principal; 25 | 26 | /** A simple index that of trusted root certificates that have been loaded into memory. */ 27 | public final class BasicTrustRootIndex implements TrustRootIndex { 28 | private final Map> subjectToCaCerts; 29 | 30 | public BasicTrustRootIndex(X509Certificate... caCerts) { 31 | subjectToCaCerts = new LinkedHashMap<>(); 32 | for (X509Certificate caCert : caCerts) { 33 | X500Principal subject = caCert.getSubjectX500Principal(); 34 | Set subjectCaCerts = subjectToCaCerts.get(subject); 35 | if (subjectCaCerts == null) { 36 | subjectCaCerts = new LinkedHashSet<>(1); 37 | subjectToCaCerts.put(subject, subjectCaCerts); 38 | } 39 | subjectCaCerts.add(caCert); 40 | } 41 | } 42 | 43 | @Override public X509Certificate findByIssuerAndSignature(X509Certificate cert) { 44 | X500Principal issuer = cert.getIssuerX500Principal(); 45 | Set subjectCaCerts = subjectToCaCerts.get(issuer); 46 | if (subjectCaCerts == null) return null; 47 | 48 | for (X509Certificate caCert : subjectCaCerts) { 49 | PublicKey publicKey = caCert.getPublicKey(); 50 | try { 51 | cert.verify(publicKey); 52 | return caCert; 53 | } catch (Exception ignored) { 54 | } 55 | } 56 | 57 | return null; 58 | } 59 | 60 | @Override public boolean equals(Object other) { 61 | if (other == this) return true; 62 | return other instanceof myokhttp.internal.tls.BasicTrustRootIndex 63 | && ((myokhttp.internal.tls.BasicTrustRootIndex) other).subjectToCaCerts.equals( 64 | subjectToCaCerts); 65 | } 66 | 67 | @Override public int hashCode() { 68 | return subjectToCaCerts.hashCode(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/tls/CertificateChainCleaner.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package myokhttp.internal.tls; 18 | 19 | import java.security.cert.Certificate; 20 | import java.security.cert.X509Certificate; 21 | import java.util.List; 22 | import javax.net.ssl.SSLPeerUnverifiedException; 23 | import javax.net.ssl.X509TrustManager; 24 | import myokhttp.internal.platform.Platform; 25 | 26 | /** 27 | * Computes the effective certificate chain from the raw array returned by Java's built in TLS APIs. 28 | * Cleaning a chain returns a list of certificates where the first element is {@code chain[0]}, each 29 | * certificate is signed by the certificate that follows, and the last certificate is a trusted CA 30 | * certificate. 31 | * 32 | *

Use of the chain cleaner is necessary to omit unexpected certificates that aren't relevant to 33 | * the TLS handshake and to extract the trusted CA certificate for the benefit of certificate 34 | * pinning. 35 | */ 36 | public abstract class CertificateChainCleaner { 37 | public abstract List clean(List chain, String hostname) 38 | throws SSLPeerUnverifiedException; 39 | 40 | public static CertificateChainCleaner get(X509TrustManager trustManager) { 41 | return Platform.get().buildCertificateChainCleaner(trustManager); 42 | } 43 | 44 | public static CertificateChainCleaner get(X509Certificate... caCerts) { 45 | return new BasicCertificateChainCleaner(new BasicTrustRootIndex(caCerts)); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/internal/tls/TrustRootIndex.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package myokhttp.internal.tls; 17 | 18 | import java.security.cert.X509Certificate; 19 | 20 | public interface TrustRootIndex { 21 | /** Returns the trusted CA certificate that signed {@code cert}. */ 22 | X509Certificate findByIssuerAndSignature(X509Certificate cert); 23 | } 24 | -------------------------------------------------------------------------------- /Primary/src/main/java/myokhttp/package-info.java: -------------------------------------------------------------------------------- 1 | /** An HTTP+HTTP/2 client for Android and Java applications. */ 2 | @javax.annotation.ParametersAreNonnullByDefault 3 | package myokhttp; 4 | -------------------------------------------------------------------------------- /Primary/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /Primary/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Primary/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Primary/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Primary/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Primary/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Primary/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /Primary/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Primary/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Primary/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Primary/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Primary/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Primary/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /Primary/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Primary/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Primary/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Primary/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Primary/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Primary/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /Primary/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Primary/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Primary/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Primary/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Primary/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Primary/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /Primary/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Primary/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Primary/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Primary/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Primary/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Primary/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /Primary/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/Primary/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Primary/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /Primary/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #26A69A 4 | -------------------------------------------------------------------------------- /Primary/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | DMM 3 | 4 | -------------------------------------------------------------------------------- /Primary/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Primary/src/main/res/xml/network_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Primary/src/test/java/edu/robustnet/xiao/mpbondpri/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package edu.robustnet.xiao.mpbondpri; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MPBond 2 | 3 |

4 | 5 |                       6 | 7 |
8 | 9 | ## Introduction 10 | MPBond is an efficient system allowing multiple personal mobile devices to collaboratively fetch content from the Internet, used in our MobiSys'20 paper: [**MPBond: Efficient Network-level Collaboration Among Personal Mobile Devices**](https://xiaoshawnzhu.github.io/mobisys20-mpbond.pdf). 11 | 12 | MPBond consists of primary, helper and proxy parts. 13 | 14 | When you use MPBond in any publications, please refer our work in the following format. 15 | ``` 16 | Xiao Zhu, Jiachen Sun, Xumiao Zhang, Yihua Ethan Guo, Feng Qian, and Z.Morley Mao. 17 | 2020. MPBond: Efficient Network-level Collaboration Among Personal Mobile Devices. 18 | In The 18th Annual International Conference on Mobile Systems, Applications, and Services (MobiSys ’20), ACM. 19 | ``` 20 | 21 | If you have any questions about how to use the code, please contact me (shawnzhu@umich.edu). -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | buildscript { 3 | 4 | repositories { 5 | google() 6 | jcenter() 7 | } 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.2.1' 10 | 11 | // NOTE: Do not place your application dependencies here; they belong 12 | // in the individual module build.gradle files 13 | } 14 | } 15 | allprojects { 16 | repositories { 17 | google() 18 | jcenter() 19 | } 20 | } 21 | task clean(type: Delete) { 22 | delete rootProject.buildDir 23 | } 24 | 25 | dependencies { 26 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | android.enableJetifier=true 11 | android.useAndroidX=true 12 | # When configured, Gradle will run in incubating parallel mode. 13 | # This option should only be used with decoupled projects. More details, visit 14 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 15 | # org.gradle.parallel=true 16 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoShawnZhu/MPBond/047bc762512ec53725257bcb2e119c4ae3219ea2/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Dec 26 21:43:43 EST 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /server/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += ss.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules 5 | g++ -O3 -Wall -Wno-write-strings -o ./dmm_proxy connections.cpp hints.cpp kernel_info.cpp meta_buffer.cpp \ 6 | subflows.cpp proxy.cpp proxy_setting.cpp scheduler.cpp Storage.cpp tools.cpp -lpthread -lpcap 7 | echo "Build finish." 8 | 9 | clean: 10 | make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean 11 | rm ./dmm_proxy 12 | -------------------------------------------------------------------------------- /server/Storage.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "Storage.h" 4 | #include "tools.h" 5 | 6 | STORAGE::STORAGE() { 7 | maxSize = 32768; 8 | pData = new BYTE[maxSize]; 9 | size = 0; 10 | } 11 | 12 | STORAGE::~STORAGE() { 13 | delete [] pData; 14 | pData = NULL; 15 | } 16 | 17 | void STORAGE::Clear() { 18 | size = 0; 19 | } 20 | 21 | BYTE * STORAGE::GetDataAt(int offset) { 22 | MyAssert(offset < size, 6); 23 | return pData + offset; 24 | } 25 | 26 | int STORAGE::PushData(const BYTE * pData, int size) { 27 | MyAssert(size != 0, 8); 28 | 29 | if (this->size + size >= maxSize) { 30 | int newMaxSize = (this->size + size) * 2; 31 | BYTE * pNewData = new BYTE[newMaxSize]; 32 | memcpy(pNewData, this->pData, this->size); 33 | maxSize = newMaxSize; 34 | delete [] this->pData; 35 | this->pData = pNewData; 36 | } 37 | 38 | int r = this->size; 39 | 40 | memcpy(this->pData + this->size, pData, size); 41 | this->size += size; 42 | 43 | return r; 44 | } 45 | 46 | 47 | int STORAGE::PushData(BYTE data) { 48 | BYTE b[1]; 49 | b[0] = data; 50 | return PushData(b, 1); 51 | } 52 | 53 | int STORAGE::PushData(STORAGE & s) { 54 | return PushData(s.GetDataAt(0), s.GetSize()); 55 | } 56 | 57 | char * STORAGE::GetString() { 58 | *(pData + size) = 0; 59 | return (char *)pData; 60 | } 61 | 62 | void STORAGE::SetString(const char * str) { 63 | Clear(); 64 | PushData((const BYTE *)str, strlen(str)); 65 | PushData(0); 66 | } 67 | 68 | int STORAGE::SetData(STORAGE & s) { 69 | Clear(); 70 | return PushData(s); 71 | } 72 | 73 | int STORAGE::SetData(const BYTE * pData, int size) { 74 | Clear(); 75 | return PushData(pData, size); 76 | } 77 | 78 | void STORAGE::ShrinkBy(int size) { 79 | this->size -= size; 80 | MyAssert(this->size >=0, 1317); 81 | if (this->size < 0) this->size = 0; 82 | } 83 | -------------------------------------------------------------------------------- /server/Storage.h: -------------------------------------------------------------------------------- 1 | #ifndef _STORAGE_H_ 2 | #define _STORAGE_H_ 3 | 4 | #include "proxy.h" 5 | 6 | class STORAGE { 7 | public: 8 | void Clear(); 9 | int PushData(const BYTE * pData, int size); 10 | int PushData(BYTE data); 11 | int PushData(STORAGE & s); 12 | //int PushDataEx(const BYTE * pData, int size, int pktID); 13 | 14 | void ShrinkBy(int size); 15 | 16 | int SetData(const BYTE * pData, int size); 17 | int SetData(STORAGE & s); 18 | 19 | BYTE * GetDataAt(int offset); 20 | int GetSize() {return size;} 21 | //const char * GetPrintableText(); 22 | //const char * GetPrintableText(int ofsBegin, int ofsEnd); 23 | 24 | //int ReadFromFile(const char * filename); 25 | //int WriteToFile(FILE * ofs); 26 | char * GetString(); 27 | void SetString(const char * str); 28 | 29 | STORAGE(); 30 | ~STORAGE(); 31 | 32 | private: 33 | BYTE * pData; 34 | int size; 35 | int maxSize; 36 | }; 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /server/hints.cpp: -------------------------------------------------------------------------------- 1 | #include "hints.h" 2 | #include "scheduler.h" 3 | #include "tools.h" 4 | 5 | int HINT_ENTRY::matchEntry(DWORD serverIP, WORD serverPort) { 6 | if (this->serverIP >> (32-ipPrefix) == serverIP >> (32-ipPrefix) 7 | && this->serverPort == serverPort) 8 | return 1; 9 | return 0; 10 | } 11 | 12 | DWORD HINT_ENTRY::getHints() { 13 | DWORD value = 0; 14 | value += ((DWORD) sched << 24); 15 | value += ((DWORD) timeType << 22); 16 | value += ((DWORD) timeValue << 16); 17 | value += ((DWORD) energyType << 14); 18 | value += ((DWORD) energyValue << 8); 19 | value += ((DWORD) dataType << 6); 20 | value += ((DWORD) dataValue); 21 | return value; 22 | } 23 | 24 | void HINT_ENTRY::decodeEntry(DWORD hints) { 25 | dataValue = int(hints & 0x3F); 26 | hints >>= 6; 27 | dataType = int(hints & 0x3); 28 | hints >>= 2; 29 | energyValue = int(hints & 0x3F); 30 | hints >>= 6; 31 | energyType = int(hints & 0x3); 32 | hints >>= 2; 33 | timeValue = int(hints & 0x3F); 34 | hints >>= 6; 35 | timeType = int(hints & 0x3); 36 | hints >>= 2; 37 | sched = int(hints & 0xFF); 38 | } 39 | 40 | void HINT_ENTRY::print() { 41 | // InfoMessage("[Hints] Sched/traffic: %s [%d]; Time: %d/%d; Energy: %d/%d; Data: %d/%d.", 42 | // SCHEDULER::getSchedulerName(sched), sched, 43 | // timeType, timeValue, energyType, energyValue, dataType, dataValue); 44 | } 45 | 46 | 47 | DWORD HINTS::getHints(DWORD serverIP, WORD serverPort) { 48 | DWORD value = 0xFFFFFFFF; 49 | for (int i = 0; i <= maxHint; i++) { 50 | if (entries[i].matchEntry(serverIP, serverPort)) { 51 | value = entries[i].getHints(); 52 | break; 53 | } 54 | } 55 | return value; 56 | } 57 | 58 | 59 | -------------------------------------------------------------------------------- /server/hints.h: -------------------------------------------------------------------------------- 1 | #ifndef _HINTS_H_ 2 | #define _HINTS_H_ 3 | 4 | #include "proxy.h" 5 | 6 | #define MAX_HINT 100 7 | 8 | struct HINT_ENTRY { 9 | DWORD serverIP; 10 | int ipPrefix; 11 | WORD serverPort; 12 | 13 | int sched; // 8 bit 14 | int timeType, timeValue; // 2 bit + 6 bit 15 | int energyType, energyValue; // 2 bit + 6 bit 16 | int dataType, dataValue; // 2 bit + 6 bit 17 | 18 | int matchEntry(DWORD serverIP, WORD serverPort); 19 | DWORD getHints(); 20 | void decodeEntry(DWORD hints); 21 | void print(); 22 | }; 23 | 24 | struct HINTS { 25 | int maxHint; 26 | HINT_ENTRY entries[MAX_HINT]; 27 | DWORD getHints(DWORD serverIP, WORD serverPort); 28 | }; 29 | 30 | #endif -------------------------------------------------------------------------------- /server/kernel_info.h: -------------------------------------------------------------------------------- 1 | #ifndef _KERNEL_INFO_H_ 2 | #define _KERNEL_INFO_H_ 3 | 4 | #include "proxy_setting.h" 5 | 6 | #define TCP_CC_CUBIC 1 7 | #define TCP_CC_BBR 2 8 | 9 | struct OWD_ENTRY { 10 | // support up to 10MB bif 11 | int owd[1024]; // unit ms * 10, index: index * 10KB ~ (index+1) * 10KB --> owd 12 | int var[1024]; 13 | int valid[1024]; 14 | 15 | int subflowNo; 16 | 17 | double tmp_var; 18 | 19 | int isOWD; 20 | 21 | void Setup(int no); 22 | int BifToIndex(int bif); // bif in bytes 23 | void AddSample(int bif, int owd_sample); // bif in bytes, owd in ms * 10 24 | double GetOWD(int bif); 25 | double GetVar(); 26 | void PrintMapping(); 27 | //double PostProcessVar(double value); 28 | }; 29 | 30 | struct OWD_MAPPING { 31 | struct OWD_ENTRY mapping[3]; // for subflow 1,2 32 | 33 | double tmp_var; 34 | double owd_var_default; 35 | 36 | void Setup(); 37 | 38 | double PostProcessVar(double value); 39 | void AddSample(int subflowNo, int bif, int owd_sample); 40 | 41 | double GetOWDDiff(int bif1, int bif2); 42 | double GetOWDDiffVar(); 43 | void PrintMapping(); 44 | }; 45 | 46 | struct KERNEL_INFO { 47 | struct tcp_info subflowinfo[MAX_SUBFLOWS]; 48 | struct OWD_MAPPING owdMapping; 49 | int space[MAX_SUBFLOWS]; 50 | //int owd_value, owd_var; // note: these are actual value * 10 51 | //int owd_default, owd_var_default; // note: these are actual value * 10 52 | //int owd_valid; 53 | //unsigned long owd_t; 54 | 55 | int fd[MAX_SUBFLOWS]; 56 | int infoSize; 57 | int nTCP; 58 | // MPBond 59 | int pipeBW[MAX_SUBFLOWS]; // in kbps 60 | int pipeRTT[MAX_SUBFLOWS]; 61 | int bytesInPipe[MAX_SUBFLOWS]; 62 | int bytesOnDevice[MAX_SUBFLOWS]; 63 | unsigned long long primaryAck; // for reliability/reinjection 64 | int updated; 65 | 66 | void Setup(); 67 | void ChangeCC(int subflowNo, int cc); 68 | void UpdateSubflowInfo(int subflowNo); 69 | void UpdateTCPAvailableSpace(); 70 | void DecreaseTCPAvailableSpace(int subflowNo, int delta); 71 | int IsCongWindowFull(int subflowNo); 72 | void UpdateOWD(int subflowNo, int owd, uint32_t ack); 73 | double GetOWD(int subflowNo, int bif1, int bif2); 74 | double GetOWDVar(); 75 | //void ResetOWD(); 76 | 77 | int HaveSpace(); 78 | 79 | double GetBW(int subflowNo); 80 | int GetTCPAvailableSpace(int subflowNo); 81 | unsigned int GetSendCwnd(int subflowNo); 82 | unsigned int GetSndSsthresh(int subflowNo); 83 | unsigned int GetSndMss(int subflowNo); 84 | int GetInFlightSize(int subflowNo); 85 | int GetSRTT(int subflowNo); 86 | DWORD GetSndBuffer(int subflowNo); 87 | // MPBond 88 | double GetSubflowBW(); 89 | int GetSubflowBuffer(); 90 | }; 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /server/proxy.h: -------------------------------------------------------------------------------- 1 | #ifndef _PROXY_H_ 2 | #define _PROXY_H_ 3 | 4 | #define MY_VERSION "20191201" 5 | 6 | //transport protocol 1=TCP, 2=UDP, 3=SCTP 7 | #define TRANS 1 8 | 9 | #define SOL_TCP 6 10 | //#define MPTCP_ENABLED 26 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include //for SIOCOUTQ 35 | 36 | using namespace std; 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "proxy_setting.h" 43 | 44 | #define R_SUCC 1 45 | #define R_FAIL 0 46 | 47 | #define PROXY_MODE_LOCAL 1 48 | #define PROXY_MODE_REMOTE 2 49 | 50 | #define MAGIC_MSS_VALUE 1459 51 | 52 | #ifndef TCP_CMAT_SUBFLOW 53 | #define TCP_CMAT_SUBFLOW 31 54 | #endif 55 | 56 | 57 | typedef unsigned char BYTE; 58 | typedef unsigned int DWORD; 59 | typedef unsigned short WORD; 60 | typedef long long INT64; 61 | typedef unsigned long long DWORD64; 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /server/scheduler.h: -------------------------------------------------------------------------------- 1 | #ifndef _SCHEDULER_H_ 2 | #define _SCHEDULER_H_ 3 | 4 | #include "subflows.h" 5 | 6 | #define SCHED_SEQ_NUM 12 7 | 8 | struct SCHEDULER; 9 | 10 | typedef SUBFLOW_MSG * (SCHEDULER::*SelectSubflowFunc)(); 11 | 12 | struct SCHEDULER { 13 | double * pkt_delay; 14 | int schedulerSeq[SCHED_SEQ_NUM]; 15 | // mapping between schedNo and meta buffer index for different schedulers 16 | int schedulerQ[16 * 2]; 17 | int indexSeq; 18 | int nTCP; 19 | int twoWayWiFi, twoWaySEC; 20 | 21 | void Setup(); 22 | 23 | int schedHasPackets(int sched); 24 | int getNextSchedNo(); 25 | int getNextSchedNo2(); 26 | 27 | // SelectSubflowFunc DefaultSelectSubflow; 28 | int defaultScheduler; 29 | 30 | SelectSubflowFunc SelectSubflow[MAX_SCHEDULER]; 31 | 32 | static const char * getSchedulerName(int sched); 33 | int getSchedNormalQueue(int sched); 34 | int getSchedFirstQueue(int sched); 35 | int getSchedLastQueue(int sched); 36 | 37 | void printPktDelay(); 38 | void clearPktDelay(); 39 | 40 | SUBFLOW_MSG * SelectSubflow_ControlMsg(); 41 | 42 | private: 43 | //subflow selection algorithms 44 | SUBFLOW_MSG * SelectSubflow_WithBinding(); 45 | SUBFLOW_MSG * SelectSubflow_TwoWay_Base(int saveBytes, int schedNo); 46 | SUBFLOW_MSG * SelectSubflow_TwoWay(); 47 | SUBFLOW_MSG * SelectSubflow_TwoWay_Naive(); 48 | SUBFLOW_MSG * SelectSubflow_TwoWay_Balance(); 49 | SUBFLOW_MSG * SelectSubflow_NewTxDelay(); 50 | SUBFLOW_MSG * SelectSubflow_NewTxDelayBase(int queueNo); 51 | SUBFLOW_MSG * SelectSubflow_MinRTT_Kernel(); 52 | SUBFLOW_MSG * SelectSubflow_TxDelay(); 53 | SUBFLOW_MSG * SelectSubflow_TxDelayPlus(); 54 | SUBFLOW_MSG * SelectSubflow_RoundRobin(); 55 | SUBFLOW_MSG * SelectSubflow_ReMP(); 56 | SUBFLOW_MSG * SelectSubflow_Wifi(); 57 | SUBFLOW_MSG * SelectSubflow_ONEPATH(); 58 | SUBFLOW_MSG * SelectSubflow_ONEPATH_Base(int subflowNo, int schedNo); 59 | SUBFLOW_MSG * SelectSubflow_BBS(); 60 | SUBFLOW_MSG * SelectSubflow_BBS_MRT(); 61 | SUBFLOW_MSG * SelectSubflow_EMPTCP(); 62 | SUBFLOW_MSG * SelectSubflow_Block(); 63 | SUBFLOW_MSG * SelectSubflow_PAMS(); 64 | 65 | SUBFLOW_MSG * TwoWayEnhanced(); 66 | 67 | SUBFLOW_MSG * SearchPacketForLargeRTTPath(int large_rtt_i, int small_rtt_i, int queueNo); 68 | SUBFLOW_MSG * GetMessageForSubflow(int subflowNo, int queueNo, int other, int isSmallRTT, int saveBytes, uint64_t currt); 69 | 70 | }; 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /server/scripts/run_rp_minrtt.sh: -------------------------------------------------------------------------------- 1 | if [ $# -lt 1 ] 2 | then 3 | echo "Usage: bash run_rp_minrtt.sh " 4 | exit 5 | fi 6 | sudo pkill dmm_proxy 7 | sleep 1 8 | sudo rmmod -f ss 9 | sudo insmod /home/shawnzhu/dmm-proj/MPBond/server/ss.ko 10 | sudo /home/shawnzhu/dmm-proj/MPBond/server/dmm_proxy $1 0 0 11 | sudo rmmod -f ss 12 | echo "finish." 13 | -------------------------------------------------------------------------------- /server/scripts/run_rp_pams.sh: -------------------------------------------------------------------------------- 1 | if [ $# -lt 1 ] 2 | then 3 | echo "Usage: bash run_rp_pams.sh " 4 | exit 5 | fi 6 | sudo pkill dmm_proxy 7 | sleep 1 8 | sudo rmmod -f ss 9 | sudo insmod /home/shawnzhu/dmm-proj/MPBond/server/ss.ko 10 | sudo /home/shawnzhu/dmm-proj/MPBond/server/dmm_proxy $1 15 1 1 1 11 | sudo rmmod -f ss 12 | echo "finish." -------------------------------------------------------------------------------- /server/ss.mod.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | MODULE_INFO(vermagic, VERMAGIC_STRING); 6 | 7 | __visible struct module __this_module 8 | __attribute__((section(".gnu.linkonce.this_module"))) = { 9 | .name = KBUILD_MODNAME, 10 | .init = init_module, 11 | #ifdef CONFIG_MODULE_UNLOAD 12 | .exit = cleanup_module, 13 | #endif 14 | .arch = MODULE_ARCH_INIT, 15 | }; 16 | 17 | static const struct modversion_info ____versions[] 18 | __used 19 | __attribute__((section("__versions"))) = { 20 | { 0xe70be2f8, __VMLINUX_SYMBOL_STR(module_layout) }, 21 | { 0x204f3ad4, __VMLINUX_SYMBOL_STR(param_ops_uint) }, 22 | { 0xb5a94a10, __VMLINUX_SYMBOL_STR(misc_deregister) }, 23 | { 0xe16b0d30, __VMLINUX_SYMBOL_STR(unregister_jprobe) }, 24 | { 0xb1bedeb7, __VMLINUX_SYMBOL_STR(register_jprobe) }, 25 | { 0x67feecd0, __VMLINUX_SYMBOL_STR(misc_register) }, 26 | { 0xb2fd5ceb, __VMLINUX_SYMBOL_STR(__put_user_4) }, 27 | { 0xb8e7ce2c, __VMLINUX_SYMBOL_STR(__put_user_8) }, 28 | { 0x37a0cba, __VMLINUX_SYMBOL_STR(kfree) }, 29 | { 0xd2b09ce5, __VMLINUX_SYMBOL_STR(__kmalloc) }, 30 | { 0x89f84cfa, __VMLINUX_SYMBOL_STR(sockfd_lookup) }, 31 | { 0xdb7305a1, __VMLINUX_SYMBOL_STR(__stack_chk_fail) }, 32 | { 0x27e1a049, __VMLINUX_SYMBOL_STR(printk) }, 33 | { 0x2482e688, __VMLINUX_SYMBOL_STR(vsprintf) }, 34 | { 0x7d11c268, __VMLINUX_SYMBOL_STR(jiffies) }, 35 | { 0x61c997a8, __VMLINUX_SYMBOL_STR(tcp_current_mss) }, 36 | { 0x1b9aca3f, __VMLINUX_SYMBOL_STR(jprobe_return) }, 37 | { 0xbdfb6dbb, __VMLINUX_SYMBOL_STR(__fentry__) }, 38 | }; 39 | 40 | static const char __module_depends[] 41 | __used 42 | __attribute__((section(".modinfo"))) = 43 | "depends="; 44 | 45 | 46 | MODULE_INFO(srcversion, "40B1D680B3EF63869C4D2B6"); 47 | -------------------------------------------------------------------------------- /server/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // proxy.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | 8 | -------------------------------------------------------------------------------- /server/stdafx.h: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':Primary', ':Helper' 2 | --------------------------------------------------------------------------------