From bb2db4e7174b0bd91d5e0ddfd5f3c0dae7965d0d Mon Sep 17 00:00:00 2001 From: gasc Date: Sun, 22 Aug 2021 13:22:37 +0200 Subject: [PATCH] Importation du code depuis GitHub --- LICENSE | 674 ++++++++++++++++++++++++++++++++++++++++ README.md | 18 ++ lab2/proxy.py | 253 +++++++++++++++ lab2/user_manual_v1.pdf | Bin 0 -> 78055 bytes lab4/RouterNode.java | 207 ++++++++++++ lab4/run.sh | 20 ++ 6 files changed, 1172 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100755 lab2/proxy.py create mode 100644 lab2/user_manual_v1.pdf create mode 100644 lab4/RouterNode.java create mode 100755 lab4/run.sh diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + 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 + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/README.md b/README.md new file mode 100644 index 0000000..4b5ae97 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# TDTS06NetworkCourse +Sharing my labs done during TDTS06 course at Linköping University (HT2020). + +## Lab 2 +Very basic web proxy supporting multi-threading. The proxy intentionally alters certain texts and images. Only supporting HTTP. + +### Configuration +Example of proxy configuration under firefox. The procedure is broadly similar for other browsers. +Go to preferences, go to the bottom of the General page, find "network options" and enter the following parameters: +``` +Proxy HTTP: 127.0.0.1 Port: 8080 +Proxy HTTPS: 127.0.0.1 Port: 8080 +Hôte SOCKS: 127.0.0.1 Port: 8080 +``` + +## Lab 4 +Implementation of `RouterNode.java`. You will need the lab environnement to run the simulation. There is also a bash script useful for build and run the simulation. + diff --git a/lab2/proxy.py b/lab2/proxy.py new file mode 100755 index 0000000..bbad059 --- /dev/null +++ b/lab2/proxy.py @@ -0,0 +1,253 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" + TDTS06 - Computer networks 2020/21 + Last modification: 2020-10-02 (rev 3) + First release: 2020-09-25 (rev 1) + + Websites to try our very basic proxy: + http://zebroid.ida.liu.se/fakenews/test2.html + http://zebroid.ida.liu.se/fakenews/test4.html + + Note to the corrector: + """ """ comments are used to describe the general operation of a passage + while # comments describe the operation of a particular line. + + Usage: proxy.py [-h] [--debug] [--port PORT] + + Optional arguments: + -h, --help show the help message and exit + --debug print debug information + --port PORT set the port to use for the client side connection + +""" + + +import argparse # For program's argument management +import re # To find patterns +import signal # To implement a signal handler +import socket # A low level socket programming library +import time # To manage timeout +import _thread # Library for multi-threading + + +""" Proxy general parameters (default values) """ +HOST = '127.0.0.1' # Localhost +INTERNAL_PORT = 8080 # HTTP proxy internal port (can be change by user using --port PORT) +EXTERNAL_PORT = 80 # Port for server connection + +""" Alteration parameters """ +REPLACE1 = "Trolly" +REPLACE2 = "Linköping" +PATTERN1 = re.compile("Smiley", re.IGNORECASE) +PATTERN2 = re.compile("Stockholm", re.IGNORECASE) + +""" Dev. parameters """ +DEBUG = False # Can be change by passing --debug arg + + +""" A non-blocking recv function """ +def recv_non_blocking(socket): + total_data = [] + first_pkt = True + content_length = 0 + + while True: + # Try to receive data + try: + print("Receiving data segment...") + data = socket.recv(8192) + + # Trying to find the Content_Length field + if first_pkt: + first_pkt = False + pos = data.find(b'Content-Length:') + pos_end = data.find(b'\r', pos, len(data) - 1) + content_length = int(data[pos+16:pos_end].decode("utf-8")) + + # If we have new data, we add it to the total + if data: + total_data.append(data) + # If the total exceed the Content_Length field, we are done. + if len(b''.join(total_data)) >= content_length and content_length: + break + else: + time.sleep(0.05) + # Except no data + except: + pass + return b''.join(total_data) + + +""" +A function which alter a request + This function is particularly complex since it is necessary + to replace words by others while ensuring that these + replaced words are not image addresses. +""" +def altered(request): + try: + # Decoding the request to analyse it + altered_request = request.decode("utf-8") + except UnicodeDecodeError: + return request + + """ + The purpose of this part is to remplace 'Smiley' by 'Trolly' + and 'Stockholm' by 'Linköping' everywhere except in image names. + """ + final_request = "" + tmp = "" + analyse_start = 0 + r_end = len(altered_request) - 1 + # Searching for image + img_pos = altered_request.find('<', analyse_start, r_end) + while img_pos > -1: + # We alter until the start of + final_request += PATTERN2.sub(REPLACE2, PATTERN1.sub(REPLACE1, altered_request[analyse_start:img_pos])) + + analyse_start = altered_request.find('>', img_pos, r_end) + # We do not modify the inside of + final_request += altered_request[img_pos:analyse_start] + # We search for another image + img_pos = altered_request.find('<', analyse_start, r_end) + + # We alter the end of the request + final_request += PATTERN2.sub(REPLACE2, PATTERN1.sub(REPLACE1, altered_request[analyse_start:img_pos])) + return bytes(final_request, "utf-8") + + +""" A basic SIGINT handler""" +def signal_handler(sig, frame): + print('Stopping...') + try: + # Try closing client socket + client_socket.close() + except NameError: + pass + try: + # Try closing server socket + server_socket.close() + except NameError: + pass + + exit(0) + + +def send_server(t_url, t_protocol, t_server, t_client_connection): + """ Attempt to resend the request to the server """ + print("Trying to reach the website:") + server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + t_server_ip = socket.gethostbyname(t_server) + server_socket.connect((t_server_ip, EXTERNAL_PORT)) + print("Connected to server...") + print("Sending request...") + new_request = bytes("GET " + t_url + " " + t_protocol + "\nHost: " + t_server + "\r\n\r\n", "utf-8") + server_socket.sendall(new_request) + + """ Waiting fo response """ + print("Request sent.") + server_response = recv_non_blocking(server_socket) + #server_response = recv_timeout(server_socket) + print("Response from the server.") + + """ Request analysis """ + status_code = server_response[:25].decode("utf-8").split("\n")[0].split(' ')[1] + if status_code != "200": + print("The server returned an error, status code: ", status_code) + print("Error bypass attempt...") + + """ Text alteration """ + print("Server response alteration") + server_response = altered(server_response) + + """ We just resend the altered server response to the client """ + print("Transmitting the altered response to the client") + t_client_connection.sendall(server_response) + server_socket.close() + + # DEBUG + if DEBUG: + print("") + print("DEBUG:") + print(data) + print(new_request) + print(server_response) + print("") + # END DEBUG + + +def manage_request(data, client_connection): + """ Analysis of the request and identification """ + request = data.decode("utf-8").split("\n") + header = request[0].split(' ') + method = header[0] + + if "detectportal.firefox.com/success.txt" in request: + pass + elif method == "GET": + """ If it is a GET request, we extract any useful information """ + url = header[1] + server = url.split('/')[2] + server_ip = socket.gethostbyname(server) + protocol = header[2] + print("Interception of a GET method requesting the URL: ", url) + print("Destination server: ", server, " (", server_ip, ")") + + """ Image alteration """ + print("Checking for alteration...") + if "smiley.jpg" in url: + url = "http://zebroid.ida.liu.se/fakenews/trolly.jpg" + + _thread.start_new_thread(send_server, (url, protocol, server, client_connection)) + + """ If this is not a GET request """ + else: + print("Receiving an unsupported method: ", method) + if DEBUG: + print("") + print("DEBUG:") + print(data) + print("") + + +""" Code entry """ +""" We check for arguments """ +parser = argparse.ArgumentParser(description='A very basic HTTP proxy.') +parser.add_argument('--debug', help='print debug information', action='store_true') +parser.add_argument('--port', help='set the port to use for the client side connection') +args = parser.parse_args() +if args.debug: + DEBUG = True +if args.port: + INTERNAL_PORT = int(args.port) + + +""" Starting proxy initialisation """ +print("Init proxy...") +# Launching signal handler +signal.signal(signal.SIGINT, signal_handler) +if DEBUG: + print("DEBUG: Debug mode enabled.") + + +""" We create a local proxy on the port INTERNAL_PORT and we listen, waiting for a request """ +client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +client_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) +client_socket.bind((HOST, INTERNAL_PORT)) + + +while True: + client_socket.listen() + print("Proxy ready and waiting...") + + """ We accept any connection on the port and we keep the data sent """ + client_connection, addr = client_socket.accept() + print("Connected by", addr) + print("Receiving data...") + data = client_connection.recv(2048) + + _thread.start_new_thread(manage_request, (data, client_connection)) + diff --git a/lab2/user_manual_v1.pdf b/lab2/user_manual_v1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4ba2c21e62336ea84ae9c549b394eeffd549247a GIT binary patch literal 78055 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%0AjL%4ckn zH`yr1qvIk}Sj zrYvW;eJ;1#=g<@-!|lML!>-wEA;a!647)?oWS?8G*$t$Y;MN4rXV`2Cy1^8+kI&(- z+d&R^y#b?}LWV*JG=y$E;~V4Ijto|F}9_Gob--of;!=T?PDk<)a2ikuG2oJHvV#BxN5kOvdjzH%Zv&_N~M zZ{Hmp3AX<7#l%(5Cf>-AyspG+IMH42zU#Ye?vutq;`_g^t>>Ob<6pHdG`Y|DhuM6K zXl;7qd~2k59|kuZ-w6Yhul6{+ED-rBZp8xcN5CW?d`s&Etq z)7n6NaYa)ukE_d7sy2|laou9kLcm=1aqn|v9qiNI!x6;@kuN(==3>%2(nAdQ`w#xQtdg!aiUKQkwlEoLcfCq*fr6g@54squ~PNq9)F?pKiDXN}L$+1$WH?}kA%(R*!TI`x_Qs6#xH=kf_P1Th~Z2aaD7pXPh6Q{7>%()9alFO1`^Fh7~z7xhSLMynr{`6-TcfXPb+6~Xz;@mJnE#2~eg0>2U-BQxeb@bQ zuH4f@GQF9;{DQpVa=yHvAK$lNq+FRlMV_9&P+P6Nrv0q{oNq5Hwi4cGn_cWJ47+^e zTg_=jTLs%%yIR*Ri}|wUwpxI?5XDEe7swWxoPz5O;(SvASKGInQ80F%%h|@C$*g4g__3C z<953|-bjoSB`Zy>rC}qkV$%K@I}i4m*SBQm@u{S!*GPYf{>Z`Q$} z_sW;%j4PZyecD5@^czO>esblY6@y$>J&+w$uWH@7ves9-wtsxWWo;InIlr=V2l8=l z(8wLwwr};=!JV(h8C-=k$f6&%m-s>aDI#dLY@tNxB?w(J>oRF(W>&B$*gaU2xgk^R z=&bNm1O|8p1ghjJeYCC0b46f=JWHQuyUKG_;Be+K?YQ^2|1;LJ7~4|vX5GbVTof89!vy`3Eu@Z|A$%t3N(K{-_%r&HH7%6Str%!Do@E|Kt!eJ?pS?V_4~1e{I~Quh zC=zybG0^`uAd;2Cp@;G7!f)%x>*wyea%XKk@wev=&ZNa7Zd>@&qYD;3B^+q{asA-+ zug^>Tkoe#MvhmP}wQs#~^kuekI3)QscN)1q0B^qHO_Hg#_4s#CkRy(V`_tE>f zd-X?*M*^Cx`_&nAIyXaDpw;Nh^~bcm%06|krg^kg+UJzBW{tPau`RQ4Ho};-UpsSc zsv2rw18jkla0Y`?o6UlbiX&)|d_mq4v=LjjH7gCV$hPEXqQXP_)i3DIJ|dA!sjEb# z_G!g0nfjrYE$hy0`Y>ld5N1S9&pms3ZqxF4TYGt116{SMQ_Zd!@iHdG$jaQDZSlt# zvABv|=|4PuJn@gY-`u?8&zU>@%f{UF#3MJ(xRtE*K68Ym6ZI)VSM1!HHgndC?|tyX z^~hPhkxD0!v+O2kJ*iS&kLtyGPhBW+l>|r8;p*kCVZo_%k}z4B=&BAL&U|0^qw{0` z7tSwSKX||Me_?WvCo?lYz}T*TfbpQzhGy$+JRNC?-k~VXweYu^t&v#@Wl8#6xq@=_%+6|UC z$)8a?q=~TxvPCcRJA{f;rXR)5Us;O@b-08HHA;1gU~CEM;thrllV4i)#|1OqzoB|# z+dYk;rxq-HblbIywyt_`-T8+%6K>7WZq)iqZ|ZpS_2*wc{^mvGC18xFkh`47T;8~DdXqVM z#dSK-1DR~$F&Zmoc|4tI#!QmwDKfI9cy?a#MI>vI#r%Pdr!WLYyIY%Y`kswVn+X+- zwG~b4@u_&2)Xr^Ywp1|hlES7#O2RQyFLGBLDEQ0%ZxTNc*Ps7LtmMMi>h6^j*EJre zL$wYgZ(g#UjPyQSPclâ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 distanceTable[j][i] + costs[j] && j != myID){ + distanceTable[myID][i] = distanceTable[j][i] + costs[j]; + newRouteCost = distanceTable[myID][i]; + routesList[i] = j; + routesCosts[i] = newRouteCost; + } + } + // If we have changed smth then we have a update + if(oldRoute != routesList[i] || oldRouteCost != distanceTable[myID][i]){ + updt = true; + } + } + return updt; + } + + + //-------------------------------------------------- + public void recvUpdate(RouterPacket pkt) { + DEBUG("Rcv packet !"); + // Updating the distance table + distanceTable[pkt.sourceid] = pkt.mincost; + // Updating the routes list from the distance table + // and send this update to all neighbour if there + // are changes + if (Update()) {sendUpdate();} + } + + + //-------------------------------------------------- + private void sendUpdate() { + for (int i = 0; i < sim.NUM_NODES; i++) { + int[] sendedCosts = Arrays.copyOf(distanceTable[myID],sim.NUM_NODES); + + // We ignore non-neighbor nodes + if(i == myID || costs[i] == sim.INFINITY) {continue;} + + // Implementing poisoned reverse + if(POISONED_REVERSE) { + // For all destination nodes, if our route for a other node go thought + // this destination node, we set the distance to infinity to avoid that + // this destination node try to go back thought us and create a loop. + // See page 418 in the course book (4th edition). + for (int j = 0; j < RouterSimulator.NUM_NODES; j++) { + if (routesList[j] == i && j != i) { + sendedCosts[j] = RouterSimulator.INFINITY; + } + } + } + RouterPacket pkt = new RouterPacket(myID,i,sendedCosts); + DEBUG("Sending updt !"); + sim.toLayer2(pkt); + } + } + + //-------------------------------------------------- + // Function that print a table header + private void printTabHeader() { + myGUI.print(F.format("dst",CONST_TAB_SIZE) + " |"); + for (int i = 0; i < sim.NUM_NODES ; i++) {myGUI.print(F.format(i,CONST_TAB_SIZE));} + myGUI.println(""); + for (int i = 0; i < sim.NUM_NODES ; i++) { + for (int j = 0; j <= 1.5*CONST_TAB_SIZE; j++) { + myGUI.print("-"); + } + } + myGUI.println(""); + } + + //-------------------------------------------------- + // Print distance table, costs list & routes list when call + public void printDistanceTable() { + // Header + myGUI.println("Current table for " + myID + + " at time " + sim.getClocktime()); + + // DistanceTable + myGUI.println("Distancetable: "); + printTabHeader(); + + // Printing a line for each known routers + for (int i = 0; i < sim.NUM_NODES; ++i ) { + // We ignore non-neighbor nodes + if (costs[i] == sim.INFINITY) continue; + + myGUI.print(F.format("nbr " + i, CONST_TAB_SIZE) + "|"); + for (int j = 0; j < sim.NUM_NODES; ++j ) {myGUI.print(F.format(distanceTable[i][j],CONST_TAB_SIZE));} + myGUI.println(""); + } + myGUI.println(""); + + // Distance vector & routes + myGUI.println("Our distance vector and routes: "); + printTabHeader(); + + // Printing costs + myGUI.print(F.format("cost",CONST_TAB_SIZE) + "|"); + for (int i = 0; i < sim.NUM_NODES; i++) { + myGUI.print(F.format(routesCosts[i],CONST_TAB_SIZE)); + //myGUI.print(F.format(costs[i],CONST_TAB_SIZE)); + } + myGUI.println(""); + + // Printing routes + myGUI.print(F.format("route",CONST_TAB_SIZE) + "|"); + for (int i = 0; i < sim.NUM_NODES; i++) { + myGUI.print(F.format(routesList[i],CONST_TAB_SIZE)); + } + myGUI.println(""); + + // Printing info on poisoned reverse + if (POISONED_REVERSE) { + myGUI.println("(Poisoned reverse active)"); + } + else { + myGUI.println("(No poisoned reverse)"); + } + myGUI.println("\n"); + } + + //-------------------------------------------------- + // If a link change its cost + public void updateLinkCost(int dest, int newcost) { + // Updating costs list + costs[dest] = newcost; + // Spreading the update + if (Update()) {sendUpdate();} + } + + // DEBUG FUNCTION - TO REMOVE + private void DEBUG(String str) { + //myGUI.print(" DEBUG from " + myID + " at time " + sim.getClocktime() + ": "); + //myGUI.println(str); + } +} + + diff --git a/lab4/run.sh b/lab4/run.sh new file mode 100755 index 0000000..bbd051c --- /dev/null +++ b/lab4/run.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +#set -xv + +echo "Remember to save the file (Ctrl+S) before compiling!" + +rm bin -r > /dev/null 2>&1 +rm *.class > /dev/null 2>&1 + +javac *.java +make test > /dev/null + +rm bin -r > /dev/null 2>&1 +rm *.class > /dev/null 2>&1 + +echo "Done." +exit 0 + + +