From 9b9fa047b96d78fd3b896aa78001cb086bb763b9 Mon Sep 17 00:00:00 2001 From: Mygod Date: Mon, 23 Jan 2017 03:54:37 +0800 Subject: [PATCH] Initial commit --- .gitignore | 95 +++ .gitmodules | 8 + LICENSE | 622 ++++++++++++++++++ README.md | 61 ++ build.sbt | 34 + local.properties.example | 3 + project/plugins.sbt | 1 + src/go | 1 + src/kcptun | 1 + src/main/AndroidManifest.xml | 38 ++ src/main/ic_launcher-web.png | Bin 0 -> 31802 bytes src/main/res/mipmap-hdpi/ic_kcptun_logo.png | Bin 0 -> 3830 bytes src/main/res/mipmap-mdpi/ic_kcptun_logo.png | Bin 0 -> 2179 bytes src/main/res/mipmap-xhdpi/ic_kcptun_logo.png | Bin 0 -> 6120 bytes .../plugin/kcptun/BinaryProvider.scala | 21 + .../plugin/kcptun/HelpCallback.scala | 33 + src/make.bash | 67 ++ 17 files changed, 985 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 LICENSE create mode 100644 README.md create mode 100644 build.sbt create mode 100644 local.properties.example create mode 100644 project/plugins.sbt create mode 160000 src/go create mode 160000 src/kcptun create mode 100644 src/main/AndroidManifest.xml create mode 100644 src/main/ic_launcher-web.png create mode 100644 src/main/res/mipmap-hdpi/ic_kcptun_logo.png create mode 100644 src/main/res/mipmap-mdpi/ic_kcptun_logo.png create mode 100644 src/main/res/mipmap-xhdpi/ic_kcptun_logo.png create mode 100644 src/main/scala/com/github/shadowsocks/plugin/kcptun/BinaryProvider.scala create mode 100644 src/main/scala/com/github/shadowsocks/plugin/kcptun/HelpCallback.scala create mode 100755 src/make.bash diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9a39257 --- /dev/null +++ b/.gitignore @@ -0,0 +1,95 @@ +# Created by .ignore support plugin (hsz.mobi) +### Scala template +*.class +*.log + +# sbt specific +.cache +.history +.lib/ +dist/* +target +lib_managed/ +src_managed/ +project/boot/ +project/plugins/project/ + +# Scala-IDE specific +.scala_dependencies +.worksheet + +# ENSIME specific +.ensime_cache/ +.ensime +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties +### SBT template +# Simple Build Tool +# http://www.scala-sbt.org/release/docs/Getting-Started/Directories.html#configuring-version-control + +### Android template +# Built application files +*.apk +*.ap_ + +# Files for the ART/Dalvik VM +*.dex + +# Java class files + +# Generated files +bin/ +gen/ +out/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# Intellij +.idea/ +proguard-sbt.txt + +# Keystore files +*.jks + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild + +/.deps/ +/src/main/libs diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..f0ce053 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,8 @@ +[submodule "src/go"] + path = src/go + url = https://github.com/shadowsocks/go.git + branch = shadowsocks +[submodule "src/kcptun"] + path = src/kcptun + url = https://github.com/shadowsocks/kcptun.git + branch = shadowsocks diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e963df8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,622 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + diff --git a/README.md b/README.md new file mode 100644 index 0000000..c2a21be --- /dev/null +++ b/README.md @@ -0,0 +1,61 @@ +## kcptun for Android + +[kcptun](https://github.com/shadowsocks/kcptun) plugin for [shadowsocks-android](https://github.com/shadowsocks/shadowsocks-android). + +### CI STATUS + +[![Build Status](https://api.travis-ci.org/shadowsocks/kcptun-android.svg)](https://travis-ci.org/shadowsocks/kcptun-android) + +### PREREQUISITES + +* JDK 1.8 +* SBT 0.13.0+ +* Go 1.4+ +* Android SDK + - Build Tools 25+ + - Android Support Repository (see `build.sbt` for version) +* Android NDK r12b+ + +### BUILD + +* Set environment variable `ANDROID_HOME` to `/path/to/android-sdk` +* Set environment variable `ANDROID_NDK_HOME` to `/path/to/android-ndk` +* Set environment variable `GOROOT_BOOTSTRAP` to `/path/to/go` +* Create your key following the instructions at https://developer.android.com/studio/publish/app-signing.html +* Create `local.properties` from `local.properties.example` with your own key information +* Invoke the building like this + +```bash + git submodule update --init --recursive + + # Build the App + sbt clean go-build android:package-release +``` + +### TRANSLATE + +This plugin is an official plugin thus you can see [shadowsocks-android](https://github.com/shadowsocks/shadowsocks-android/blob/master/README.md#translate)'s instructions to translate this plugin's UI. + +## OPEN SOURCE LICENSES + + + +### LICENSE + +Copyright (C) 2017 by Max Lv <> +Copyright (C) 2017 by Mygod Studio <> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..8eddab7 --- /dev/null +++ b/build.sbt @@ -0,0 +1,34 @@ +scalaVersion := "2.11.8" + +enablePlugins(AndroidApp) +android.useSupportVectors + +name := "kcptun" +organization := "com.github.shadowsocks" +version := "0.0.1" +versionCode := Some(1) + +platformTarget := "android-25" + +compileOrder := CompileOrder.JavaThenScala +javacOptions ++= "-source" :: "1.7" :: "-target" :: "1.7" :: Nil +scalacOptions ++= "-target:jvm-1.7" :: "-Xexperimental" :: Nil + +proguardVersion := "5.3.2" +proguardCache := Seq() + +shrinkResources := true +typedResources := false +resConfigs := Seq("zh-rCN") + +resolvers += "Local Maven Repository" at "file://" + Path.userHome.absolutePath + "/.m2/repository" + +libraryDependencies += "com.github.shadowsocks" %% "plugin" % "0.0.1-SNAPSHOT" + +lazy val goBuild = TaskKey[Unit]("go-build", "Build go and kcptun") +goBuild := { + Process(Seq("src/make.bash", minSdkVersion.value)) ! streams.value.log match { + case 0 => // Success! + case n => sys.error(s"Native build script exit code: $n") + } +} diff --git a/local.properties.example b/local.properties.example new file mode 100644 index 0000000..d23c53e --- /dev/null +++ b/local.properties.example @@ -0,0 +1,3 @@ +key.alias: your_key_alias +key.store: /path/to/your/key/store +key.store.password: your_key_password diff --git a/project/plugins.sbt b/project/plugins.sbt new file mode 100644 index 0000000..d876664 --- /dev/null +++ b/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("org.scala-android" % "sbt-android" % "1.7.3") diff --git a/src/go b/src/go new file mode 160000 index 0000000..dcf83d3 --- /dev/null +++ b/src/go @@ -0,0 +1 @@ +Subproject commit dcf83d3b990d79304b78780a3b128b76fc6b70cc diff --git a/src/kcptun b/src/kcptun new file mode 160000 index 0000000..87479ab --- /dev/null +++ b/src/kcptun @@ -0,0 +1 @@ +Subproject commit 87479ab12e2c729564e1210a058984ae96e0d9b6 diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml new file mode 100644 index 0000000..6bc724a --- /dev/null +++ b/src/main/AndroidManifest.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/ic_launcher-web.png b/src/main/ic_launcher-web.png new file mode 100644 index 0000000000000000000000000000000000000000..37c058a5fb3180224482b1bec502e862a76d0eb3 GIT binary patch literal 31802 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 sflrb6K9CX*h!tPOSMgPR-51yY0V|PDFlk literal 0 HcmV?d00001 diff --git a/src/main/res/mipmap-mdpi/ic_kcptun_logo.png b/src/main/res/mipmap-mdpi/ic_kcptun_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..2522268a10c16f8cac41aa164edd6f09c4668576 GIT binary patch literal 2179 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 uVq ParcelFileDescriptor.open(new File(getExecutable), ParcelFileDescriptor.MODE_READ_ONLY) + case _ => throw new FileNotFoundException() + } +} diff --git a/src/main/scala/com/github/shadowsocks/plugin/kcptun/HelpCallback.scala b/src/main/scala/com/github/shadowsocks/plugin/kcptun/HelpCallback.scala new file mode 100644 index 0000000..31a3114 --- /dev/null +++ b/src/main/scala/com/github/shadowsocks/plugin/kcptun/HelpCallback.scala @@ -0,0 +1,33 @@ +package com.github.shadowsocks.plugin.kcptun + +import com.github.shadowsocks.plugin.PluginOptions + +import scala.io.Source + +/** + * @author Mygod + */ +class HelpCallback extends com.github.shadowsocks.plugin.HelpCallback { + override def produceHelpMessage(options: PluginOptions): CharSequence = { + val process = new ProcessBuilder(getApplicationInfo.nativeLibraryDir + "/libkcptun.so", "--help") + .redirectErrorStream(true) + .start() + process.waitFor() + Source.fromInputStream(process.getInputStream()) + .getLines() + .dropWhile(line => line != "GLOBAL OPTIONS:") + .drop(1) + .takeWhile(line => line.length() > 3) + .filter(line => + !line.startsWith(" --localaddr ") && + !line.startsWith(" --remoteaddr ") && + !line.startsWith(" -c ") && + !line.startsWith(" -V ") && + !line.startsWith(" --fast-open ") && + !line.startsWith(" --help,") && + !line.startsWith(" --version,")) + .mkString("\n") + .replaceAll(" {2,}", "\n") + .substring(1) // remove 1st \n + } +} diff --git a/src/make.bash b/src/make.bash new file mode 100755 index 0000000..13bb793 --- /dev/null +++ b/src/make.bash @@ -0,0 +1,67 @@ +#!/bin/bash + +function try () { +"$@" || exit -1 +} + +[ -z "$ANDROID_NDK_HOME" ] && ANDROID_NDK_HOME=~/android-ndk-r12b + +DIR=$(pwd)/src +MIN_API=$1 +DEPS=$(pwd)/.deps +ANDROID_ARM_TOOLCHAIN=$DEPS/android-toolchain-${MIN_API}-arm +ANDROID_X86_TOOLCHAIN=$DEPS/android-toolchain-${MIN_API}-x86 + +ANDROID_ARM_CC=$ANDROID_ARM_TOOLCHAIN/bin/arm-linux-androideabi-gcc +ANDROID_ARM_STRIP=$ANDROID_ARM_TOOLCHAIN/bin/arm-linux-androideabi-strip + +ANDROID_X86_CC=$ANDROID_X86_TOOLCHAIN/bin/i686-linux-android-gcc +ANDROID_X86_STRIP=$ANDROID_X86_TOOLCHAIN/bin/i686-linux-android-strip + +try mkdir -p $DEPS $DIR/main/libs/armeabi-v7a $DIR/main/libs/x86 + +if [ ! -d "$ANDROID_ARM_TOOLCHAIN" ]; then + echo "Make standalone toolchain for ARM arch" + $ANDROID_NDK_HOME/build/tools/make_standalone_toolchain.py --arch arm \ + --api $MIN_API --install-dir $ANDROID_ARM_TOOLCHAIN +fi + +if [ ! -d "$ANDROID_X86_TOOLCHAIN" ]; then + echo "Make standalone toolchain for X86 arch" + $ANDROID_NDK_HOME/build/tools/make_standalone_toolchain.py --arch x86 \ + --api $MIN_API --install-dir $ANDROID_X86_TOOLCHAIN +fi + +if [ ! -d "$DIR/go/bin" ]; then + echo "Build the custom go" + + pushd $DIR/go/src + try ./make.bash + popd +fi + +export GOROOT=$DIR/go +export GOPATH=$DEPS/gopath +export GOBIN=$GOPATH/bin +mkdir -p $GOBIN +export PATH=$GOROOT/bin:$PATH + +pushd $DIR/kcptun/client + +echo "Get dependences for kcptun" +go get -u github.com/xtaci/kcp-go +go get -u github.com/xtaci/smux +go get + +echo "Cross compile kcptun for arm" +try env CGO_ENABLED=1 CC=$ANDROID_ARM_CC GOOS=android GOARCH=arm GOARM=7 go build -ldflags="-s -w" +try $ANDROID_ARM_STRIP client +try mv client $DIR/main/libs/armeabi-v7a/libkcptun.so + +echo "Cross compile kcptun for x86" +try env CGO_ENABLED=1 CC=$ANDROID_X86_CC GOOS=android GOARCH=386 go build -ldflags="-s -w" +try $ANDROID_X86_STRIP client +try mv client $DIR/main/libs/x86/libkcptun.so +popd + +echo "Successfully build kcptun"