Compare commits
	
		
			170 Commits
		
	
	
		
			v0.7.0
			...
			xenia/topl
		
	
	| Author | SHA1 | Date | 
|---|---|---|
| 
							
							
								
									
								
								 | 
						578504caef | |
| 
							
							
								
									
								
								 | 
						1155274a32 | |
| 
							
							
								
									
								
								 | 
						d77ec85675 | |
| 
							
							
								 | 
						df49fd6f3d | |
| 
							
							
								 | 
						3cb6a1eec2 | |
| 
							
							
								 | 
						17169e3444 | |
| 
							
							
								 | 
						1df7d235f5 | |
| 
							
							
								 | 
						c74618ae9e | |
| 
							
							
								 | 
						25867f20b4 | |
| 
							
							
								 | 
						b004723a28 | |
| 
							
							
								 | 
						0032ffa055 | |
| 
							
							
								 | 
						3818a59541 | |
| 
							
							
								 | 
						853d5f3764 | |
| 
							
							
								 | 
						95fde8b3ee | |
| 
							
							
								 | 
						f1e7823a3d | |
| 
							
							
								 | 
						589027568b | |
| 
							
							
								 | 
						f09dadb1ed | |
| 
							
							
								 | 
						5388eae1df | |
| 
							
							
								 | 
						6e4107a93b | |
| 
							
							
								 | 
						f5a82afe29 | |
| 
							
							
								 | 
						cfd0b07e1f | |
| 
							
							
								 | 
						569a86a140 | |
| 
							
							
								 | 
						cb6cbecba1 | |
| 
							
							
								 | 
						348aee839a | |
| 
							
							
								 | 
						d00eba8df2 | |
| 
							
							
								 | 
						8afcf4fb8d | |
| 
							
							
								 | 
						f19948b6cf | |
| 
							
							
								 | 
						aa5819fe35 | |
| 
							
							
								 | 
						1684aa3806 | |
| 
							
							
								 | 
						ee623a2d84 | |
| 
							
							
								 | 
						43a82ef6be | |
| 
							
							
								 | 
						559dafb030 | |
| 
							
							
								 | 
						3c7169fcf5 | |
| 
							
							
								 | 
						f2b619faad | |
| 
							
							
								 | 
						a6d82b1a44 | |
| 
							
							
								 | 
						8041e0368c | |
| 
							
							
								 | 
						d02f1b4f41 | |
| 
							
							
								 | 
						4c46580e43 | |
| 
							
							
								 | 
						02173b8352 | |
| 
							
							
								 | 
						25e4caa105 | |
| 
							
							
								 | 
						dc307b7183 | |
| 
							
							
								 | 
						6a7763c210 | |
| 
							
							
								 | 
						cc51ee6f02 | |
| 
							
							
								 | 
						4b3d6e2962 | |
| 
							
							
								 | 
						9faaa44787 | |
| 
							
							
								 | 
						a9045705ba | |
| 
							
							
								 | 
						39356163d9 | |
| 
							
							
								 | 
						9a041683be | |
| 
							
							
								 | 
						8d2c86c73d | |
| 
							
							
								 | 
						b7b1082dc6 | |
| 
							
							
								 | 
						c399f915b7 | |
| 
							
							
								 | 
						bbb604db06 | |
| 
							
							
								 | 
						ba90706429 | |
| 
							
							
								 | 
						9cba3299c4 | |
| 
							
							
								 | 
						5de13805d8 | |
| 
							
							
								 | 
						d74939d323 | |
| 
							
							
								 | 
						a8a20f570e | |
| 
							
							
								 | 
						aeacfbc2c0 | |
| 
							
							
								 | 
						15f12d0693 | |
| 
							
							
								 | 
						19d0d1be64 | |
| 
							
							
								 | 
						310aedac8e | |
| 
							
							
								 | 
						13d081f5ed | |
| 
							
							
								 | 
						cde0b7632d | |
| 
							
							
								 | 
						ec6a1ac308 | |
| 
							
							
								 | 
						d09c3e4f0b | |
| 
							
							
								 | 
						c77b875e89 | |
| 
							
							
								 | 
						07beeca580 | |
| 
							
							
								 | 
						ed78f1b43f | |
| 
							
							
								 | 
						d8f3ac8971 | |
| 
							
							
								 | 
						07b2978326 | |
| 
							
							
								 | 
						814a1fd7b0 | |
| 
							
							
								 | 
						aae23e2482 | |
| 
							
							
								 | 
						db65eed2c3 | |
| 
							
							
								 | 
						2032b44949 | |
| 
							
							
								 | 
						e8a4c66719 | |
| 
							
							
								 | 
						b213d56eb4 | |
| 
							
							
								 | 
						ff91879ae1 | |
| 
							
							
								 | 
						8379384d37 | |
| 
							
							
								 | 
						25323f6839 | |
| 
							
							
								 | 
						721b7f0d9b | |
| 
							
							
								 | 
						78d64f3cb0 | |
| 
							
							
								 | 
						be0735d7c7 | |
| 
							
							
								 | 
						8e14f18282 | |
| 
							
							
								 | 
						d2f671bdc7 | |
| 
							
							
								 | 
						67643ee996 | |
| 
							
							
								 | 
						37960ab9dd | |
| 
							
							
								 | 
						d37ebdaca7 | |
| 
							
							
								 | 
						024481c94b | |
| 
							
							
								 | 
						b406009c6d | |
| 
							
							
								 | 
						27e5d6fadd | |
| 
							
							
								 | 
						05dc792d86 | |
| 
							
							
								 | 
						99c0efc467 | |
| 
							
							
								 | 
						72bdf7f20e | |
| 
							
							
								 | 
						31bfe9ff3e | |
| 
							
							
								 | 
						cd5bedca74 | |
| 
							
							
								 | 
						9f48fc01a5 | |
| 
							
							
								 | 
						122ac1a25d | |
| 
							
							
								 | 
						006ffa619e | |
| 
							
							
								 | 
						79455c380d | |
| 
							
							
								 | 
						8d4b43e178 | |
| 
							
							
								 | 
						8c5127b375 | |
| 
							
							
								 | 
						119d1b2da1 | |
| 
							
							
								 | 
						4591cafd27 | |
| 
							
							
								 | 
						0eb3b65158 | |
| 
							
							
								 | 
						317511e3ca | |
| 
							
							
								 | 
						844a2798eb | |
| 
							
							
								 | 
						6b438e7517 | |
| 
							
							
								 | 
						b517121f1c | |
| 
							
							
								 | 
						d05923d2b1 | |
| 
							
							
								 | 
						52c4940523 | |
| 
							
							
								 | 
						ccc49f16f7 | |
| 
							
							
								 | 
						ac6db12ddb | |
| 
							
							
								 | 
						f8f87e3a54 | |
| 
							
							
								 | 
						84ded018cf | |
| 
							
							
								 | 
						5fd0874aba | |
| 
							
							
								 | 
						43dad946c6 | |
| 
							
							
								 | 
						b884bfecfb | |
| 
							
							
								 | 
						829a822de3 | |
| 
							
							
								 | 
						fe0dbccbc5 | |
| 
							
							
								 | 
						2efa4dfb35 | |
| 
							
							
								 | 
						1c86bf347f | |
| 
							
							
								 | 
						c83d2ae03c | |
| 
							
							
								 | 
						77dd915ad5 | |
| 
							
							
								 | 
						68443abd60 | |
| 
							
							
								 | 
						52e9b3479f | |
| 
							
							
								 | 
						1ad7c05b92 | |
| 
							
							
								 | 
						a96e2e7a69 | |
| 
							
							
								 | 
						8e15a73a77 | |
| 
							
							
								 | 
						2edb879845 | |
| 
							
							
								 | 
						4987aa536d | |
| 
							
							
								 | 
						36df8dc16b | |
| 
							
							
								 | 
						7b1df75e3a | |
| 
							
							
								 | 
						482d005d11 | |
| 
							
							
								 | 
						9c8a941729 | |
| 
							
							
								 | 
						a8a5fbbf0d | |
| 
							
							
								 | 
						e5843a9143 | |
| 
							
							
								 | 
						c269a00344 | |
| 
							
							
								 | 
						d8bf5cc85b | |
| 
							
							
								 | 
						f61ed01a3c | |
| 
							
							
								 | 
						7d915500b7 | |
| 
							
							
								 | 
						fc1611fc40 | |
| 
							
							
								 | 
						4d03ee7786 | |
| 
							
							
								 | 
						e7d253b1c1 | |
| 
							
							
								 | 
						b4e9148df8 | |
| 
							
							
								 | 
						7a51b22909 | |
| 
							
							
								 | 
						ec0e3f2e51 | |
| 
							
							
								 | 
						7a117bd71e | |
| 
							
							
								 | 
						07c2fd4068 | |
| 
							
							
								 | 
						3069665646 | |
| 
							
							
								 | 
						987a21a0d8 | |
| 
							
							
								 | 
						69a91d5421 | |
| 
							
							
								 | 
						582a818f2a | |
| 
							
							
								 | 
						778d29825d | |
| 
							
							
								 | 
						5233d1e858 | |
| 
							
							
								 | 
						840155ca9a | |
| 
							
							
								 | 
						1f51bab2a3 | |
| 
							
							
								 | 
						9e105d21d4 | |
| 
							
							
								 | 
						b559806a8e | |
| 
							
							
								 | 
						b38b2ca7c5 | |
| 
							
							
								 | 
						33abc0ca26 | |
| 
							
							
								 | 
						1160649794 | |
| 
							
							
								 | 
						434a023afe | |
| 
							
							
								 | 
						9a45c4aa66 | |
| 
							
							
								 | 
						7433423836 | |
| 
							
							
								 | 
						46532539c2 | |
| 
							
							
								 | 
						b9a1f14e86 | |
| 
							
							
								 | 
						81d932703b | |
| 
							
							
								 | 
						cea498e710 | |
| 
							
							
								 | 
						cc4bc22447 | |
| 
							
							
								 | 
						b4c3656c3c | 
| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					name: macos
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					on:
 | 
				
			||||||
 | 
					  push:
 | 
				
			||||||
 | 
					    branches: [ master ]
 | 
				
			||||||
 | 
					  pull_request:
 | 
				
			||||||
 | 
					    branches: [ master ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jobs:
 | 
				
			||||||
 | 
					  build:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    runs-on: macos-latest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					    - uses: actions/checkout@v2
 | 
				
			||||||
 | 
					    - name: make
 | 
				
			||||||
 | 
					      run: make
 | 
				
			||||||
 | 
					    - name: install check
 | 
				
			||||||
 | 
					      run: brew install check
 | 
				
			||||||
 | 
					    - name: run tests
 | 
				
			||||||
 | 
					      run: make test
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,33 @@
 | 
				
			||||||
 | 
					name: ubuntu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					on:
 | 
				
			||||||
 | 
					  push:
 | 
				
			||||||
 | 
					    branches: [ master ]
 | 
				
			||||||
 | 
					  pull_request:
 | 
				
			||||||
 | 
					    branches: [ master ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jobs:
 | 
				
			||||||
 | 
					  build:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					    - uses: actions/checkout@v2
 | 
				
			||||||
 | 
					    - name: make
 | 
				
			||||||
 | 
					      run: make
 | 
				
			||||||
 | 
					    - name: install check
 | 
				
			||||||
 | 
					      run: sudo apt install check
 | 
				
			||||||
 | 
					    - name: run tests
 | 
				
			||||||
 | 
					      run: make test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  build-android:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					    - uses: actions/checkout@v2
 | 
				
			||||||
 | 
					    - uses: nttld/setup-ndk@v1
 | 
				
			||||||
 | 
					      with:
 | 
				
			||||||
 | 
					        ndk-version: r21e
 | 
				
			||||||
 | 
					    - name: make
 | 
				
			||||||
 | 
					      run: make cross-android
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,25 @@
 | 
				
			||||||
 | 
					name: windows
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					on:
 | 
				
			||||||
 | 
					  push:
 | 
				
			||||||
 | 
					    branches: [ master ]
 | 
				
			||||||
 | 
					  pull_request:
 | 
				
			||||||
 | 
					    branches: [ master ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jobs:
 | 
				
			||||||
 | 
					  build:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    runs-on: windows-latest
 | 
				
			||||||
 | 
					    defaults:
 | 
				
			||||||
 | 
					      run:
 | 
				
			||||||
 | 
					        shell: msys2 {0}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					    - uses: actions/checkout@v2
 | 
				
			||||||
 | 
					    - uses: msys2/setup-msys2@v2
 | 
				
			||||||
 | 
					      with:
 | 
				
			||||||
 | 
					        msystem: MINGW64
 | 
				
			||||||
 | 
					        update: false
 | 
				
			||||||
 | 
					        install: git make mingw-w64-x86_64-toolchain mingw-w64-x86_64-zlib
 | 
				
			||||||
 | 
					    - name: make
 | 
				
			||||||
 | 
					      run: make TARGETOS=windows32
 | 
				
			||||||
| 
						 | 
					@ -3,3 +3,6 @@
 | 
				
			||||||
/src/base64u.c
 | 
					/src/base64u.c
 | 
				
			||||||
/src/base64u.h
 | 
					/src/base64u.h
 | 
				
			||||||
/tests/test
 | 
					/tests/test
 | 
				
			||||||
 | 
					*.o.d
 | 
				
			||||||
 | 
					/src/obj/local/*/iodine
 | 
				
			||||||
 | 
					/src/libs/*/iodine
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										11
									
								
								.travis.yml
								
								
								
								
							
							
						
						
									
										11
									
								
								.travis.yml
								
								
								
								
							| 
						 | 
					@ -1,11 +0,0 @@
 | 
				
			||||||
#set language to objective-c to force osx build
 | 
					 | 
				
			||||||
#linux builds are done at http://buildbot.dev.kryo.se
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
language: objective-c
 | 
					 | 
				
			||||||
os: osx
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
before_install: brew update
 | 
					 | 
				
			||||||
install: brew install check
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
script: make && make test
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,4 @@
 | 
				
			||||||
 | 
					set noexpandtab
 | 
				
			||||||
 | 
					set tabstop=8
 | 
				
			||||||
 | 
					set softtabstop=8
 | 
				
			||||||
 | 
					set shiftwidth=8
 | 
				
			||||||
							
								
								
									
										19
									
								
								CHANGELOG
								
								
								
								
							
							
						
						
									
										19
									
								
								CHANGELOG
								
								
								
								
							| 
						 | 
					@ -1,11 +1,28 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
iodine - http://code.kryo.se/iodine
 | 
					iodine - https://code.kryo.se/iodine
 | 
				
			||||||
 | 
					
 | 
				
			||||||
***********************************
 | 
					***********************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CHANGES:
 | 
					CHANGES:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
master:
 | 
					master:
 | 
				
			||||||
 | 
						- Mac OS X: Support native utun VPN devices. Patch by
 | 
				
			||||||
 | 
							Peter Sagerson, ported from OpenVPN by Catalin Patulea.
 | 
				
			||||||
 | 
						- Fix compilation failure on kFreeBSD and Hurd, by Gregor Herrmann
 | 
				
			||||||
 | 
						- Patch from Ryan Welton that fixes compilation warning.
 | 
				
			||||||
 | 
						- README converted to markdown by Nicolas Braud-Santoni.
 | 
				
			||||||
 | 
						- Linux: use pkg-config for systemd support flags.
 | 
				
			||||||
 | 
							Patch by Jason A. Donenfeld.
 | 
				
			||||||
 | 
						- Add support for IPv6 in the server.
 | 
				
			||||||
 | 
						   Raw mode will be with same protocol as used for login.
 | 
				
			||||||
 | 
						   Traffic inside tunnel is still IPv4.
 | 
				
			||||||
 | 
						- Update android build to support 5.0 (Lollipop) and newer.
 | 
				
			||||||
 | 
						- Change external IP lookup to using myip.opendns.com via DNS.
 | 
				
			||||||
 | 
						- Add option to choose IPv4 listen address from external IP lookup.
 | 
				
			||||||
 | 
						- Add server support for handling multiple domains via wildcard.
 | 
				
			||||||
 | 
						- Recognize tap device component id 'root' prefix on Windows.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2014-06-16: 0.7.0 "Kryoptonite"
 | 
				
			||||||
	- Partial IPv6 support (#107)
 | 
						- Partial IPv6 support (#107)
 | 
				
			||||||
	   Client can connect to iodined through an relaying IPv6
 | 
						   Client can connect to iodined through an relaying IPv6
 | 
				
			||||||
	   nameserver. Server only supports IPv4 for now.
 | 
						   nameserver. Server only supports IPv4 for now.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					Copyright (c) 2006-2020 iodine authors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Permission to use, copy, modify, and/or distribute this software for any purpose
 | 
				
			||||||
 | 
					with or without fee is hereby granted, provided that the above copyright notice
 | 
				
			||||||
 | 
					and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 | 
				
			||||||
 | 
					REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
				
			||||||
 | 
					FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
 | 
				
			||||||
 | 
					INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 | 
				
			||||||
 | 
					LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
				
			||||||
 | 
					OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
				
			||||||
 | 
					PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
							
								
								
									
										61
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										61
									
								
								Makefile
								
								
								
								
							| 
						 | 
					@ -2,6 +2,7 @@ prefix?=/usr/local
 | 
				
			||||||
sbindir=$(prefix)/sbin
 | 
					sbindir=$(prefix)/sbin
 | 
				
			||||||
datadir=$(prefix)/share
 | 
					datadir=$(prefix)/share
 | 
				
			||||||
mandir=$(datadir)/man
 | 
					mandir=$(datadir)/man
 | 
				
			||||||
 | 
					docdir=$(datadir)/doc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DESTDIR=
 | 
					DESTDIR=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +18,7 @@ RM_FLAGS=-f
 | 
				
			||||||
TARGETOS = `uname`
 | 
					TARGETOS = `uname`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
all:
 | 
					all:
 | 
				
			||||||
	@(cd src; $(MAKE) TARGETOS=$(TARGETOS) all)
 | 
						@$(MAKE) -C src TARGETOS=$(TARGETOS) all
 | 
				
			||||||
 | 
					
 | 
				
			||||||
install: all
 | 
					install: all
 | 
				
			||||||
	$(MKDIR) $(MKDIR_FLAGS) $(DESTDIR)$(sbindir)
 | 
						$(MKDIR) $(MKDIR_FLAGS) $(DESTDIR)$(sbindir)
 | 
				
			||||||
| 
						 | 
					@ -28,6 +29,9 @@ install: all
 | 
				
			||||||
	$(MKDIR) $(MKDIR_FLAGS) $(DESTDIR)$(mandir)/man8
 | 
						$(MKDIR) $(MKDIR_FLAGS) $(DESTDIR)$(mandir)/man8
 | 
				
			||||||
	$(INSTALL) $(INSTALL_FLAGS) man/iodine.8 $(DESTDIR)$(mandir)/man8/iodine.8
 | 
						$(INSTALL) $(INSTALL_FLAGS) man/iodine.8 $(DESTDIR)$(mandir)/man8/iodine.8
 | 
				
			||||||
	chmod 644 $(DESTDIR)$(mandir)/man8/iodine.8
 | 
						chmod 644 $(DESTDIR)$(mandir)/man8/iodine.8
 | 
				
			||||||
 | 
						$(MKDIR) $(MKDIR_FLAGS) $(DESTDIR)$(docdir)/iodine
 | 
				
			||||||
 | 
						$(INSTALL) $(INSTALL_FLAGS) README.md $(DESTDIR)$(docdir)/iodine/README.md
 | 
				
			||||||
 | 
						chmod 644 $(DESTDIR)$(docdir)/iodine/README.md
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uninstall:
 | 
					uninstall:
 | 
				
			||||||
	$(RM) $(RM_FLAGS) $(DESTDIR)$(sbindir)/iodine
 | 
						$(RM) $(RM_FLAGS) $(DESTDIR)$(sbindir)/iodine
 | 
				
			||||||
| 
						 | 
					@ -36,13 +40,13 @@ uninstall:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test: all
 | 
					test: all
 | 
				
			||||||
	@echo "!! The check library is required for compiling and running the tests"
 | 
						@echo "!! The check library is required for compiling and running the tests"
 | 
				
			||||||
	@echo "!! Get it at http://check.sf.net"
 | 
						@echo "!! Get it at https://libcheck.github.io/check/"
 | 
				
			||||||
	@(cd tests; $(MAKE) TARGETOS=$(TARGETOS) all)
 | 
						@$(MAKE) -C tests TARGETOS=$(TARGETOS) all
 | 
				
			||||||
 | 
					
 | 
				
			||||||
clean:
 | 
					clean:
 | 
				
			||||||
	@echo "Cleaning..."
 | 
						@echo "Cleaning..."
 | 
				
			||||||
	@(cd src; $(MAKE) clean)
 | 
						@$(MAKE) -C src clean
 | 
				
			||||||
	@(cd tests; $(MAKE) clean)
 | 
						@$(MAKE) -C tests clean
 | 
				
			||||||
	@rm -rf bin iodine-latest*
 | 
						@rm -rf bin iodine-latest*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#Helper target for windows/android zipfiles
 | 
					#Helper target for windows/android zipfiles
 | 
				
			||||||
| 
						 | 
					@ -50,55 +54,60 @@ iodine-latest:
 | 
				
			||||||
	@rm -rf iodine-latest*
 | 
						@rm -rf iodine-latest*
 | 
				
			||||||
	@mkdir -p iodine-latest
 | 
						@mkdir -p iodine-latest
 | 
				
			||||||
	@echo "Create date: " > iodine-latest/VERSION.txt
 | 
						@echo "Create date: " > iodine-latest/VERSION.txt
 | 
				
			||||||
	@date >> iodine-latest/VERSION.txt
 | 
						@LANG=en_US date >> iodine-latest/VERSION.txt
 | 
				
			||||||
	@echo "Git version: " >> iodine-latest/VERSION.txt
 | 
						@echo "Git version: " >> iodine-latest/VERSION.txt
 | 
				
			||||||
	@git rev-parse HEAD >> iodine-latest/VERSION.txt
 | 
						@git rev-parse HEAD >> iodine-latest/VERSION.txt
 | 
				
			||||||
	@for i in README CHANGELOG TODO; do cp $$i iodine-latest/$$i.txt; done
 | 
						@for i in README.md CHANGELOG; do cp $$i iodine-latest/$$i.txt; done
 | 
				
			||||||
	@unix2dos iodine-latest/*
 | 
						@unix2dos iodine-latest/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#non-PIE build for old android
 | 
				
			||||||
 | 
					cross-android-old:
 | 
				
			||||||
 | 
						@$(MAKE) -C src base64u.c
 | 
				
			||||||
 | 
						@(cd src && ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk APP_PLATFORM=android-3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#Position-indepedent build for modern android
 | 
				
			||||||
cross-android:
 | 
					cross-android:
 | 
				
			||||||
	@(cd src; $(MAKE) base64u.c base64u.h)
 | 
						@$(MAKE) -C src base64u.c
 | 
				
			||||||
	@(cd src; ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk)
 | 
						@(cd src && ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.16.mk APP_PLATFORM=android-16)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
iodine-latest-android.zip: iodine-latest
 | 
					iodine-latest-android.zip: iodine-latest
 | 
				
			||||||
	@mv iodine-latest iodine-latest-android
 | 
						@mv iodine-latest iodine-latest-android
 | 
				
			||||||
	@mkdir -p iodine-latest-android/armeabi iodine-latest-android/x86
 | 
						@mkdir -p iodine-latest-android/pre-kitkat/armeabi
 | 
				
			||||||
 | 
						@mkdir -p iodine-latest-android/pre-kitkat/x86
 | 
				
			||||||
 | 
						@$(MAKE) cross-android-old TARGET_ARCH_ABI=armeabi
 | 
				
			||||||
 | 
						@cp src/libs/armeabi/* iodine-latest-android/pre-kitkat/armeabi
 | 
				
			||||||
 | 
						@$(MAKE) cross-android-old TARGET_ARCH_ABI=x86
 | 
				
			||||||
 | 
						@cp src/libs/x86/* iodine-latest-android/pre-kitkat/x86
 | 
				
			||||||
 | 
						@rm -rf src/libs src/obj
 | 
				
			||||||
 | 
						@mkdir -p iodine-latest-android/armeabi
 | 
				
			||||||
 | 
						@mkdir -p iodine-latest-android/arm64-v8a
 | 
				
			||||||
 | 
						@mkdir -p iodine-latest-android/x86
 | 
				
			||||||
	@$(MAKE) cross-android TARGET_ARCH_ABI=armeabi
 | 
						@$(MAKE) cross-android TARGET_ARCH_ABI=armeabi
 | 
				
			||||||
	@cp src/libs/armeabi/* iodine-latest-android/armeabi
 | 
						@cp src/libs/armeabi/* iodine-latest-android/armeabi
 | 
				
			||||||
 | 
						@$(MAKE) cross-android TARGET_ARCH_ABI=arm64-v8a
 | 
				
			||||||
 | 
						@cp src/libs/arm64-v8a/* iodine-latest-android/arm64-v8a
 | 
				
			||||||
	@$(MAKE) cross-android TARGET_ARCH_ABI=x86
 | 
						@$(MAKE) cross-android TARGET_ARCH_ABI=x86
 | 
				
			||||||
	@cp src/libs/x86/* iodine-latest-android/x86
 | 
						@cp src/libs/x86/* iodine-latest-android/x86
 | 
				
			||||||
	@cp README-android.txt iodine-latest-android
 | 
						@cp README-android.txt iodine-latest-android
 | 
				
			||||||
	@zip -r iodine-latest-android.zip iodine-latest-android
 | 
						@zip -r iodine-latest-android.zip iodine-latest-android
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cross-mingw32:
 | 
					cross-mingw32:
 | 
				
			||||||
	@(cd src; $(MAKE) TARGETOS=windows32 CC=i686-w64-mingw32-gcc all)
 | 
						@$(MAKE) -C src TARGETOS=windows32 CC=i686-w64-mingw32-gcc all
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cross-mingw64:
 | 
					cross-mingw64:
 | 
				
			||||||
	@(cd src; $(MAKE) TARGETOS=windows32 CC=x86_64-w64-mingw32-gcc all)
 | 
						@$(MAKE) -C src TARGETOS=windows32 CC=x86_64-w64-mingw32-gcc all
 | 
				
			||||||
 | 
					
 | 
				
			||||||
iodine-latest-windows.zip: iodine-latest
 | 
					iodine-latest-windows.zip: iodine-latest
 | 
				
			||||||
	@mv iodine-latest iodine-latest-windows
 | 
						@mv iodine-latest iodine-latest-windows
 | 
				
			||||||
	@mkdir -p iodine-latest-windows/64bit iodine-latest-windows/32bit
 | 
						@mkdir -p iodine-latest-windows/64bit iodine-latest-windows/32bit
 | 
				
			||||||
	@(cd src; $(MAKE) TARGETOS=windows32 CC=i686-w64-mingw32-gcc clean all)
 | 
						@$(MAKE) -C src TARGETOS=windows32 CC=i686-w64-mingw32-gcc clean all
 | 
				
			||||||
	@i686-w64-mingw32-strip bin/iodine*
 | 
						@i686-w64-mingw32-strip bin/iodine*
 | 
				
			||||||
	@for i in `ls bin`; do cp bin/$$i iodine-latest-windows/32bit/$$i.exe; done
 | 
						@for i in `ls bin`; do cp bin/$$i iodine-latest-windows/32bit/$$i.exe; done
 | 
				
			||||||
	@cp /usr/i686-w64-mingw32/bin/zlib1.dll iodine-latest-windows/32bit
 | 
						@cp /usr/i686-w64-mingw32/bin/zlib1.dll iodine-latest-windows/32bit
 | 
				
			||||||
	@(cd src; $(MAKE) TARGETOS=windows32 CC=x86_64-w64-mingw32-gcc clean all)
 | 
						@$(MAKE) -C src TARGETOS=windows32 CC=x86_64-w64-mingw32-gcc clean all
 | 
				
			||||||
	@x86_64-w64-mingw32-strip bin/iodine*
 | 
						@x86_64-w64-mingw32-strip bin/iodine*
 | 
				
			||||||
	@for i in `ls bin`; do cp bin/$$i iodine-latest-windows/64bit/$$i.exe; done
 | 
						@for i in `ls bin`; do cp bin/$$i iodine-latest-windows/64bit/$$i.exe; done
 | 
				
			||||||
	@cp /usr/x86_64-w64-mingw32/bin/zlib1.dll iodine-latest-windows/64bit
 | 
						@cp /usr/x86_64-w64-mingw32/bin/zlib1.dll iodine-latest-windows/64bit
 | 
				
			||||||
	@cp README-win32.txt iodine-latest-windows
 | 
						@cp README-win32.txt iodine-latest-windows
 | 
				
			||||||
	@zip -r iodine-latest-windows.zip iodine-latest-windows
 | 
						@zip -r iodine-latest-windows.zip iodine-latest-windows
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cross-mingw:
 | 
					 | 
				
			||||||
	@(cd src; $(MAKE) TARGETOS=windows32 CC=i686-mingw32-gcc all)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
iodine-latest-win32.zip: cross-mingw iodine-latest
 | 
					 | 
				
			||||||
	@mv iodine-latest iodine-latest-win32
 | 
					 | 
				
			||||||
	@mkdir -p iodine-latest-win32/bin
 | 
					 | 
				
			||||||
	@i686-mingw32-strip bin/iodine*
 | 
					 | 
				
			||||||
	@for i in `ls bin`; do cp bin/$$i iodine-latest-win32/bin/$$i.exe; done
 | 
					 | 
				
			||||||
	@cp /usr/i686-mingw32/usr/bin/zlib1.dll iodine-latest-win32/bin
 | 
					 | 
				
			||||||
	@cp README-win32.txt iodine-latest-win32
 | 
					 | 
				
			||||||
	@zip -r iodine-latest-win32.zip iodine-latest-win32
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										379
									
								
								README
								
								
								
								
							
							
						
						
									
										379
									
								
								README
								
								
								
								
							| 
						 | 
					@ -1,379 +0,0 @@
 | 
				
			||||||
 | 
					 | 
				
			||||||
iodine - http://code.kryo.se/iodine
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
***********************************
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This is a piece of software that lets you tunnel IPv4 data through a DNS
 | 
					 | 
				
			||||||
server. This can be usable in different situations where internet access is
 | 
					 | 
				
			||||||
firewalled, but DNS queries are allowed.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
COMPILING:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Iodine has no configure script. There are two optional features for Linux
 | 
					 | 
				
			||||||
(SELinux and systemd support) that will be enabled automatically if the
 | 
					 | 
				
			||||||
relevant header files are found in /usr/include. (See script at ./src/osflags)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Run 'make' to compile the server and client binaries.
 | 
					 | 
				
			||||||
Run 'make install' to copy binaries and manpage to the destination directory.
 | 
					 | 
				
			||||||
Run 'make test' to compile and run the unit tests. (Requires the check library)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
QUICKSTART:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Try it out within your own LAN! Follow these simple steps:
 | 
					 | 
				
			||||||
- On your server, run: ./iodined -f 10.0.0.1 test.com
 | 
					 | 
				
			||||||
  (If you already use the 10.0.0.0 network, use another internal net like 
 | 
					 | 
				
			||||||
  172.16.0.0)
 | 
					 | 
				
			||||||
- Enter a password
 | 
					 | 
				
			||||||
- On the client, run: ./iodine -f -r 192.168.0.1 test.com
 | 
					 | 
				
			||||||
  (Replace 192.168.0.1 with your server's ip address)
 | 
					 | 
				
			||||||
- Enter the same password
 | 
					 | 
				
			||||||
- Now the client has the tunnel ip 10.0.0.2 and the server has 10.0.0.1
 | 
					 | 
				
			||||||
- Try pinging each other through the tunnel
 | 
					 | 
				
			||||||
- Done! :)
 | 
					 | 
				
			||||||
To actually use it through a relaying nameserver, see below.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
HOW TO USE:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Note: server and client are required to speak the exact same protocol. In most
 | 
					 | 
				
			||||||
cases, this means running the same iodine version. Unfortunately, implementing
 | 
					 | 
				
			||||||
backward and forward protocol compatibility is usually not feasible.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Server side:
 | 
					 | 
				
			||||||
To use this tunnel, you need control over a real domain (like mydomain.com),
 | 
					 | 
				
			||||||
and a server with a public IP address to run iodined on. If this server
 | 
					 | 
				
			||||||
already runs a DNS program, change its listening port and then use iodined's
 | 
					 | 
				
			||||||
-b option to let iodined forward the DNS requests. (Note that this procedure
 | 
					 | 
				
			||||||
is not advised in production environments, because iodined's DNS forwarding
 | 
					 | 
				
			||||||
is not completely transparent.)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Then, delegate a subdomain (say, t1.mydomain.com) to the iodined server.
 | 
					 | 
				
			||||||
If you use BIND for your domain, add two lines like these to the zone file:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
t1		IN	NS	t1ns.mydomain.com.		; note the dot!
 | 
					 | 
				
			||||||
t1ns		IN	A	10.15.213.99
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The "NS" line is all that's needed to route queries for the "t1" subdomain
 | 
					 | 
				
			||||||
to the "t1ns" server. We use a short name for the subdomain, to keep as much
 | 
					 | 
				
			||||||
space as possible available for the data traffic. At the end of the "NS" line
 | 
					 | 
				
			||||||
is the name of your iodined server. This can be any name, pointing anywhere,
 | 
					 | 
				
			||||||
but in this case it's easily kept in the same zone file. It must be a name
 | 
					 | 
				
			||||||
(not an IP address), and that name itself must have an A record (not a CNAME).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If your iodined server has a dynamic IP, use a dynamic dns provider. Simply
 | 
					 | 
				
			||||||
point the "NS" line to it, and leave the "A" line out:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
t1		IN	NS	myname.mydyndnsprovider.com.	; note the dot!
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Then reload or restart your nameserver program. Now any DNS queries for
 | 
					 | 
				
			||||||
domains ending in t1.mydomain.com will be sent to your iodined server.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Finally start iodined on your server. The first argument is the IP address
 | 
					 | 
				
			||||||
inside the tunnel, which can be from any range that you don't use yet (for
 | 
					 | 
				
			||||||
example 192.168.99.1), and the second argument is the assigned domain (in this
 | 
					 | 
				
			||||||
case t1.mydomain.com). Using the -f option will keep iodined running in the
 | 
					 | 
				
			||||||
foreground, which helps when testing. iodined will open a virtual interface
 | 
					 | 
				
			||||||
("tun device"), and will also start listening for DNS queries on UDP port 53.
 | 
					 | 
				
			||||||
Either enter a password on the commandline (-P pass) or after the server has
 | 
					 | 
				
			||||||
started. Now everything is ready for the client.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If there is a chance you'll be using an iodine tunnel from unexpected
 | 
					 | 
				
			||||||
environments, start iodined with a -c option.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Resulting commandline in this example situation:
 | 
					 | 
				
			||||||
./iodined -f -c -P secretpassword 192.168.99.1 t1.mydomain.com
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Client side: 
 | 
					 | 
				
			||||||
All the setup is done, just start iodine. It takes one or two arguments, the
 | 
					 | 
				
			||||||
first is the local relaying DNS server (optional) and the second is the domain
 | 
					 | 
				
			||||||
you used (t1.mydomain.com). If you don't specify the first argument, the
 | 
					 | 
				
			||||||
system's current DNS setting will be consulted.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If DNS queries are allowed to any computer, you can directly give the iodined
 | 
					 | 
				
			||||||
server's address as first argument (in the example: t1ns.mydomain.com or
 | 
					 | 
				
			||||||
10.15.213.99). In that case, it may also happen that _any_ traffic is allowed
 | 
					 | 
				
			||||||
to the DNS port (53 UDP) of any computer. Iodine will detect this, and switch
 | 
					 | 
				
			||||||
to raw UDP tunneling if possible. To force DNS tunneling in any case, use the
 | 
					 | 
				
			||||||
-r option (especially useful when testing within your own network).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The client's tunnel interface will get an IP close to the server's (in this
 | 
					 | 
				
			||||||
case 192.168.99.2 or .3 etc.) and a suitable MTU. Enter the same password as
 | 
					 | 
				
			||||||
on the server either as commandline option or after the client has started.
 | 
					 | 
				
			||||||
Using the -f option will keep the iodine client running in the foreground.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Resulting commandline in this example situation:
 | 
					 | 
				
			||||||
./iodine -f -P secretpassword t1.mydomain.com
 | 
					 | 
				
			||||||
(add -r to force DNS tunneling even if raw UDP tunneling would be possible)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
From either side, you should now be able to ping the IP address on the other
 | 
					 | 
				
			||||||
end of the tunnel. In this case, ping 192.168.99.1 from the iodine client, and
 | 
					 | 
				
			||||||
192.168.99.2 or .3 etc. from the iodine server.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
MISC. INFO:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
IPv6:
 | 
					 | 
				
			||||||
At the moment the iodined server only supports IPv4. The data inside the tunnel
 | 
					 | 
				
			||||||
is IPv4 only.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The client can use IPv4 or IPv6 nameservers to connect to iodined. The relay
 | 
					 | 
				
			||||||
nameservers will translate between protocols automatically if needed. Use
 | 
					 | 
				
			||||||
options -4 or -6 to force the client to use a specific IP version for its DNS
 | 
					 | 
				
			||||||
queries. The client has to force IPv4 if it has dual-stack connectivity and
 | 
					 | 
				
			||||||
the hostname handling the tunnel domain has both A and AAAA records.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Routing:
 | 
					 | 
				
			||||||
It is possible to route all traffic through the DNS tunnel. To do this, first
 | 
					 | 
				
			||||||
add a host route to the nameserver used by iodine over the wired/wireless
 | 
					 | 
				
			||||||
interface with the default gateway as gateway. Then replace the default
 | 
					 | 
				
			||||||
gateway with the iodined server's IP address inside the DNS tunnel, and
 | 
					 | 
				
			||||||
configure the server to do NAT.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
However, note that the tunneled data traffic is not encrypted at all, and can
 | 
					 | 
				
			||||||
be read and changed by external parties relatively easily. For maximum
 | 
					 | 
				
			||||||
security, run a VPN through the DNS tunnel (=double tunneling), or use secure
 | 
					 | 
				
			||||||
shell (SSH) access, possibly with port forwarding. The latter can also be used
 | 
					 | 
				
			||||||
for web browsing, when you run a web proxy (for example Privoxy) on your
 | 
					 | 
				
			||||||
server.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Testing:
 | 
					 | 
				
			||||||
The iodined server replies to NS requests sent for subdomains of the tunnel
 | 
					 | 
				
			||||||
domain. If your iodined subdomain is t1.mydomain.com, send a NS request for
 | 
					 | 
				
			||||||
foo123.t1.mydomain.com to see if the delegation works. dig is a good tool
 | 
					 | 
				
			||||||
for this:
 | 
					 | 
				
			||||||
dig -t NS foo123.t1.mydomain.com
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Also, the iodined server will answer requests starting with 'z' for any of the
 | 
					 | 
				
			||||||
supported request types, for example:
 | 
					 | 
				
			||||||
dig -t TXT z456.t1.mydomain.com
 | 
					 | 
				
			||||||
dig -t SRV z456.t1.mydomain.com
 | 
					 | 
				
			||||||
dig -t CNAME z456.t1.mydomain.com
 | 
					 | 
				
			||||||
The reply should look like garbled text in all these cases.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Operational info:
 | 
					 | 
				
			||||||
The DNS-response fragment size is normally autoprobed to get maximum bandwidth.
 | 
					 | 
				
			||||||
To force a specific value (and speed things up), use the -m option.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The DNS hostnames are normally used up to their maximum length, 255 characters.
 | 
					 | 
				
			||||||
Some DNS relays have been found that answer full-length queries rather
 | 
					 | 
				
			||||||
unreliably, giving widely varying (and mostly very bad) results of the
 | 
					 | 
				
			||||||
fragment size autoprobe on repeated tries. In these cases, use the -M switch
 | 
					 | 
				
			||||||
to reduce the DNS hostname length to for example 200 characters, which makes
 | 
					 | 
				
			||||||
these DNS relays much more stable. This is also useful on some "de-optimizing"
 | 
					 | 
				
			||||||
DNS relays that stuff the response with two full copies of the query, leaving
 | 
					 | 
				
			||||||
very little space for downstream data (also not capable of EDNS0). The -M
 | 
					 | 
				
			||||||
switch can trade some upstream bandwidth for downstream bandwidth. Note that
 | 
					 | 
				
			||||||
the minimum -M value is about 100, since the protocol can split packets (1200
 | 
					 | 
				
			||||||
bytes max) in only 16 fragments, requiring at least 75 real data bytes per
 | 
					 | 
				
			||||||
fragment.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The upstream data is sent gzipped encoded with Base32; or Base64 if the relay
 | 
					 | 
				
			||||||
server supports mixed case and '+' in domain names; or Base64u if '_' is
 | 
					 | 
				
			||||||
supported instead; or Base128 if high-byte-value characters are supported.
 | 
					 | 
				
			||||||
This upstream encoding is autodetected. The DNS protocol allows one query per
 | 
					 | 
				
			||||||
packet, and one query can be max 256 chars. Each domain name part can be max
 | 
					 | 
				
			||||||
63 chars. So your domain name and subdomain should be as short as possible to
 | 
					 | 
				
			||||||
allow maximum upstream throughput.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Several DNS request types are supported, with the NULL and PRIVATE types
 | 
					 | 
				
			||||||
expected to provide the largest downstream bandwidth. The PRIVATE type uses
 | 
					 | 
				
			||||||
value 65399 in the private-use range. Other available types are TXT, SRV, MX,
 | 
					 | 
				
			||||||
CNAME and A (returning CNAME), in decreasing bandwidth order.  Normally the
 | 
					 | 
				
			||||||
"best" request type is autodetected and used. However, DNS relays may impose
 | 
					 | 
				
			||||||
limits on for example NULL and TXT, making SRV or MX actually the best choice.
 | 
					 | 
				
			||||||
This is not autodetected, but can be forced using the -T option.  It is
 | 
					 | 
				
			||||||
advisable to try various alternatives especially when the autodetected request
 | 
					 | 
				
			||||||
type provides a downstream fragment size of less than 200 bytes.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Note that SRV, MX and A (returning CNAME) queries may/will cause additional
 | 
					 | 
				
			||||||
lookups by "smart" caching nameservers to get an actual IP address, which may
 | 
					 | 
				
			||||||
either slow down or fail completely.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
DNS responses for non-NULL/PRIVATE queries can be encoded with the same set of
 | 
					 | 
				
			||||||
codecs as upstream data. This is normally also autodetected, but no fully
 | 
					 | 
				
			||||||
exhaustive tests are done, so some problems may not be noticed when selecting
 | 
					 | 
				
			||||||
more advanced codecs. In that case, you'll see failures/corruption in the
 | 
					 | 
				
			||||||
fragment size autoprobe. In particular, several DNS relays have been found that
 | 
					 | 
				
			||||||
change replies returning hostnames (SRV, MX, CNAME, A) to lowercase only when
 | 
					 | 
				
			||||||
that hostname exceeds ca. 180 characters. In these and similar cases, use the
 | 
					 | 
				
			||||||
-O option to try other downstream codecs; Base32 should always work.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Normal operation now is for the server to _not_ answer a DNS request until
 | 
					 | 
				
			||||||
the next DNS request has come in, a.k.a. being "lazy". This way, the server
 | 
					 | 
				
			||||||
will always have a DNS request handy when new downstream data has to be sent.
 | 
					 | 
				
			||||||
This greatly improves (interactive) performance and latency, and allows to
 | 
					 | 
				
			||||||
slow down the quiescent ping requests to 4 second intervals by default, and
 | 
					 | 
				
			||||||
possibly much slower. In fact, the main purpose of the pings now is to force
 | 
					 | 
				
			||||||
a reply to the previous ping, and prevent DNS server timeouts (usually at
 | 
					 | 
				
			||||||
least 5-10 seconds per RFC1035). Some DNS servers are more impatient and will
 | 
					 | 
				
			||||||
give SERVFAIL errors (timeouts) in periods without tunneled data traffic. All
 | 
					 | 
				
			||||||
data should still get through in these cases, but iodine will reduce the ping
 | 
					 | 
				
			||||||
interval to 1 second anyway (-I1) to reduce the number of error messages. This
 | 
					 | 
				
			||||||
may not help for very impatient DNS relays like dnsadvantage.com (ultradns),
 | 
					 | 
				
			||||||
which time out in 1 second or even less. Yet data will still get trough, and
 | 
					 | 
				
			||||||
you can ignore the SERVFAIL errors.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If you are running on a local network without any DNS server in-between, try
 | 
					 | 
				
			||||||
-I 50 (iodine and iodined close the connection after 60 seconds of silence).
 | 
					 | 
				
			||||||
The only time you'll notice a slowdown, is when DNS reply packets go missing;
 | 
					 | 
				
			||||||
the iodined server then has to wait for a new ping to re-send the data. You can
 | 
					 | 
				
			||||||
speed this up by generating some upstream traffic (keypress, ping). If this
 | 
					 | 
				
			||||||
happens often, check your network for bottlenecks and/or run with -I1.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The delayed answering in lazy mode will cause some "carrier grade" commercial
 | 
					 | 
				
			||||||
DNS relays to repeatedly re-send the same DNS query to the iodined server.
 | 
					 | 
				
			||||||
If the DNS relay is actually implemented as a pool of parallel servers,
 | 
					 | 
				
			||||||
duplicate requests may even arrive from multiple sources. This effect will
 | 
					 | 
				
			||||||
only be visible in the network traffic at the iodined server, and will not
 | 
					 | 
				
			||||||
affect the client's connection. Iodined will notice these duplicates, and send
 | 
					 | 
				
			||||||
the same answer (when its time has come) to both the original query and the
 | 
					 | 
				
			||||||
latest duplicate. After that, the full answer is cached for a short while.
 | 
					 | 
				
			||||||
Delayed duplicates that arrive at the server even later, get a reply that the
 | 
					 | 
				
			||||||
iodine client will ignore (if it ever arrives there).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If you have problems, try inspecting the traffic with network monitoring tools
 | 
					 | 
				
			||||||
like tcpdump or ethereal/wireshark, and make sure that the relaying DNS server
 | 
					 | 
				
			||||||
has not cached the response. A cached error message could mean that you
 | 
					 | 
				
			||||||
started the client before the server. The -D (and -DD) option on the server
 | 
					 | 
				
			||||||
can also show received and sent queries.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TIPS & TRICKS:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If your port 53 is taken on a specific interface by an application that does 
 | 
					 | 
				
			||||||
not use it, use -p on iodined to specify an alternate port (like -p 5353) and 
 | 
					 | 
				
			||||||
use for instance iptables (on Linux) to forward the traffic:
 | 
					 | 
				
			||||||
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 53 -j DNAT --to :5353
 | 
					 | 
				
			||||||
(Sent in by Tom Schouten)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Iodined will reject data from clients that have not been active (data/pings)
 | 
					 | 
				
			||||||
for more than 60 seconds. Similarly, iodine will exit when no downstream
 | 
					 | 
				
			||||||
data has been received for 60 seconds. In case of a long network outage or
 | 
					 | 
				
			||||||
similar, just restart iodine (re-login), possibly multiple times until you get
 | 
					 | 
				
			||||||
your old IP address back. Once that's done, just wait a while, and you'll
 | 
					 | 
				
			||||||
eventually see the tunneled TCP traffic continue to flow from where it left
 | 
					 | 
				
			||||||
off before the outage.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
With the introduction of the downstream packet queue in the server, its memory
 | 
					 | 
				
			||||||
usage has increased with several megabytes in the default configuration.
 | 
					 | 
				
			||||||
For use in low-memory environments (e.g. running on your DSL router), you can
 | 
					 | 
				
			||||||
decrease USERS and undefine OUTPACKETQ_LEN in user.h without any ill conse-
 | 
					 | 
				
			||||||
quence, assuming at most one client will be connected at any time. A small
 | 
					 | 
				
			||||||
DNSCACHE_LEN is still advised, preferably 2 or higher, however you can also
 | 
					 | 
				
			||||||
undefine it to save a few more kilobytes.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PERFORMANCE:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This section tabulates some performance measurements. To view properly, use
 | 
					 | 
				
			||||||
a fixed-width font like Courier.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Measurements were done in protocol 00000502 in lazy mode; upstream encoding
 | 
					 | 
				
			||||||
always Base128; iodine -M255; iodined -m1130. Network conditions were not
 | 
					 | 
				
			||||||
extremely favorable; results are not benchmarks but a realistic indication of
 | 
					 | 
				
			||||||
real-world performance that can be expected in similar situations.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Upstream/downstream throughput was measured by scp'ing a file previously
 | 
					 | 
				
			||||||
read from /dev/urandom (i.e. incompressible), and measuring size with
 | 
					 | 
				
			||||||
"ls -l ; sleep 30 ; ls -l" on a separate non-tunneled connection. Given the
 | 
					 | 
				
			||||||
large scp block size of 16 kB, this gives a resolution of 4.3 kbit/s, which
 | 
					 | 
				
			||||||
explains why some values are exactly equal.
 | 
					 | 
				
			||||||
Ping round-trip times measured with "ping -c100", presented are average rtt
 | 
					 | 
				
			||||||
and mean deviation (indicating spread around the average), in milliseconds.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Situation 1:
 | 
					 | 
				
			||||||
Laptop  ->   Wifi AP   ->  Home server  ->  DSL provider  ->  Datacenter
 | 
					 | 
				
			||||||
 iodine    DNS "relay"        bind9           DNS cache        iodined
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        downstr.  upstream downstr.  ping-up       ping-down
 | 
					 | 
				
			||||||
                        fragsize   kbit/s   kbit/s  avg +/-mdev   avg +/-mdev
 | 
					 | 
				
			||||||
------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
iodine -> Wifi AP :53
 | 
					 | 
				
			||||||
  -Tnull (= -Oraw)           982    43.6    131.0   28.0    4.6   26.8    3.4
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
iodine -> Home server :53
 | 
					 | 
				
			||||||
  -Tnull (= -Oraw)          1174    48.0    305.8   26.6    5.0   26.9    8.4
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
iodine -> DSL provider :53  
 | 
					 | 
				
			||||||
  -Tnull (= -Oraw)          1174    56.7    367.0   20.6    3.1   21.2    4.4
 | 
					 | 
				
			||||||
  -Ttxt -Obase32             730    56.7    174.7*
 | 
					 | 
				
			||||||
  -Ttxt -Obase64             874    56.7    174.7
 | 
					 | 
				
			||||||
  -Ttxt -Obase128           1018    56.7    174.7
 | 
					 | 
				
			||||||
  -Ttxt -Oraw               1162    56.7    358.2
 | 
					 | 
				
			||||||
  -Tsrv -Obase128            910    56.7    174.7
 | 
					 | 
				
			||||||
  -Tcname -Obase32           151    56.7     43.6
 | 
					 | 
				
			||||||
  -Tcname -Obase128          212    56.7     52.4
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
iodine -> DSL provider :53  
 | 
					 | 
				
			||||||
  wired (no Wifi) -Tnull    1174    74.2    585.4   20.2    5.6   19.6    3.4
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 [174.7* : these all have 2frag/packet]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Situation 2:
 | 
					 | 
				
			||||||
Laptop  ->  Wifi+vpn / wired  ->  Home server
 | 
					 | 
				
			||||||
 iodine                            iodined
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        downstr.  upstream downstr.  ping-up       ping-down
 | 
					 | 
				
			||||||
                        fragsize   kbit/s   kbit/s  avg +/-mdev   avg +/-mdev
 | 
					 | 
				
			||||||
------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
wifi + openvpn  -Tnull      1186   166.0   1022.3    6.3    1.3    6.6    1.6
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
wired  -Tnull               1186   677.2   2464.1    1.3    0.2    1.3    0.1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Performance is strongly coupled to low ping times, as iodine requires
 | 
					 | 
				
			||||||
confirmation for every data fragment before moving on to the next. Allowing
 | 
					 | 
				
			||||||
multiple fragments in-flight like TCP could possibly increase performance,
 | 
					 | 
				
			||||||
but it would likely cause serious overload for the intermediary DNS servers.
 | 
					 | 
				
			||||||
The current protocol scales performance with DNS responsivity, since the
 | 
					 | 
				
			||||||
DNS servers are on average handling at most one DNS request per client.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PORTABILITY:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
iodine has been tested on Linux (arm, ia64, x86, AMD64 and SPARC64), FreeBSD
 | 
					 | 
				
			||||||
(ia64, x86), OpenBSD (x86), NetBSD (x86), MacOS X (ppc and x86, with
 | 
					 | 
				
			||||||
http://tuntaposx.sourceforge.net/). and Windows (with OpenVPN TAP32 driver, see
 | 
					 | 
				
			||||||
win32 readme file).  It should be easy to port to other unix-like systems that
 | 
					 | 
				
			||||||
has TUN/TAP tunneling support. Let us know if you get it to run on other
 | 
					 | 
				
			||||||
platforms. 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
THE NAME:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The name iodine was chosen since it starts with IOD (IP Over DNS) and since
 | 
					 | 
				
			||||||
iodine has atomic number 53, which happens to be the DNS port number.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
THANKS:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- To kuxien for FreeBSD and OS X testing
 | 
					 | 
				
			||||||
- To poplix for code audit
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
AUTHORS & LICENSE:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>, 2006-2009 Bjorn
 | 
					 | 
				
			||||||
Andersson <flex@kryo.se>. Also major contributions by Anne Bezemer.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Permission to use, copy, modify, and distribute this software for any purpose
 | 
					 | 
				
			||||||
with or without fee is hereby granted, provided that the above copyright notice
 | 
					 | 
				
			||||||
and this permission notice appear in all copies.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 | 
					 | 
				
			||||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
					 | 
				
			||||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
 | 
					 | 
				
			||||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 | 
					 | 
				
			||||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
					 | 
				
			||||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
					 | 
				
			||||||
PERFORMANCE OF THIS SOFTWARE.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
MD5 implementation by L. Peter Deutsch (license and source in src/md5.[ch])
 | 
					 | 
				
			||||||
Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved.
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
iodine - http://code.kryo.se/iodine
 | 
					iodine - https://code.kryo.se/iodine
 | 
				
			||||||
 | 
					
 | 
				
			||||||
***********************************
 | 
					***********************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,9 +37,14 @@ For more information: http://blog.bokhorst.biz/5123
 | 
				
			||||||
3. Build:
 | 
					3. Build:
 | 
				
			||||||
	cd src
 | 
						cd src
 | 
				
			||||||
	make base64u.h base64u.c
 | 
						make base64u.h base64u.c
 | 
				
			||||||
		ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk
 | 
						ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.16.mk APP_PLATFORM=android-16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   or run "make cross-android" in the iodine root directory.
 | 
					   or run "make cross-android" in the iodine root directory.
 | 
				
			||||||
   To build for other archs, specify TARGET_ARCH_ABI:
 | 
					   To build for other archs, specify TARGET_ARCH_ABI:
 | 
				
			||||||
		"make cross-android TARGET_ARCH_ABI=x86"
 | 
							"make cross-android TARGET_ARCH_ABI=x86"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   For older android versions (pre-kitkat), build with "make cross-android-old" in the
 | 
				
			||||||
 | 
					   root directory, or manually like above but with APP_PLATFORM=android-3 and with
 | 
				
			||||||
 | 
					   APP_BUILD_SCRIPT=Android.mk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   The iodine binary ends up in src/libs/<arch>/iodine
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
iodine - http://code.kryo.se/iodine
 | 
					iodine - https://code.kryo.se/iodine
 | 
				
			||||||
 | 
					
 | 
				
			||||||
***********************************
 | 
					***********************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,10 +11,11 @@ Extra README file for Win32 related stuff
 | 
				
			||||||
 | 
					
 | 
				
			||||||
0. After iodine 0.6, you need Windows XP or newer to run.
 | 
					0. After iodine 0.6, you need Windows XP or newer to run.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. Install the TAP32 driver 
 | 
					1. Install the TAP driver 
 | 
				
			||||||
   http://openvpn.net/index.php/open-source/downloads.html
 | 
					   https://openvpn.net/index.php/open-source/downloads.html
 | 
				
			||||||
   Choose OpenVPN 2.0.9 Windows Installer, when installing you can
 | 
					   Download the OpenVPN TAP driver (under section Tap-windows)
 | 
				
			||||||
   select to install only the TAP driver.
 | 
					   Problems has been reported with the NDIS6 version (9.2x.y), use the
 | 
				
			||||||
 | 
					   NDIS5 version for now if possible.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
2. Have at least one TAP32 interface installed. There are scripts for adding
 | 
					2. Have at least one TAP32 interface installed. There are scripts for adding
 | 
				
			||||||
   and removing in the OpenVPN bin directory. If you have more than one
 | 
					   and removing in the OpenVPN bin directory. If you have more than one
 | 
				
			||||||
| 
						 | 
					@ -46,7 +47,7 @@ Note that the binaries will not get a .exe suffix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
== Zlib download
 | 
					== Zlib download
 | 
				
			||||||
You can get zlib for MinGW here (both for native and crosscompile):
 | 
					You can get zlib for MinGW here (both for native and crosscompile):
 | 
				
			||||||
http://code.kryo.se/iodine/deps/zlib.zip
 | 
					https://code.kryo.se/iodine/deps/zlib.zip
 | 
				
			||||||
Unzip it in your MinGW directory on Windows or in $ROOT/usr for
 | 
					Unzip it in your MinGW directory on Windows or in $ROOT/usr for
 | 
				
			||||||
cross-compile.
 | 
					cross-compile.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,423 @@
 | 
				
			||||||
 | 
					iodine - <https://code.kryo.se/iodine>
 | 
				
			||||||
 | 
					=====================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This is a piece of software that lets you tunnel IPv4 data through a DNS
 | 
				
			||||||
 | 
					server. This can be usable in different situations where internet access is
 | 
				
			||||||
 | 
					firewalled, but DNS queries are allowed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					COMPILING
 | 
				
			||||||
 | 
					---------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Iodine has no configure script. There are two optional features for Linux
 | 
				
			||||||
 | 
					(SELinux and systemd support) that will be enabled automatically if the
 | 
				
			||||||
 | 
					relevant header files are found in `/usr/include`.
 | 
				
			||||||
 | 
					(See script at `./src/osflags`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Run `make` to compile the server and client binaries.
 | 
				
			||||||
 | 
					Run `make install` to copy binaries and manpage to the destination directory.
 | 
				
			||||||
 | 
					Run `make test` to compile and run the unit tests. (Requires the `check` library)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QUICKSTART
 | 
				
			||||||
 | 
					----------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Try it out within your own LAN! Follow these simple steps:
 | 
				
			||||||
 | 
					- On your server, run: `./iodined -f 10.0.0.1 test.com`.
 | 
				
			||||||
 | 
					  If you already use the `10.0.0.0` network, use another internal net like
 | 
				
			||||||
 | 
					  `172.16.0.0`.
 | 
				
			||||||
 | 
					- Enter a password.
 | 
				
			||||||
 | 
					- On the client, run: `./iodine -f -r 192.168.0.1 test.com`.
 | 
				
			||||||
 | 
					  Replace `192.168.0.1` with your server's ip address.
 | 
				
			||||||
 | 
					- Enter the same password.
 | 
				
			||||||
 | 
					- Now the client has the tunnel ip `10.0.0.2` and the server has `10.0.0.1`.
 | 
				
			||||||
 | 
					- Try pinging each other through the tunnel.
 | 
				
			||||||
 | 
					- Done! :)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To actually use it through a relaying nameserver, see below.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HOW TO USE
 | 
				
			||||||
 | 
					----------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note: server and client are required to speak the exact same protocol. In most
 | 
				
			||||||
 | 
					cases, this means running the same iodine version. Unfortunately, implementing
 | 
				
			||||||
 | 
					backward and forward protocol compatibility is usually not feasible.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Server side
 | 
				
			||||||
 | 
					To use this tunnel, you need control over a real domain (like `mydomain.com`),
 | 
				
			||||||
 | 
					and a server with a public IP address to run `iodined` on. If this server
 | 
				
			||||||
 | 
					already runs a DNS program, change its listening port and then use `iodined`'s
 | 
				
			||||||
 | 
					`-b` option to let `iodined` forward the DNS requests. (Note that this procedure
 | 
				
			||||||
 | 
					is not advised in production environments, because `iodined`'s DNS forwarding
 | 
				
			||||||
 | 
					is not completely transparent, for example zone transfers will not work.)
 | 
				
			||||||
 | 
					Alternatively you can forward the subdomain from your DNS server to `iodined`
 | 
				
			||||||
 | 
					which must then run on a different port (`-p`).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Then, delegate a subdomain (say, `t1.mydomain.com`) to the iodined server.
 | 
				
			||||||
 | 
					If you use BIND for your domain, add two lines like these to the zone file:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t1		IN	NS	t1ns.mydomain.com.		; note the dot!
 | 
				
			||||||
 | 
						t1ns		IN	A	10.15.213.99
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The `NS` line is all that's needed to route queries for the `t1` subdomain
 | 
				
			||||||
 | 
					to the `t1ns` server. We use a short name for the subdomain, to keep as much
 | 
				
			||||||
 | 
					space as possible available for the data traffic. At the end of the `NS` line
 | 
				
			||||||
 | 
					is the name of your `iodined` server. This can be any name, pointing anywhere,
 | 
				
			||||||
 | 
					but in this case it's easily kept in the same zone file. It must be a name
 | 
				
			||||||
 | 
					(not an IP address), and that name itself must have an `A` record
 | 
				
			||||||
 | 
					(not a `CNAME`).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If your `iodined` server has a dynamic IP, use a dynamic DNS provider. Simply
 | 
				
			||||||
 | 
					point the `NS` line to it, and leave the `A` line out:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t1		IN	NS	myname.mydyndnsprovider.com.	; note the dot!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Then reload or restart your nameserver program. Now any DNS queries for
 | 
				
			||||||
 | 
					domains ending in `t1.mydomain.com` will be sent to your `iodined` server.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Finally start `iodined` on your server. The first argument is the IP address
 | 
				
			||||||
 | 
					inside the tunnel, which can be from any range that you don't use yet (for
 | 
				
			||||||
 | 
					example `192.168.99.1`), and the second argument is the assigned domain (in this
 | 
				
			||||||
 | 
					case `t1.mydomain.com`). Using the `-f` option will keep iodined running in the
 | 
				
			||||||
 | 
					foreground, which helps when testing. iodined will open a virtual interface
 | 
				
			||||||
 | 
					("tun device"), and will also start listening for DNS queries on UDP port 53.
 | 
				
			||||||
 | 
					Either enter a password on the commandline (`-P pass`) or after the server has
 | 
				
			||||||
 | 
					started. Now everything is ready for the client.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If there is a chance you'll be using an iodine tunnel from unexpected
 | 
				
			||||||
 | 
					environments, start `iodined` with a `-c` option.
 | 
				
			||||||
 | 
					Resulting commandline in this example situation:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						./iodined -f -c -P secretpassword 192.168.99.1 t1.mydomain.com
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Client side
 | 
				
			||||||
 | 
					All the setup is done, just start `iodine`. It takes one or two arguments, the
 | 
				
			||||||
 | 
					first is the local relaying DNS server (optional) and the second is the domain
 | 
				
			||||||
 | 
					you used (`t1.mydomain.com`). If you don't specify the first argument, the
 | 
				
			||||||
 | 
					system's current DNS setting will be consulted.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If DNS queries are allowed to any computer, you can directly give the `iodined`
 | 
				
			||||||
 | 
					server's address as first argument (in the example: `t1ns.mydomain.com` or
 | 
				
			||||||
 | 
					`10.15.213.99`). In that case, it may also happen that _any_ traffic is allowed
 | 
				
			||||||
 | 
					to the DNS port (53 UDP) of any computer. Iodine will detect this, and switch
 | 
				
			||||||
 | 
					to raw UDP tunneling if possible. To force DNS tunneling in any case, use the
 | 
				
			||||||
 | 
					`-r` option (especially useful when testing within your own network).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The client's tunnel interface will get an IP close to the server's (in this
 | 
				
			||||||
 | 
					case `192.168.99.2` or `.3` etc.) and a suitable MTU. Enter the same password as
 | 
				
			||||||
 | 
					on the server either as commandline option or after the client has started.
 | 
				
			||||||
 | 
					Using the `-f` option will keep the iodine client running in the foreground.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Resulting commandline in this example situation, adding -r forces DNS tunneling
 | 
				
			||||||
 | 
					even if raw UDP tunneling would be possible:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						./iodine -f -P secretpassword t1.mydomain.com
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					From either side, you should now be able to ping the IP address on the other
 | 
				
			||||||
 | 
					end of the tunnel. In this case, `ping 192.168.99.1` from the iodine client, and
 | 
				
			||||||
 | 
					`192.168.99.2` from the iodine server.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### MISC. INFO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### IPv6
 | 
				
			||||||
 | 
					The data inside the tunnel is IPv4 only.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The server listens to both IPv4 and IPv6 for incoming requests by default.
 | 
				
			||||||
 | 
					Use options `-4` or `-6` to only listen on one protocol. Raw mode will be
 | 
				
			||||||
 | 
					attempted on the same protocol as used for the login.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The client can use IPv4 or IPv6 nameservers to connect to iodined. The relay
 | 
				
			||||||
 | 
					nameservers will translate between protocols automatically if needed. Use
 | 
				
			||||||
 | 
					options `-4` or `-6` to force the client to use a specific IP version for its DNS
 | 
				
			||||||
 | 
					queries.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If your server is listening on IPv6 and is reachable, add an AAAA record for it
 | 
				
			||||||
 | 
					to your DNS setup. Extending the example above would look like this:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t1		IN	NS	t1ns.mydomain.com.		; note the dot!
 | 
				
			||||||
 | 
						t1ns		IN	A	10.15.213.99
 | 
				
			||||||
 | 
						t1ns		IN	AAAA	2001:db8::1001:99
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Routing
 | 
				
			||||||
 | 
					It is possible to route all traffic through the DNS tunnel. To do this, first
 | 
				
			||||||
 | 
					add a host route to the nameserver used by iodine over the wired/wireless
 | 
				
			||||||
 | 
					interface with the default gateway as gateway. Then replace the default
 | 
				
			||||||
 | 
					gateway with the iodined server's IP address inside the DNS tunnel, and
 | 
				
			||||||
 | 
					configure the server to do NAT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					However, note that the tunneled data traffic is not encrypted at all, and can
 | 
				
			||||||
 | 
					be read and changed by external parties relatively easily. For maximum
 | 
				
			||||||
 | 
					security, run a VPN through the DNS tunnel (=double tunneling), or use secure
 | 
				
			||||||
 | 
					shell (SSH) access, possibly with port forwarding. The latter can also be used
 | 
				
			||||||
 | 
					for web browsing, when you run a web proxy (for example Privoxy) on your
 | 
				
			||||||
 | 
					server.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Testing
 | 
				
			||||||
 | 
					The `iodined` server replies to `NS` requests sent for subdomains of the tunnel
 | 
				
			||||||
 | 
					domain. If your iodined subdomain is `t1.mydomain.com`, send a `NS` request for
 | 
				
			||||||
 | 
					`foo123.t1.mydomain.com` to see if the delegation works.
 | 
				
			||||||
 | 
					`dig` is a good tool for this:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						% dig -t NS foo123.t1.mydomain.com
 | 
				
			||||||
 | 
						ns.io.citronna.de.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Also, the iodined server will answer requests starting with 'z' for any of the
 | 
				
			||||||
 | 
					supported request types, for example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dig -t TXT z456.t1.mydomain.com
 | 
				
			||||||
 | 
						dig -t SRV z456.t1.mydomain.com
 | 
				
			||||||
 | 
						dig -t CNAME z456.t1.mydomain.com
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The reply should look like garbled text in all these cases.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Mac OS X
 | 
				
			||||||
 | 
					On Mac OS X 10.6 and later, iodine supports the native utun devices built into
 | 
				
			||||||
 | 
					the OS - use `-d utunX`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Operational info
 | 
				
			||||||
 | 
					----------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The DNS-response fragment size is normally autoprobed to get maximum bandwidth.
 | 
				
			||||||
 | 
					To force a specific value (and speed things up), use the `-m` option.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The DNS hostnames are normally used up to their maximum length, 255 characters.
 | 
				
			||||||
 | 
					Some DNS relays have been found that answer full-length queries rather
 | 
				
			||||||
 | 
					unreliably, giving widely varying (and mostly very bad) results of the
 | 
				
			||||||
 | 
					fragment size autoprobe on repeated tries. In these cases, use the `-M` switch
 | 
				
			||||||
 | 
					to reduce the DNS hostname length to, for example 200 characters, which makes
 | 
				
			||||||
 | 
					these DNS relays much more stable. This is also useful on some “de-optimizing”
 | 
				
			||||||
 | 
					DNS relays that stuff the response with two full copies of the query, leaving
 | 
				
			||||||
 | 
					very little space for downstream data (also not capable of EDNS0). The `-M`
 | 
				
			||||||
 | 
					switch can trade some upstream bandwidth for downstream bandwidth. Note that
 | 
				
			||||||
 | 
					the minimum `-M` value is about 100, since the protocol can split packets (1200
 | 
				
			||||||
 | 
					bytes max) in only 16 fragments, requiring at least 75 real data bytes per
 | 
				
			||||||
 | 
					fragment.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The upstream data is sent gzipped encoded with Base32; or Base64 if the relay
 | 
				
			||||||
 | 
					server supports mixed case and `+` in domain names; or Base64u if `_` is
 | 
				
			||||||
 | 
					supported instead; or Base128 if high-byte-value characters are supported.
 | 
				
			||||||
 | 
					This upstream encoding is autodetected. The DNS protocol allows one query per
 | 
				
			||||||
 | 
					packet, and one query can be max 256 chars. Each domain name part can be max
 | 
				
			||||||
 | 
					63 chars. So your domain name and subdomain should be as short as possible to
 | 
				
			||||||
 | 
					allow maximum upstream throughput.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Several DNS request types are supported, with the `NULL` and `PRIVATE` types
 | 
				
			||||||
 | 
					expected to provide the largest downstream bandwidth. The `PRIVATE` type uses
 | 
				
			||||||
 | 
					value 65399 in the private-use range. Other available types are `TXT`, `SRV`,
 | 
				
			||||||
 | 
					`MX`, `CNAME` and `A` (returning `CNAME`), in decreasing bandwidth order.
 | 
				
			||||||
 | 
					Normally the “best” request type is autodetected and used. However, DNS relays
 | 
				
			||||||
 | 
					may impose limits on for example NULL and TXT, making SRV or MX actually the best
 | 
				
			||||||
 | 
					choice. This is not autodetected, but can be forced using the `-T` option.
 | 
				
			||||||
 | 
					It is advisable to try various alternatives especially when the autodetected
 | 
				
			||||||
 | 
					request type provides a downstream fragment size of less than 200 bytes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note that `SRV`, `MX` and `A` (returning `CNAME`) queries may/will cause
 | 
				
			||||||
 | 
					additional lookups by "smart" caching nameservers to get an actual IP address,
 | 
				
			||||||
 | 
					which may either slow down or fail completely.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DNS responses for non-`NULL/PRIVATE` queries can be encoded with the same set of
 | 
				
			||||||
 | 
					codecs as upstream data. This is normally also autodetected, but no fully
 | 
				
			||||||
 | 
					exhaustive tests are done, so some problems may not be noticed when selecting
 | 
				
			||||||
 | 
					more advanced codecs. In that case, you'll see failures/corruption in the
 | 
				
			||||||
 | 
					fragment size autoprobe. In particular, several DNS relays have been found that
 | 
				
			||||||
 | 
					change replies returning hostnames (`SRV`, `MX`, `CNAME`, `A`) to lowercase only
 | 
				
			||||||
 | 
					when that hostname exceeds ca. 180 characters. In these and similar cases, use
 | 
				
			||||||
 | 
					the `-O` option to try other downstream codecs; Base32 should always work.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Normal operation now is for the server to _not_ answer a DNS request until
 | 
				
			||||||
 | 
					the next DNS request has come in, a.k.a. being “lazy”. This way, the server
 | 
				
			||||||
 | 
					will always have a DNS request handy when new downstream data has to be sent.
 | 
				
			||||||
 | 
					This greatly improves (interactive) performance and latency, and allows to
 | 
				
			||||||
 | 
					slow down the quiescent ping requests to 4 second intervals by default, and
 | 
				
			||||||
 | 
					possibly much slower. In fact, the main purpose of the pings now is to force
 | 
				
			||||||
 | 
					a reply to the previous ping, and prevent DNS server timeouts (usually at
 | 
				
			||||||
 | 
					least 5-10 seconds per RFC1035). Some DNS servers are more impatient and will
 | 
				
			||||||
 | 
					give SERVFAIL errors (timeouts) in periods without tunneled data traffic. All
 | 
				
			||||||
 | 
					data should still get through in these cases, but `iodine` will reduce the ping
 | 
				
			||||||
 | 
					interval to 1 second anyway (-I1) to reduce the number of error messages. This
 | 
				
			||||||
 | 
					may not help for very impatient DNS relays like `dnsadvantage.com` (ultradns),
 | 
				
			||||||
 | 
					which time out in 1 second or even less. Yet data will still get trough, and
 | 
				
			||||||
 | 
					you can ignore the `SERVFAIL` errors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you are running on a local network without any DNS server in-between, try
 | 
				
			||||||
 | 
					`-I 50` (iodine and iodined close the connection after 60 seconds of silence).
 | 
				
			||||||
 | 
					The only time you'll notice a slowdown, is when DNS reply packets go missing;
 | 
				
			||||||
 | 
					the `iodined` server then has to wait for a new ping to re-send the data. You can
 | 
				
			||||||
 | 
					speed this up by generating some upstream traffic (keypress, ping). If this
 | 
				
			||||||
 | 
					happens often, check your network for bottlenecks and/or run with `-I1`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The delayed answering in lazy mode will cause some “carrier grade” commercial
 | 
				
			||||||
 | 
					DNS relays to repeatedly re-send the same DNS query to the iodined server.
 | 
				
			||||||
 | 
					If the DNS relay is actually implemented as a pool of parallel servers,
 | 
				
			||||||
 | 
					duplicate requests may even arrive from multiple sources. This effect will
 | 
				
			||||||
 | 
					only be visible in the network traffic at the `iodined` server, and will not
 | 
				
			||||||
 | 
					affect the client's connection. Iodined will notice these duplicates, and send
 | 
				
			||||||
 | 
					the same answer (when its time has come) to both the original query and the
 | 
				
			||||||
 | 
					latest duplicate. After that, the full answer is cached for a short while.
 | 
				
			||||||
 | 
					Delayed duplicates that arrive at the server even later, get a reply that the
 | 
				
			||||||
 | 
					iodine client will ignore (if it ever arrives there).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you have problems, try inspecting the traffic with network monitoring tools
 | 
				
			||||||
 | 
					like tcpdump or ethereal/wireshark, and make sure that the relaying DNS server
 | 
				
			||||||
 | 
					has not cached the response. A cached error message could mean that you
 | 
				
			||||||
 | 
					started the client before the server. The `-D` (and `-DD`) option on the server
 | 
				
			||||||
 | 
					can also show received and sent queries.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TIPS & TRICKS
 | 
				
			||||||
 | 
					-------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If your port 53 is taken on a specific interface by an application that does
 | 
				
			||||||
 | 
					not use it, use `-p` on iodined to specify an alternate port (like `-p 5353`)
 | 
				
			||||||
 | 
					and use for instance iptables (on Linux) to forward the traffic:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						iptables -t nat -A PREROUTING -i eth0 -p udp --dport 53 -j DNAT --to :5353
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(Sent in by Tom Schouten)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Iodined will reject data from clients that have not been active (data/pings)
 | 
				
			||||||
 | 
					for more than 60 seconds. Similarly, iodine will exit when no downstream
 | 
				
			||||||
 | 
					data has been received for 60 seconds. In case of a long network outage or
 | 
				
			||||||
 | 
					similar, just restart iodine (re-login), possibly multiple times until you get
 | 
				
			||||||
 | 
					your old IP address back. Once that's done, just wait a while, and you'll
 | 
				
			||||||
 | 
					eventually see the tunneled TCP traffic continue to flow from where it left
 | 
				
			||||||
 | 
					off before the outage.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					With the introduction of the downstream packet queue in the server, its memory
 | 
				
			||||||
 | 
					usage has increased with several megabytes in the default configuration.
 | 
				
			||||||
 | 
					For use in low-memory environments (e.g. running on your DSL router), you can
 | 
				
			||||||
 | 
					decrease USERS and undefine OUTPACKETQ_LEN in user.h without any ill conse-
 | 
				
			||||||
 | 
					quence, assuming at most one client will be connected at any time. A small
 | 
				
			||||||
 | 
					DNSCACHE_LEN is still advised, preferably 2 or higher, however you can also
 | 
				
			||||||
 | 
					undefine it to save a few more kilobytes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					One iodine server can handle multiple domains. Set up different NS records
 | 
				
			||||||
 | 
					on the same domain all pointing to the same host, and use a wildcard
 | 
				
			||||||
 | 
					at the start of the topdomain argument (example `*.mydomain.com`). iodine
 | 
				
			||||||
 | 
					will accept tunnel traffic for all domains matching that pattern. The wildcard
 | 
				
			||||||
 | 
					has to be at the start of the topdomain argument and be followed by a dot.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PERFORMANCE
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This section tabulates some performance measurements. To view properly, use
 | 
				
			||||||
 | 
					a fixed-width font like Courier.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Measurements were done in protocol 00000502 in lazy mode; upstream encoding
 | 
				
			||||||
 | 
					always Base128; `iodine -M255`; `iodined -m1130`. Network conditions were not
 | 
				
			||||||
 | 
					extremely favorable; results are not benchmarks but a realistic indication of
 | 
				
			||||||
 | 
					real-world performance that can be expected in similar situations.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Upstream/downstream throughput was measured by `scp`'ing a file previously
 | 
				
			||||||
 | 
					read from `/dev/urandom` (i.e. incompressible), and measuring size with
 | 
				
			||||||
 | 
					`ls -l ; sleep 30 ; ls -l` on a separate non-tunneled connection. Given the
 | 
				
			||||||
 | 
					large `scp` block size of 16 kB, this gives a resolution of 4.3 kbit/s, which
 | 
				
			||||||
 | 
					explains why some values are exactly equal.
 | 
				
			||||||
 | 
					Ping round-trip times measured with `ping -c100`, presented are average rtt
 | 
				
			||||||
 | 
					and mean deviation (indicating spread around the average), in milliseconds.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Situation 1: `Laptop  ->   Wifi AP   ->  Home server  ->  DSL provider  ->  Datacenter`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						 iodine    DNS "relay"        bind9           DNS cache        iodined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						                        downstr.  upstream downstr.  ping-up       ping-down
 | 
				
			||||||
 | 
						                        fragsize   kbit/s   kbit/s  avg +/-mdev   avg +/-mdev
 | 
				
			||||||
 | 
						-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						iodine -> Wifi AP :53
 | 
				
			||||||
 | 
						  -Tnull (= -Oraw)           982    43.6    131.0   28.0    4.6   26.8    3.4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						iodine -> Home server :53
 | 
				
			||||||
 | 
						  -Tnull (= -Oraw)          1174    48.0    305.8   26.6    5.0   26.9    8.4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						iodine -> DSL provider :53
 | 
				
			||||||
 | 
						  -Tnull (= -Oraw)          1174    56.7    367.0   20.6    3.1   21.2    4.4
 | 
				
			||||||
 | 
						  -Ttxt -Obase32             730    56.7    174.7*
 | 
				
			||||||
 | 
						  -Ttxt -Obase64             874    56.7    174.7
 | 
				
			||||||
 | 
						  -Ttxt -Obase128           1018    56.7    174.7
 | 
				
			||||||
 | 
						  -Ttxt -Oraw               1162    56.7    358.2
 | 
				
			||||||
 | 
						  -Tsrv -Obase128            910    56.7    174.7
 | 
				
			||||||
 | 
						  -Tcname -Obase32           151    56.7     43.6
 | 
				
			||||||
 | 
						  -Tcname -Obase128          212    56.7     52.4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						iodine -> DSL provider :53
 | 
				
			||||||
 | 
						  wired (no Wifi) -Tnull    1174    74.2    585.4   20.2    5.6   19.6    3.4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						 [174.7* : these all have 2frag/packet]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Situation 2: `Laptop  ->  Wifi+vpn / wired  ->  Home server`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						 iodine                            iodined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						                        downstr.  upstream downstr.  ping-up       ping-down
 | 
				
			||||||
 | 
						                        fragsize   kbit/s   kbit/s  avg +/-mdev   avg +/-mdev
 | 
				
			||||||
 | 
						-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wifi + openvpn  -Tnull      1186   166.0   1022.3    6.3    1.3    6.6    1.6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wired  -Tnull               1186   677.2   2464.1    1.3    0.2    1.3    0.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Notes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Performance is strongly coupled to low ping times, as iodine requires
 | 
				
			||||||
 | 
					confirmation for every data fragment before moving on to the next. Allowing
 | 
				
			||||||
 | 
					multiple fragments in-flight like TCP could possibly increase performance,
 | 
				
			||||||
 | 
					but it would likely cause serious overload for the intermediary DNS servers.
 | 
				
			||||||
 | 
					The current protocol scales performance with DNS responsivity, since the
 | 
				
			||||||
 | 
					DNS servers are on average handling at most one DNS request per client.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PORTABILITY
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					iodine has been tested on Linux (arm, ia64, x86, AMD64 and SPARC64), FreeBSD
 | 
				
			||||||
 | 
					(ia64, x86), OpenBSD (x86), NetBSD (x86), MacOS X (ppc and x86, with
 | 
				
			||||||
 | 
					<http://tuntaposx.sourceforge.net/>). and Windows (with OpenVPN TAP32 driver, see
 | 
				
			||||||
 | 
					win32 readme file).  It should be easy to port to other unix-like systems that
 | 
				
			||||||
 | 
					have TUN/TAP tunneling support. Let us know if you get it to run on other
 | 
				
			||||||
 | 
					platforms.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THE NAME
 | 
				
			||||||
 | 
					--------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The name iodine was chosen since it starts with IOD (IP Over DNS) and since
 | 
				
			||||||
 | 
					iodine has atomic number 53, which happens to be the DNS port number.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THANKS
 | 
				
			||||||
 | 
					------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- To kuxien for FreeBSD and OS X testing
 | 
				
			||||||
 | 
					- To poplix for code audit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AUTHORS & LICENSE
 | 
				
			||||||
 | 
					-----------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>, 2006-2009 Bjorn
 | 
				
			||||||
 | 
					Andersson <flex@kryo.se>. Also major contributions by Anne Bezemer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Permission to use, copy, modify, and/or distribute this software for any purpose
 | 
				
			||||||
 | 
					with or without fee is hereby granted, provided that the above copyright notice
 | 
				
			||||||
 | 
					and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 | 
				
			||||||
 | 
					REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
				
			||||||
 | 
					FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
 | 
				
			||||||
 | 
					INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 | 
				
			||||||
 | 
					LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
				
			||||||
 | 
					OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
				
			||||||
 | 
					PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MD5 implementation by L. Peter Deutsch (license and source in `src/md5.[ch]`)
 | 
				
			||||||
 | 
					Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved.
 | 
				
			||||||
							
								
								
									
										12
									
								
								TODO
								
								
								
								
							
							
						
						
									
										12
									
								
								TODO
								
								
								
								
							| 
						 | 
					@ -1,12 +0,0 @@
 | 
				
			||||||
 | 
					 | 
				
			||||||
iodine - http://code.kryo.se/iodine
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
***********************************
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The TODO list is now located at
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
http://dev.kryo.se/iodine/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The list is under the "View tickets" page
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Feel free to add your own wishes and bug reports
 | 
					 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,8 @@ Description=Iodine socket
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Socket]
 | 
					[Socket]
 | 
				
			||||||
ListenDatagram=53
 | 
					ListenDatagram=53
 | 
				
			||||||
 | 
					ListenDatagram=0.0.0.0:53
 | 
				
			||||||
 | 
					BindIPv6Only=ipv6-only
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Install]
 | 
					[Install]
 | 
				
			||||||
WantedBy=sockets.target
 | 
					WantedBy=sockets.target
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,14 +50,16 @@ Server replies:
 | 
				
			||||||
	LNAK means not accepted
 | 
						LNAK means not accepted
 | 
				
			||||||
	x.x.x.x-y.y.y.y-mtu-netmask means accepted (server ip, client ip, mtu, netmask bits)
 | 
						x.x.x.x-y.y.y.y-mtu-netmask means accepted (server ip, client ip, mtu, netmask bits)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
IP Request:
 | 
					IP Request: (for where to try raw login)
 | 
				
			||||||
Client sends:
 | 
					Client sends:
 | 
				
			||||||
	First byte i or I
 | 
						First byte i or I
 | 
				
			||||||
	5 bits coded as Base32 char, meaning userid
 | 
						5 bits coded as Base32 char, meaning userid
 | 
				
			||||||
	CMC as 3 Base32 chars
 | 
						CMC as 3 Base32 chars
 | 
				
			||||||
Server replies
 | 
					Server replies
 | 
				
			||||||
	BADIP if bad userid, or
 | 
						BADIP if bad userid
 | 
				
			||||||
	I and then 4 bytes network order external IP address of iodined server
 | 
						First byte I
 | 
				
			||||||
 | 
						Then comes external IP address of iodined server
 | 
				
			||||||
 | 
						as 4 bytes (IPv4) or 16 bytes (IPv6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Upstream codec check / bounce:
 | 
					Upstream codec check / bounce:
 | 
				
			||||||
Client sends:
 | 
					Client sends:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										44
									
								
								man/iodine.8
								
								
								
								
							
							
						
						
									
										44
									
								
								man/iodine.8
								
								
								
								
							| 
						 | 
					@ -45,7 +45,7 @@ iodine, iodined \- tunnel IPv4 over DNS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.B iodined [-h]
 | 
					.B iodined [-h]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.B iodined [-c] [-s] [-f] [-D] [-u
 | 
					.B iodined [-4] [-6] [-c] [-s] [-f] [-D] [-u
 | 
				
			||||||
.I user
 | 
					.I user
 | 
				
			||||||
.B ] [-t
 | 
					.B ] [-t
 | 
				
			||||||
.I chrootdir
 | 
					.I chrootdir
 | 
				
			||||||
| 
						 | 
					@ -54,7 +54,9 @@ iodine, iodined \- tunnel IPv4 over DNS
 | 
				
			||||||
.B ] [-m
 | 
					.B ] [-m
 | 
				
			||||||
.I mtu
 | 
					.I mtu
 | 
				
			||||||
.B ] [-l
 | 
					.B ] [-l
 | 
				
			||||||
.I listen_ip
 | 
					.I listen_ip4
 | 
				
			||||||
 | 
					.B ] [-L
 | 
				
			||||||
 | 
					.I listen_ip6
 | 
				
			||||||
.B ] [-p
 | 
					.B ] [-p
 | 
				
			||||||
.I port
 | 
					.I port
 | 
				
			||||||
.B ] [-n
 | 
					.B ] [-n
 | 
				
			||||||
| 
						 | 
					@ -110,6 +112,12 @@ Print usage info and exit.
 | 
				
			||||||
.B -f
 | 
					.B -f
 | 
				
			||||||
Keep running in foreground.
 | 
					Keep running in foreground.
 | 
				
			||||||
.TP
 | 
					.TP
 | 
				
			||||||
 | 
					.B -4
 | 
				
			||||||
 | 
					Force/allow only IPv4 DNS queries
 | 
				
			||||||
 | 
					.TP
 | 
				
			||||||
 | 
					.B -6
 | 
				
			||||||
 | 
					Force/allow only IPv6 DNS queries
 | 
				
			||||||
 | 
					.TP
 | 
				
			||||||
.B -u user
 | 
					.B -u user
 | 
				
			||||||
Drop privileges and run as user 'user' after setting up tunnel.
 | 
					Drop privileges and run as user 'user' after setting up tunnel.
 | 
				
			||||||
.TP
 | 
					.TP
 | 
				
			||||||
| 
						 | 
					@ -118,7 +126,8 @@ Chroot to 'chrootdir' after setting up tunnel.
 | 
				
			||||||
.TP
 | 
					.TP
 | 
				
			||||||
.B -d device
 | 
					.B -d device
 | 
				
			||||||
Use the TUN device 'device' instead of the normal one, which is dnsX on Linux
 | 
					Use the TUN device 'device' instead of the normal one, which is dnsX on Linux
 | 
				
			||||||
and otherwise tunX.
 | 
					and otherwise tunX. On Mac OS X 10.6, this can also be utunX, which will attempt
 | 
				
			||||||
 | 
					to use an utun device built into the OS.
 | 
				
			||||||
.TP
 | 
					.TP
 | 
				
			||||||
.B -P password
 | 
					.B -P password
 | 
				
			||||||
Use 'password' to authenticate. If not used,
 | 
					Use 'password' to authenticate. If not used,
 | 
				
			||||||
| 
						 | 
					@ -132,12 +141,6 @@ Apply SELinux 'context' after initialization.
 | 
				
			||||||
Create 'pidfile' and write process id in it.
 | 
					Create 'pidfile' and write process id in it.
 | 
				
			||||||
.SS Client Options:
 | 
					.SS Client Options:
 | 
				
			||||||
.TP
 | 
					.TP
 | 
				
			||||||
.B -4
 | 
					 | 
				
			||||||
Force IPv4 DNS queries
 | 
					 | 
				
			||||||
.TP
 | 
					 | 
				
			||||||
.B -6
 | 
					 | 
				
			||||||
Force IPv6 DNS queries
 | 
					 | 
				
			||||||
.TP
 | 
					 | 
				
			||||||
.B -r
 | 
					.B -r
 | 
				
			||||||
Skip raw UDP mode. If not used, iodine will try getting the public IP address
 | 
					Skip raw UDP mode. If not used, iodine will try getting the public IP address
 | 
				
			||||||
of the iodined host and test if it is reachable directly. If it is, traffic
 | 
					of the iodined host and test if it is reachable directly. If it is, traffic
 | 
				
			||||||
| 
						 | 
					@ -265,13 +268,21 @@ This will be sent to the client on login, and the client will use the same mtu
 | 
				
			||||||
for its tun device.  Default 1130.  Note that the DNS traffic will be
 | 
					for its tun device.  Default 1130.  Note that the DNS traffic will be
 | 
				
			||||||
automatically fragmented when needed.
 | 
					automatically fragmented when needed.
 | 
				
			||||||
.TP
 | 
					.TP
 | 
				
			||||||
.B -l listen_ip
 | 
					.B -l external|listen_ip4
 | 
				
			||||||
Make the server listen only on 'listen_ip' for incoming requests.
 | 
					Make the server listen only on 'listen_ip4' for incoming IPv4 requests.
 | 
				
			||||||
By default, incoming requests are accepted from all interfaces.
 | 
					By default, incoming requests are accepted from all interfaces (0.0.0.0).
 | 
				
			||||||
 | 
					A domain name can be used as argument - use one with only one A record.
 | 
				
			||||||
 | 
					If listen_ip4 is 'external', iodined will use the opendns.com DNS service to
 | 
				
			||||||
 | 
					retrieve the external IP of the host and use that as listen address.
 | 
				
			||||||
 | 
					.TP
 | 
				
			||||||
 | 
					.B -L listen_ip6
 | 
				
			||||||
 | 
					Make the server listen only on 'listen_ip6' for incoming IPv6 requests.
 | 
				
			||||||
 | 
					By default, incoming requests are accepted from all interfaces (::).
 | 
				
			||||||
 | 
					A domain name can be used as argument - use one with only one AAAA record.
 | 
				
			||||||
.TP
 | 
					.TP
 | 
				
			||||||
.B -p port
 | 
					.B -p port
 | 
				
			||||||
Make the server listen on 'port' instead of 53 for traffic.
 | 
					Make the server listen on 'port' instead of 53 for traffic.
 | 
				
			||||||
If 'listen_ip' does not include localhost, this 'port' can be the same
 | 
					If 'listen_ip4' does not include localhost, this 'port' can be the same
 | 
				
			||||||
as 'dnsport'.
 | 
					as 'dnsport'.
 | 
				
			||||||
.B Note:
 | 
					.B Note:
 | 
				
			||||||
You must make sure the dns requests are forwarded to this port yourself.
 | 
					You must make sure the dns requests are forwarded to this port yourself.
 | 
				
			||||||
| 
						 | 
					@ -279,7 +290,7 @@ You must make sure the dns requests are forwarded to this port yourself.
 | 
				
			||||||
.B -n auto|external_ip
 | 
					.B -n auto|external_ip
 | 
				
			||||||
The IP address to return in NS responses. Default is to return the address used
 | 
					The IP address to return in NS responses. Default is to return the address used
 | 
				
			||||||
as destination in the query.
 | 
					as destination in the query.
 | 
				
			||||||
If external_ip is 'auto', iodined will use externalip.net web service to
 | 
					If external_ip is 'auto', iodined will use the opendns.com DNS service to
 | 
				
			||||||
retrieve the external IP of the host and use that for NS responses.
 | 
					retrieve the external IP of the host and use that for NS responses.
 | 
				
			||||||
.TP
 | 
					.TP
 | 
				
			||||||
.B -b dnsport
 | 
					.B -b dnsport
 | 
				
			||||||
| 
						 | 
					@ -326,7 +337,8 @@ subdomains under 'topdomain'. This is normally a subdomain to a domain you
 | 
				
			||||||
own. Use a short domain name to get better throughput. This argument must be
 | 
					own. Use a short domain name to get better throughput. This argument must be
 | 
				
			||||||
the same on both the client and the server. Queries for domains other
 | 
					the same on both the client and the server. Queries for domains other
 | 
				
			||||||
than 'topdomain' will be forwarded when the \-b option is given, otherwise
 | 
					than 'topdomain' will be forwarded when the \-b option is given, otherwise
 | 
				
			||||||
they will be dropped.
 | 
					they will be dropped. The topdomain can start with '*' which will allow all
 | 
				
			||||||
 | 
					domains ending with the same suffix.
 | 
				
			||||||
.SH EXAMPLES
 | 
					.SH EXAMPLES
 | 
				
			||||||
See the README file for both a quick test scenario, and a detailed description
 | 
					See the README file for both a quick test scenario, and a detailed description
 | 
				
			||||||
of real-world deployment.
 | 
					of real-world deployment.
 | 
				
			||||||
| 
						 | 
					@ -362,7 +374,7 @@ option still has precedence.
 | 
				
			||||||
The README file in the source distribution contains some more elaborate
 | 
					The README file in the source distribution contains some more elaborate
 | 
				
			||||||
information.
 | 
					information.
 | 
				
			||||||
.SH BUGS
 | 
					.SH BUGS
 | 
				
			||||||
File bugs at http://dev.kryo.se/iodine/
 | 
					File bugs at https://github.com/yarrick/iodine
 | 
				
			||||||
.SH AUTHORS
 | 
					.SH AUTHORS
 | 
				
			||||||
Erik Ekman <yarrick@kryo.se> and Bjorn Andersson <flex@kryo.se>. Major
 | 
					Erik Ekman <yarrick@kryo.se> and Bjorn Andersson <flex@kryo.se>. Major
 | 
				
			||||||
contributions by Anne Bezemer.
 | 
					contributions by Anne Bezemer.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# iodine for Android
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# by Marcel Bokhorst
 | 
				
			||||||
 | 
					# http://blog.bokhorst.biz/5123/computers-en-internet/iodine-for-android/
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# cd iodine-0.6.0-rc1/src
 | 
				
			||||||
 | 
					# make base64u.h base64u.c
 | 
				
			||||||
 | 
					# .../ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LOCAL_PATH:= $(call my-dir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HEAD_COMMIT = `git rev-parse --short HEAD`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include $(CLEAR_VARS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LOCAL_MODULE    := iodine
 | 
				
			||||||
 | 
					LOCAL_SRC_FILES := tun.c dns.c read.c encoding.c login.c base32.c base64.c base64u.c base128.c md5.c common.c iodine.c client.c util.c
 | 
				
			||||||
 | 
					LOCAL_CFLAGS    := -c -DANDROID -DLINUX -DIFCONFIGPATH=\"/system/bin/\" -Wall -DGITREVISION=\"$(HEAD_COMMIT)\"
 | 
				
			||||||
 | 
					LOCAL_LDLIBS    := -lz
 | 
				
			||||||
 | 
					LOCAL_CFLAGS += -fPIE
 | 
				
			||||||
 | 
					LOCAL_LDFLAGS += -fPIE -pie
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include $(BUILD_EXECUTABLE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,7 @@ HEAD_COMMIT = `git rev-parse --short HEAD`
 | 
				
			||||||
LIBPATH = -L.
 | 
					LIBPATH = -L.
 | 
				
			||||||
LDFLAGS +=  -lz `sh osflags $(TARGETOS) link` $(LIBPATH)
 | 
					LDFLAGS +=  -lz `sh osflags $(TARGETOS) link` $(LIBPATH)
 | 
				
			||||||
CFLAGS += -std=c99 -c -g -Wall -D$(OS) -pedantic `sh osflags $(TARGETOS) cflags` -DGITREVISION=\"$(HEAD_COMMIT)\"
 | 
					CFLAGS += -std=c99 -c -g -Wall -D$(OS) -pedantic `sh osflags $(TARGETOS) cflags` -DGITREVISION=\"$(HEAD_COMMIT)\"
 | 
				
			||||||
 | 
					CFLAGS += -Wstrict-prototypes -Wtype-limits -Wmissing-declarations -Wmissing-prototypes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
all: stateos $(CLIENT) $(SERVER)
 | 
					all: stateos $(CLIENT) $(SERVER)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,15 +32,10 @@ $(SERVER): $(COMMONOBJS) $(SERVEROBJS)
 | 
				
			||||||
	@echo CC $<
 | 
						@echo CC $<
 | 
				
			||||||
	@$(CC) $(CFLAGS) $< -o $@
 | 
						@$(CC) $(CFLAGS) $< -o $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
base64u.o client.o iodined.o: base64u.h
 | 
					 | 
				
			||||||
base64u.c: base64.c
 | 
					base64u.c: base64.c
 | 
				
			||||||
	@echo Making $@
 | 
						@echo Making $@
 | 
				
			||||||
	@echo '/* No use in editing, produced by Makefile! */' > $@
 | 
						@echo '/* No use in editing, produced by Makefile! */' > $@
 | 
				
			||||||
	@sed -e 's/\([Bb][Aa][Ss][Ee]64\)/\1u/g ; s/0123456789+/0123456789_/' < base64.c >> $@
 | 
						@sed -e 's/\([Bb][Aa][Ss][Ee]64\)/\1u/g ; s/0123456789+/0123456789_/' < base64.c >> $@
 | 
				
			||||||
base64u.h: base64.h
 | 
					 | 
				
			||||||
	@echo Making $@
 | 
					 | 
				
			||||||
	@echo '/* No use in editing, produced by Makefile! */' > $@
 | 
					 | 
				
			||||||
	@sed -e 's/\([Bb][Aa][Ss][Ee]64\)/\1u/g ; s/0123456789+/0123456789_/' < base64.h >> $@
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
clean:
 | 
					clean:
 | 
				
			||||||
	@echo "Cleaning src/"
 | 
						@echo "Cleaning src/"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,25 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Marcel Bokhorst <marcel@bokhorst.biz>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
				
			||||||
 | 
					 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
				
			||||||
 | 
					 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef __FIX_ANDROID_H__
 | 
					#ifndef __FIX_ANDROID_H__
 | 
				
			||||||
#define __FIX_ANDROID_H__
 | 
					#define __FIX_ANDROID_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Newer android platforms can have this data already */
 | 
				
			||||||
 | 
					#ifndef C_IN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
	unsigned id :16;
 | 
						unsigned id :16;
 | 
				
			||||||
	unsigned rd :1;
 | 
						unsigned rd :1;
 | 
				
			||||||
| 
						 | 
					@ -36,4 +54,6 @@ typedef struct {
 | 
				
			||||||
#define T_TXT		16
 | 
					#define T_TXT		16
 | 
				
			||||||
#define T_SRV		33
 | 
					#define T_SRV		33
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* !C_IN */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright (C) 2009 J.A.Bezemer@opensourcepartners.nl
 | 
					 * Copyright (C) 2009 J.A.Bezemer@opensourcepartners.nl
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -33,10 +33,9 @@
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "encoding.h"
 | 
					#include "encoding.h"
 | 
				
			||||||
#include "base128.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BLKSIZE_RAW 7
 | 
					#define BASE128_BLKSIZE_RAW 7
 | 
				
			||||||
#define BLKSIZE_ENC 8
 | 
					#define BASE128_BLKSIZE_ENC 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Don't use '-' (restricted to middle of labels), prefer iso_8859-1
 | 
					/* Don't use '-' (restricted to middle of labels), prefer iso_8859-1
 | 
				
			||||||
 * accent chars since they might readily be entered in normal use,
 | 
					 * accent chars since they might readily be entered in normal use,
 | 
				
			||||||
| 
						 | 
					@ -52,55 +51,13 @@ static const unsigned char cb128[] =
 | 
				
			||||||
static unsigned char rev128[256];
 | 
					static unsigned char rev128[256];
 | 
				
			||||||
static int reverse_init = 0;
 | 
					static int reverse_init = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int base128_encode(char *, size_t *, const void *, size_t);
 | 
					inline static void base128_reverse_init(void)
 | 
				
			||||||
static int base128_decode(void *, size_t *, const char *, size_t);
 | 
					 | 
				
			||||||
static int base128_handles_dots();
 | 
					 | 
				
			||||||
static int base128_blksize_raw();
 | 
					 | 
				
			||||||
static int base128_blksize_enc();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct encoder base128_encoder =
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	"Base128",
 | 
					 | 
				
			||||||
	base128_encode,
 | 
					 | 
				
			||||||
	base128_decode,
 | 
					 | 
				
			||||||
	base128_handles_dots,
 | 
					 | 
				
			||||||
	base128_handles_dots,
 | 
					 | 
				
			||||||
	base128_blksize_raw,
 | 
					 | 
				
			||||||
	base128_blksize_enc
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct encoder
 | 
					 | 
				
			||||||
*get_base128_encoder()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return &base128_encoder;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
base128_handles_dots()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
base128_blksize_raw()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return BLKSIZE_RAW;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
base128_blksize_enc()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return BLKSIZE_ENC;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
inline static void
 | 
					 | 
				
			||||||
base128_reverse_init()
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	unsigned char c;
 | 
						unsigned char c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!reverse_init) {
 | 
						if (!reverse_init) {
 | 
				
			||||||
		memset (rev128, 0, 256);
 | 
							memset(rev128, 0, 256);
 | 
				
			||||||
		for (i = 0; i < 128; i++) {
 | 
							for (i = 0; i < 128; i++) {
 | 
				
			||||||
			c = cb128[i];
 | 
								c = cb128[i];
 | 
				
			||||||
			rev128[(int) c] = i;
 | 
								rev128[(int) c] = i;
 | 
				
			||||||
| 
						 | 
					@ -109,8 +66,6 @@ base128_reverse_init()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
base128_encode(char *buf, size_t *buflen, const void *data, size_t size)
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Fills *buf with max. *buflen characters, encoding size bytes of *data.
 | 
					 * Fills *buf with max. *buflen characters, encoding size bytes of *data.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -120,6 +75,8 @@ base128_encode(char *buf, size_t *buflen, const void *data, size_t size)
 | 
				
			||||||
 * return value    : #bytes filled in buf   (excluding \0)
 | 
					 * return value    : #bytes filled in buf   (excluding \0)
 | 
				
			||||||
 * sets *buflen to : #bytes encoded from data
 | 
					 * sets *buflen to : #bytes encoded from data
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					static int base128_encode(char *buf, size_t *buflen, const void *data,
 | 
				
			||||||
 | 
								  size_t size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned char *ubuf = (unsigned char *) buf;
 | 
						unsigned char *ubuf = (unsigned char *) buf;
 | 
				
			||||||
	unsigned char *udata = (unsigned char *) data;
 | 
						unsigned char *udata = (unsigned char *) data;
 | 
				
			||||||
| 
						 | 
					@ -203,8 +160,6 @@ base128_encode(char *buf, size_t *buflen, const void *data, size_t size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define REV128(x) rev128[(int) (x)]
 | 
					#define REV128(x) rev128[(int) (x)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
base128_decode(void *buf, size_t *buflen, const char *str, size_t slen)
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Fills *buf with max. *buflen bytes, decoded from slen chars in *str.
 | 
					 * Fills *buf with max. *buflen bytes, decoded from slen chars in *str.
 | 
				
			||||||
 * Decoding stops early when *str contains \0.
 | 
					 * Decoding stops early when *str contains \0.
 | 
				
			||||||
| 
						 | 
					@ -216,13 +171,15 @@ base128_decode(void *buf, size_t *buflen, const char *str, size_t slen)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * return value    : #bytes filled in buf   (excluding \0)
 | 
					 * return value    : #bytes filled in buf   (excluding \0)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					static int base128_decode(void *buf, size_t *buflen, const char *str,
 | 
				
			||||||
 | 
								  size_t slen)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned char *ustr = (unsigned char *) str;
 | 
						unsigned char *ustr = (unsigned char *) str;
 | 
				
			||||||
	unsigned char *ubuf = (unsigned char *) buf;
 | 
						unsigned char *ubuf = (unsigned char *) buf;
 | 
				
			||||||
	int iout = 0;	/* to-be-filled output byte */
 | 
						int iout = 0;	/* to-be-filled output byte */
 | 
				
			||||||
	int iin = 0;	/* next input char to use in decoding */
 | 
						int iin = 0;	/* next input char to use in decoding */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	base128_reverse_init ();
 | 
						base128_reverse_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Note: Don't bother to optimize manually. GCC optimizes
 | 
						/* Note: Don't bother to optimize manually. GCC optimizes
 | 
				
			||||||
	   better(!) when using simplistic array indexing. */
 | 
						   better(!) when using simplistic array indexing. */
 | 
				
			||||||
| 
						 | 
					@ -289,3 +246,16 @@ base128_decode(void *buf, size_t *buflen, const char *str, size_t slen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return iout;
 | 
						return iout;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct encoder base128_ops = {
 | 
				
			||||||
 | 
						.name = "Base128",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.encode = base128_encode,
 | 
				
			||||||
 | 
						.decode = base128_decode,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.places_dots = false,
 | 
				
			||||||
 | 
						.eats_dots = false,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.blocksize_raw = BASE128_BLKSIZE_RAW,
 | 
				
			||||||
 | 
						.blocksize_encoded = BASE128_BLKSIZE_ENC,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,22 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (C) 2009 J.A.Bezemer@opensourcepartners.nl
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
					 | 
				
			||||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
					 | 
				
			||||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
					 | 
				
			||||||
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
					 | 
				
			||||||
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
					 | 
				
			||||||
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
					 | 
				
			||||||
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef __BASE128_H__
 | 
					 | 
				
			||||||
#define __BASE128_H__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct encoder *get_base128_encoder(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
							
								
								
									
										81
									
								
								src/base32.c
								
								
								
								
							
							
						
						
									
										81
									
								
								src/base32.c
								
								
								
								
							| 
						 | 
					@ -3,7 +3,7 @@
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 * Mostly rewritten 2009 J.A.Bezemer@opensourcepartners.nl
 | 
					 * Mostly rewritten 2009 J.A.Bezemer@opensourcepartners.nl
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -21,10 +21,9 @@
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "encoding.h"
 | 
					#include "encoding.h"
 | 
				
			||||||
#include "base32.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BLKSIZE_RAW 5
 | 
					#define BASE32_BLKSIZE_RAW 5
 | 
				
			||||||
#define BLKSIZE_ENC 8
 | 
					#define BASE32_BLKSIZE_ENC 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char cb32[] =
 | 
					static const char cb32[] =
 | 
				
			||||||
	"abcdefghijklmnopqrstuvwxyz012345";
 | 
						"abcdefghijklmnopqrstuvwxyz012345";
 | 
				
			||||||
| 
						 | 
					@ -33,55 +32,13 @@ static const char cb32_ucase[] =
 | 
				
			||||||
static unsigned char rev32[256];
 | 
					static unsigned char rev32[256];
 | 
				
			||||||
static int reverse_init = 0;
 | 
					static int reverse_init = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int base32_encode(char *, size_t *, const void *, size_t);
 | 
					inline static void base32_reverse_init(void)
 | 
				
			||||||
static int base32_decode(void *, size_t *, const char *, size_t);
 | 
					 | 
				
			||||||
static int base32_handles_dots();
 | 
					 | 
				
			||||||
static int base32_blksize_raw();
 | 
					 | 
				
			||||||
static int base32_blksize_enc();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct encoder base32_encoder =
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	"Base32",
 | 
					 | 
				
			||||||
	base32_encode,
 | 
					 | 
				
			||||||
	base32_decode,
 | 
					 | 
				
			||||||
	base32_handles_dots,
 | 
					 | 
				
			||||||
	base32_handles_dots,
 | 
					 | 
				
			||||||
	base32_blksize_raw,
 | 
					 | 
				
			||||||
	base32_blksize_enc
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct encoder
 | 
					 | 
				
			||||||
*get_base32_encoder()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return &base32_encoder;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
base32_handles_dots()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
base32_blksize_raw()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return BLKSIZE_RAW;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
base32_blksize_enc()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return BLKSIZE_ENC;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
inline static void
 | 
					 | 
				
			||||||
base32_reverse_init()
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	unsigned char c;
 | 
						unsigned char c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!reverse_init) {
 | 
						if (!reverse_init) {
 | 
				
			||||||
		memset (rev32, 0, 256);
 | 
							memset(rev32, 0, 256);
 | 
				
			||||||
		for (i = 0; i < 32; i++) {
 | 
							for (i = 0; i < 32; i++) {
 | 
				
			||||||
			c = cb32[i];
 | 
								c = cb32[i];
 | 
				
			||||||
			rev32[(int) c] = i;
 | 
								rev32[(int) c] = i;
 | 
				
			||||||
| 
						 | 
					@ -92,21 +49,17 @@ base32_reverse_init()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int b32_5to8(int in)
 | 
				
			||||||
b32_5to8(int in)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return cb32[in & 31];
 | 
						return cb32[in & 31];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int b32_8to5(int in)
 | 
				
			||||||
b32_8to5(int in)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	base32_reverse_init();
 | 
						base32_reverse_init();
 | 
				
			||||||
	return rev32[in];
 | 
						return rev32[in];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
base32_encode(char *buf, size_t *buflen, const void *data, size_t size)
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Fills *buf with max. *buflen characters, encoding size bytes of *data.
 | 
					 * Fills *buf with max. *buflen characters, encoding size bytes of *data.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -116,6 +69,7 @@ base32_encode(char *buf, size_t *buflen, const void *data, size_t size)
 | 
				
			||||||
 * return value    : #bytes filled in buf   (excluding \0)
 | 
					 * return value    : #bytes filled in buf   (excluding \0)
 | 
				
			||||||
 * sets *buflen to : #bytes encoded from data
 | 
					 * sets *buflen to : #bytes encoded from data
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					static int base32_encode(char *buf, size_t *buflen, const void *data, size_t size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned char *udata = (unsigned char *) data;
 | 
						unsigned char *udata = (unsigned char *) data;
 | 
				
			||||||
	int iout = 0;	/* to-be-filled output char */
 | 
						int iout = 0;	/* to-be-filled output char */
 | 
				
			||||||
| 
						 | 
					@ -196,8 +150,6 @@ base32_encode(char *buf, size_t *buflen, const void *data, size_t size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define REV32(x) rev32[(int) (x)]
 | 
					#define REV32(x) rev32[(int) (x)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
base32_decode(void *buf, size_t *buflen, const char *str, size_t slen)
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Fills *buf with max. *buflen bytes, decoded from slen chars in *str.
 | 
					 * Fills *buf with max. *buflen bytes, decoded from slen chars in *str.
 | 
				
			||||||
 * Decoding stops early when *str contains \0.
 | 
					 * Decoding stops early when *str contains \0.
 | 
				
			||||||
| 
						 | 
					@ -209,12 +161,14 @@ base32_decode(void *buf, size_t *buflen, const char *str, size_t slen)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * return value    : #bytes filled in buf   (excluding \0)
 | 
					 * return value    : #bytes filled in buf   (excluding \0)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					static int base32_decode(void *buf, size_t *buflen, const char *str,
 | 
				
			||||||
 | 
								 size_t slen)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned char *ubuf = (unsigned char *) buf;
 | 
						unsigned char *ubuf = (unsigned char *) buf;
 | 
				
			||||||
	int iout = 0;	/* to-be-filled output byte */
 | 
						int iout = 0;	/* to-be-filled output byte */
 | 
				
			||||||
	int iin = 0;	/* next input char to use in decoding */
 | 
						int iin = 0;	/* next input char to use in decoding */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	base32_reverse_init ();
 | 
						base32_reverse_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Note: Don't bother to optimize manually. GCC optimizes
 | 
						/* Note: Don't bother to optimize manually. GCC optimizes
 | 
				
			||||||
	   better(!) when using simplistic array indexing. */
 | 
						   better(!) when using simplistic array indexing. */
 | 
				
			||||||
| 
						 | 
					@ -269,3 +223,16 @@ base32_decode(void *buf, size_t *buflen, const char *str, size_t slen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return iout;
 | 
						return iout;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct encoder base32_ops = {
 | 
				
			||||||
 | 
						.name = "Base32",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.encode = base32_encode,
 | 
				
			||||||
 | 
						.decode = base32_decode,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.places_dots = false,
 | 
				
			||||||
 | 
						.eats_dots = false,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.blocksize_raw = BASE32_BLKSIZE_RAW,
 | 
				
			||||||
 | 
						.blocksize_encoded = BASE32_BLKSIZE_ENC,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										25
									
								
								src/base32.h
								
								
								
								
							
							
						
						
									
										25
									
								
								src/base32.h
								
								
								
								
							| 
						 | 
					@ -1,25 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
					 | 
				
			||||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
					 | 
				
			||||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
					 | 
				
			||||||
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
					 | 
				
			||||||
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
					 | 
				
			||||||
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
					 | 
				
			||||||
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef __BASE32_H__
 | 
					 | 
				
			||||||
#define __BASE32_H__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct encoder *get_base32_encoder(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int b32_5to8(int);
 | 
					 | 
				
			||||||
int b32_8to5(int);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
							
								
								
									
										78
									
								
								src/base64.c
								
								
								
								
							
							
						
						
									
										78
									
								
								src/base64.c
								
								
								
								
							| 
						 | 
					@ -3,7 +3,7 @@
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 * Mostly rewritten 2009 J.A.Bezemer@opensourcepartners.nl
 | 
					 * Mostly rewritten 2009 J.A.Bezemer@opensourcepartners.nl
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -21,10 +21,9 @@
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "encoding.h"
 | 
					#include "encoding.h"
 | 
				
			||||||
#include "base64.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BLKSIZE_RAW 3
 | 
					#define BASE64_BLKSIZE_RAW 3
 | 
				
			||||||
#define BLKSIZE_ENC 4
 | 
					#define BASE64_BLKSIZE_ENC 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Note: the "unofficial" char is last here, which means that the \377 pattern
 | 
					/* Note: the "unofficial" char is last here, which means that the \377 pattern
 | 
				
			||||||
   in DOWNCODECCHECK1 ('Y' request) will properly test it. */
 | 
					   in DOWNCODECCHECK1 ('Y' request) will properly test it. */
 | 
				
			||||||
| 
						 | 
					@ -33,55 +32,13 @@ static const char cb64[] =
 | 
				
			||||||
static unsigned char rev64[256];
 | 
					static unsigned char rev64[256];
 | 
				
			||||||
static int reverse_init = 0;
 | 
					static int reverse_init = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int base64_encode(char *, size_t *, const void *, size_t);
 | 
					inline static void base64_reverse_init(void)
 | 
				
			||||||
static int base64_decode(void *, size_t *, const char *, size_t);
 | 
					 | 
				
			||||||
static int base64_handles_dots();
 | 
					 | 
				
			||||||
static int base64_blksize_raw();
 | 
					 | 
				
			||||||
static int base64_blksize_enc();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct encoder base64_encoder =
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	"Base64",
 | 
					 | 
				
			||||||
	base64_encode,
 | 
					 | 
				
			||||||
	base64_decode,
 | 
					 | 
				
			||||||
	base64_handles_dots,
 | 
					 | 
				
			||||||
	base64_handles_dots,
 | 
					 | 
				
			||||||
	base64_blksize_raw,
 | 
					 | 
				
			||||||
	base64_blksize_enc
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct encoder
 | 
					 | 
				
			||||||
*get_base64_encoder()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return &base64_encoder;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
base64_handles_dots()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
base64_blksize_raw()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return BLKSIZE_RAW;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
base64_blksize_enc()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return BLKSIZE_ENC;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
inline static void
 | 
					 | 
				
			||||||
base64_reverse_init()
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	unsigned char c;
 | 
						unsigned char c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!reverse_init) {
 | 
						if (!reverse_init) {
 | 
				
			||||||
		memset (rev64, 0, 256);
 | 
							memset(rev64, 0, 256);
 | 
				
			||||||
		for (i = 0; i < 64; i++) {
 | 
							for (i = 0; i < 64; i++) {
 | 
				
			||||||
			c = cb64[i];
 | 
								c = cb64[i];
 | 
				
			||||||
			rev64[(int) c] = i;
 | 
								rev64[(int) c] = i;
 | 
				
			||||||
| 
						 | 
					@ -90,8 +47,6 @@ base64_reverse_init()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
base64_encode(char *buf, size_t *buflen, const void *data, size_t size)
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Fills *buf with max. *buflen characters, encoding size bytes of *data.
 | 
					 * Fills *buf with max. *buflen characters, encoding size bytes of *data.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -101,6 +56,8 @@ base64_encode(char *buf, size_t *buflen, const void *data, size_t size)
 | 
				
			||||||
 * return value    : #bytes filled in buf   (excluding \0)
 | 
					 * return value    : #bytes filled in buf   (excluding \0)
 | 
				
			||||||
 * sets *buflen to : #bytes encoded from data
 | 
					 * sets *buflen to : #bytes encoded from data
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					static int base64_encode(char *buf, size_t *buflen, const void *data,
 | 
				
			||||||
 | 
								 size_t size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned char *udata = (unsigned char *) data;
 | 
						unsigned char *udata = (unsigned char *) data;
 | 
				
			||||||
	int iout = 0;	/* to-be-filled output char */
 | 
						int iout = 0;	/* to-be-filled output char */
 | 
				
			||||||
| 
						 | 
					@ -128,7 +85,7 @@ base64_encode(char *buf, size_t *buflen, const void *data, size_t size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (iout >= *buflen || iin >= size)
 | 
							if (iout >= *buflen || iin >= size)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		buf[iout] = cb64[((udata[iin] & 0x0f) << 2 ) |
 | 
							buf[iout] = cb64[((udata[iin] & 0x0f) << 2) |
 | 
				
			||||||
				  ((iin + 1 < size) ?
 | 
									  ((iin + 1 < size) ?
 | 
				
			||||||
				   ((udata[iin + 1] & 0xc0) >> 6) : 0)];
 | 
									   ((udata[iin + 1] & 0xc0) >> 6) : 0)];
 | 
				
			||||||
		iin++;			/* 1 complete, iin=2 */
 | 
							iin++;			/* 1 complete, iin=2 */
 | 
				
			||||||
| 
						 | 
					@ -151,8 +108,6 @@ base64_encode(char *buf, size_t *buflen, const void *data, size_t size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define REV64(x) rev64[(int) (x)]
 | 
					#define REV64(x) rev64[(int) (x)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
base64_decode(void *buf, size_t *buflen, const char *str, size_t slen)
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Fills *buf with max. *buflen bytes, decoded from slen chars in *str.
 | 
					 * Fills *buf with max. *buflen bytes, decoded from slen chars in *str.
 | 
				
			||||||
 * Decoding stops early when *str contains \0.
 | 
					 * Decoding stops early when *str contains \0.
 | 
				
			||||||
| 
						 | 
					@ -164,12 +119,14 @@ base64_decode(void *buf, size_t *buflen, const char *str, size_t slen)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * return value    : #bytes filled in buf   (excluding \0)
 | 
					 * return value    : #bytes filled in buf   (excluding \0)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					static int base64_decode(void *buf, size_t *buflen, const char *str,
 | 
				
			||||||
 | 
								 size_t slen)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned char *ubuf = (unsigned char *) buf;
 | 
						unsigned char *ubuf = (unsigned char *) buf;
 | 
				
			||||||
	int iout = 0;	/* to-be-filled output byte */
 | 
						int iout = 0;	/* to-be-filled output byte */
 | 
				
			||||||
	int iin = 0;	/* next input char to use in decoding */
 | 
						int iin = 0;	/* next input char to use in decoding */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	base64_reverse_init ();
 | 
						base64_reverse_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Note: Don't bother to optimize manually. GCC optimizes
 | 
						/* Note: Don't bother to optimize manually. GCC optimizes
 | 
				
			||||||
	   better(!) when using simplistic array indexing. */
 | 
						   better(!) when using simplistic array indexing. */
 | 
				
			||||||
| 
						 | 
					@ -204,3 +161,16 @@ base64_decode(void *buf, size_t *buflen, const char *str, size_t slen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return iout;
 | 
						return iout;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct encoder base64_ops = {
 | 
				
			||||||
 | 
						.name = "Base64",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.encode = base64_encode,
 | 
				
			||||||
 | 
						.decode = base64_decode,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.places_dots = false,
 | 
				
			||||||
 | 
						.eats_dots = false,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.blocksize_raw = BASE64_BLKSIZE_RAW,
 | 
				
			||||||
 | 
						.blocksize_encoded = BASE64_BLKSIZE_ENC,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										23
									
								
								src/base64.h
								
								
								
								
							
							
						
						
									
										23
									
								
								src/base64.h
								
								
								
								
							| 
						 | 
					@ -1,23 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
					 | 
				
			||||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
					 | 
				
			||||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
					 | 
				
			||||||
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
					 | 
				
			||||||
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
					 | 
				
			||||||
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
					 | 
				
			||||||
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef __BASE64_H__
 | 
					 | 
				
			||||||
#define __BASE64_H__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct encoder *get_base64_encoder(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
							
								
								
									
										291
									
								
								src/client.c
								
								
								
								
							
							
						
						
									
										291
									
								
								src/client.c
								
								
								
								
							| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -32,10 +32,10 @@
 | 
				
			||||||
#ifdef WINDOWS32
 | 
					#ifdef WINDOWS32
 | 
				
			||||||
#include "windows.h"
 | 
					#include "windows.h"
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
 | 
					#include <arpa/nameser.h>
 | 
				
			||||||
#ifdef ANDROID
 | 
					#ifdef ANDROID
 | 
				
			||||||
#include "android_dns.h"
 | 
					#include "android_dns.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#include <arpa/nameser.h>
 | 
					 | 
				
			||||||
#ifdef DARWIN
 | 
					#ifdef DARWIN
 | 
				
			||||||
#define BIND_8_COMPAT
 | 
					#define BIND_8_COMPAT
 | 
				
			||||||
#include <arpa/nameser_compat.h>
 | 
					#include <arpa/nameser_compat.h>
 | 
				
			||||||
| 
						 | 
					@ -47,10 +47,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "common.h"
 | 
					#include "common.h"
 | 
				
			||||||
#include "encoding.h"
 | 
					#include "encoding.h"
 | 
				
			||||||
#include "base32.h"
 | 
					 | 
				
			||||||
#include "base64.h"
 | 
					 | 
				
			||||||
#include "base64u.h"
 | 
					 | 
				
			||||||
#include "base128.h"
 | 
					 | 
				
			||||||
#include "dns.h"
 | 
					#include "dns.h"
 | 
				
			||||||
#include "login.h"
 | 
					#include "login.h"
 | 
				
			||||||
#include "tun.h"
 | 
					#include "tun.h"
 | 
				
			||||||
| 
						 | 
					@ -64,7 +60,8 @@ static const char *password;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct sockaddr_storage nameserv;
 | 
					static struct sockaddr_storage nameserv;
 | 
				
			||||||
static int nameserv_len;
 | 
					static int nameserv_len;
 | 
				
			||||||
static struct sockaddr_in raw_serv;
 | 
					static struct sockaddr_storage raw_serv;
 | 
				
			||||||
 | 
					static int raw_serv_len;
 | 
				
			||||||
static const char *topdomain;
 | 
					static const char *topdomain;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uint16_t rand_seed;
 | 
					static uint16_t rand_seed;
 | 
				
			||||||
| 
						 | 
					@ -84,16 +81,9 @@ static uint16_t chunkid;
 | 
				
			||||||
static uint16_t chunkid_prev;
 | 
					static uint16_t chunkid_prev;
 | 
				
			||||||
static uint16_t chunkid_prev2;
 | 
					static uint16_t chunkid_prev2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Base32 encoder used for non-data packets and replies */
 | 
					 | 
				
			||||||
static struct encoder *b32;
 | 
					 | 
				
			||||||
/* Base64 etc encoders for replies */
 | 
					 | 
				
			||||||
static struct encoder *b64;
 | 
					 | 
				
			||||||
static struct encoder *b64u;
 | 
					 | 
				
			||||||
static struct encoder *b128;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* The encoder used for data packets
 | 
					/* The encoder used for data packets
 | 
				
			||||||
 * Defaults to Base32, can be changed after handshake */
 | 
					 * Defaults to Base32, can be changed after handshake */
 | 
				
			||||||
static struct encoder *dataenc;
 | 
					const static struct encoder *dataenc = &base32_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* The encoder to use for downstream data */
 | 
					/* The encoder to use for downstream data */
 | 
				
			||||||
static char downenc = ' ';
 | 
					static char downenc = ' ';
 | 
				
			||||||
| 
						 | 
					@ -116,11 +106,6 @@ void
 | 
				
			||||||
client_init()
 | 
					client_init()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	running = 1;
 | 
						running = 1;
 | 
				
			||||||
	b32 = get_base32_encoder();
 | 
					 | 
				
			||||||
	b64 = get_base64_encoder();
 | 
					 | 
				
			||||||
	b64u = get_base64u_encoder();
 | 
					 | 
				
			||||||
	b128 = get_base128_encoder();
 | 
					 | 
				
			||||||
	dataenc = get_base32_encoder();
 | 
					 | 
				
			||||||
	rand_seed = ((unsigned int) rand()) & 0xFFFF;
 | 
						rand_seed = ((unsigned int) rand()) & 0xFFFF;
 | 
				
			||||||
	send_ping_soon = 1;	/* send ping immediately after startup */
 | 
						send_ping_soon = 1;	/* send ping immediately after startup */
 | 
				
			||||||
	conn = CONN_DNS_NULL;
 | 
						conn = CONN_DNS_NULL;
 | 
				
			||||||
| 
						 | 
					@ -242,7 +227,7 @@ client_set_hostname_maxlen(int i)
 | 
				
			||||||
const char *
 | 
					const char *
 | 
				
			||||||
client_get_raw_addr()
 | 
					client_get_raw_addr()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return inet_ntoa(raw_serv.sin_addr);
 | 
						return format_addr(&raw_serv, raw_serv_len);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -307,7 +292,7 @@ send_query(int fd, char *hostname)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
send_raw(int fd, char *buf, int buflen, int user, int cmd)
 | 
					send_raw(int fd, char *buf, int buflen, int cmd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char packet[4096];
 | 
						char packet[4096];
 | 
				
			||||||
	int len;
 | 
						int len;
 | 
				
			||||||
| 
						 | 
					@ -320,7 +305,7 @@ send_raw(int fd, char *buf, int buflen, int user, int cmd)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	len += RAW_HDR_LEN;
 | 
						len += RAW_HDR_LEN;
 | 
				
			||||||
	packet[RAW_HDR_CMD] = cmd | (user & 0x0F);
 | 
						packet[RAW_HDR_CMD] = cmd | (userid & 0x0F);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sendto(fd, packet, len, 0, (struct sockaddr*)&raw_serv, sizeof(raw_serv));
 | 
						sendto(fd, packet, len, 0, (struct sockaddr*)&raw_serv, sizeof(raw_serv));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -328,7 +313,7 @@ send_raw(int fd, char *buf, int buflen, int user, int cmd)
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
send_raw_data(int dns_fd)
 | 
					send_raw_data(int dns_fd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	send_raw(dns_fd, outpkt.data, outpkt.len, userid, RAW_HDR_CMD_DATA);
 | 
						send_raw(dns_fd, outpkt.data, outpkt.len, RAW_HDR_CMD_DATA);
 | 
				
			||||||
	outpkt.len = 0;
 | 
						outpkt.len = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -341,12 +326,11 @@ send_packet(int fd, char cmd, const char *data, const size_t datalen)
 | 
				
			||||||
	buf[0] = cmd;
 | 
						buf[0] = cmd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	build_hostname(buf + 1, sizeof(buf) - 1, data, datalen, topdomain,
 | 
						build_hostname(buf + 1, sizeof(buf) - 1, data, datalen, topdomain,
 | 
				
			||||||
		       b32, hostname_maxlen);
 | 
							       &base32_ops, hostname_maxlen);
 | 
				
			||||||
	send_query(fd, buf);
 | 
						send_query(fd, buf);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int
 | 
					static inline int is_sending(void)
 | 
				
			||||||
is_sending()
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return (outpkt.len != 0);
 | 
						return (outpkt.len != 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -416,7 +400,7 @@ send_ping(int fd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		send_packet(fd, 'p', data, sizeof(data));
 | 
							send_packet(fd, 'p', data, sizeof(data));
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		send_raw(fd, NULL, 0, userid, RAW_HDR_CMD_PING);
 | 
							send_raw(fd, NULL, 0, RAW_HDR_CMD_PING);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -480,7 +464,7 @@ dns_namedec(char *outdata, int outdatalen, char *buf, int buflen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* this also does undotify */
 | 
							/* this also does undotify */
 | 
				
			||||||
		return unpack_data(outdata, outdatalen, buf + 1, buflen - 4,
 | 
							return unpack_data(outdata, outdatalen, buf + 1, buflen - 4,
 | 
				
			||||||
				   b32);
 | 
									   &base32_ops);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case 'i': /* Hostname++ with base64 */
 | 
						case 'i': /* Hostname++ with base64 */
 | 
				
			||||||
	case 'I':
 | 
						case 'I':
 | 
				
			||||||
| 
						 | 
					@ -490,7 +474,7 @@ dns_namedec(char *outdata, int outdatalen, char *buf, int buflen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* this also does undotify */
 | 
							/* this also does undotify */
 | 
				
			||||||
		return unpack_data(outdata, outdatalen, buf + 1, buflen - 4,
 | 
							return unpack_data(outdata, outdatalen, buf + 1, buflen - 4,
 | 
				
			||||||
				   b64);
 | 
									   &base64_ops);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case 'j': /* Hostname++ with base64u */
 | 
						case 'j': /* Hostname++ with base64u */
 | 
				
			||||||
	case 'J':
 | 
						case 'J':
 | 
				
			||||||
| 
						 | 
					@ -500,7 +484,7 @@ dns_namedec(char *outdata, int outdatalen, char *buf, int buflen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* this also does undotify */
 | 
							/* this also does undotify */
 | 
				
			||||||
		return unpack_data(outdata, outdatalen, buf + 1, buflen - 4,
 | 
							return unpack_data(outdata, outdatalen, buf + 1, buflen - 4,
 | 
				
			||||||
				   b64u);
 | 
									   &base64u_ops);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case 'k': /* Hostname++ with base128 */
 | 
						case 'k': /* Hostname++ with base128 */
 | 
				
			||||||
	case 'K':
 | 
						case 'K':
 | 
				
			||||||
| 
						 | 
					@ -510,35 +494,35 @@ dns_namedec(char *outdata, int outdatalen, char *buf, int buflen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* this also does undotify */
 | 
							/* this also does undotify */
 | 
				
			||||||
		return unpack_data(outdata, outdatalen, buf + 1, buflen - 4,
 | 
							return unpack_data(outdata, outdatalen, buf + 1, buflen - 4,
 | 
				
			||||||
				   b128);
 | 
									   &base128_ops);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case 't': /* plain base32(Thirty-two) from TXT */
 | 
						case 't': /* plain base32(Thirty-two) from TXT */
 | 
				
			||||||
	case 'T':
 | 
						case 'T':
 | 
				
			||||||
		if (buflen < 2)
 | 
							if (buflen < 2)
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return b32->decode(outdata, &outdatalenu, buf + 1, buflen - 1);
 | 
							return base32_ops.decode(outdata, &outdatalenu, buf + 1, buflen - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case 's': /* plain base64(Sixty-four) from TXT */
 | 
						case 's': /* plain base64(Sixty-four) from TXT */
 | 
				
			||||||
	case 'S':
 | 
						case 'S':
 | 
				
			||||||
		if (buflen < 2)
 | 
							if (buflen < 2)
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return b64->decode(outdata, &outdatalenu, buf + 1, buflen - 1);
 | 
							return base64_ops.decode(outdata, &outdatalenu, buf + 1, buflen - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case 'u': /* plain base64u (Underscore) from TXT */
 | 
						case 'u': /* plain base64u (Underscore) from TXT */
 | 
				
			||||||
	case 'U':
 | 
						case 'U':
 | 
				
			||||||
		if (buflen < 2)
 | 
							if (buflen < 2)
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return b64u->decode(outdata, &outdatalenu, buf + 1, buflen - 1);
 | 
							return base64_ops.decode(outdata, &outdatalenu, buf + 1, buflen - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case 'v': /* plain base128 from TXT */
 | 
						case 'v': /* plain base128 from TXT */
 | 
				
			||||||
	case 'V':
 | 
						case 'V':
 | 
				
			||||||
		if (buflen < 2)
 | 
							if (buflen < 2)
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return b128->decode(outdata, &outdatalenu, buf + 1, buflen - 1);
 | 
							return base128_ops.decode(outdata, &outdatalenu, buf + 1, buflen - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case 'r': /* Raw binary from TXT */
 | 
						case 'r': /* Raw binary from TXT */
 | 
				
			||||||
	case 'R':
 | 
						case 'R':
 | 
				
			||||||
| 
						 | 
					@ -849,7 +833,7 @@ tunnel_dns(int tun_fd, int dns_fd)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* read==1 happens with "QMEM" illegal replies, caused by
 | 
							/* read == 1 happens with "QMEM" illegal replies, caused by
 | 
				
			||||||
		   heavy reordering, or after short disconnections when
 | 
							   heavy reordering, or after short disconnections when
 | 
				
			||||||
		   data-CMC has looped around into the "duplicate" values.
 | 
							   data-CMC has looped around into the "duplicate" values.
 | 
				
			||||||
		   All these cases are helped by faster pinging. */
 | 
							   All these cases are helped by faster pinging. */
 | 
				
			||||||
| 
						 | 
					@ -1271,116 +1255,74 @@ send_version(int fd, uint32_t version)
 | 
				
			||||||
	send_packet(fd, 'v', data, sizeof(data));
 | 
						send_packet(fd, 'v', data, sizeof(data));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Add lower 15 bits of rand seed as base32,
 | 
				
			||||||
 | 
					 * followed by a dot and the tunnel domain and send */
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
send_ip_request(int fd, int userid)
 | 
					send_handshake_query(int fd, char *prefix)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char buf[512] = "i____.";
 | 
						char buf[300];
 | 
				
			||||||
	buf[1] = b32_5to8(userid);
 | 
						char cmc_dot[5];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	buf[2] = b32_5to8((rand_seed >> 10) & 0x1f);
 | 
						cmc_dot[0] = b32_5to8((rand_seed >> 10) & 0x1f);
 | 
				
			||||||
	buf[3] = b32_5to8((rand_seed >> 5) & 0x1f);
 | 
						cmc_dot[1] = b32_5to8((rand_seed >> 5) & 0x1f);
 | 
				
			||||||
	buf[4] = b32_5to8((rand_seed ) & 0x1f);
 | 
						cmc_dot[2] = b32_5to8((rand_seed) & 0x1f);
 | 
				
			||||||
 | 
						cmc_dot[3] = '.';
 | 
				
			||||||
 | 
						cmc_dot[4] = 0;
 | 
				
			||||||
	rand_seed++;
 | 
						rand_seed++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	strncat(buf, topdomain, 512 - strlen(buf));
 | 
						buf[0] = 0;
 | 
				
			||||||
 | 
						strncat(buf, prefix, 60); /* 63 - space for 3 CMC bytes */
 | 
				
			||||||
 | 
						strcat(buf, cmc_dot);
 | 
				
			||||||
 | 
						strncat(buf, topdomain, sizeof(buf) - strlen(buf) - 1);
 | 
				
			||||||
	send_query(fd, buf);
 | 
						send_query(fd, buf);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
send_raw_udp_login(int dns_fd, int userid, int seed)
 | 
					send_raw_udp_login(int dns_fd, int seed)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char buf[16];
 | 
						char buf[16];
 | 
				
			||||||
	login_calculate(buf, 16, password, seed + 1);
 | 
						login_calculate(buf, 16, password, seed + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	send_raw(dns_fd, buf, sizeof(buf), userid, RAW_HDR_CMD_LOGIN);
 | 
						send_raw(dns_fd, buf, sizeof(buf), RAW_HDR_CMD_LOGIN);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
send_upenctest(int fd, char *s)
 | 
					send_upenctest(int fd, const char *s)
 | 
				
			||||||
/* NOTE: String may be at most 63-4=59 chars to fit in 1 dns chunk. */
 | 
					/* NOTE: String may be at most 63-4=59 chars to fit in 1 dns chunk. */
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char buf[512] = "z___";
 | 
						char buf[512] = "z___";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	buf[1] = b32_5to8((rand_seed >> 10) & 0x1f);
 | 
						buf[1] = b32_5to8((rand_seed >> 10) & 0x1f);
 | 
				
			||||||
	buf[2] = b32_5to8((rand_seed >> 5) & 0x1f);
 | 
						buf[2] = b32_5to8((rand_seed >> 5) & 0x1f);
 | 
				
			||||||
	buf[3] = b32_5to8((rand_seed ) & 0x1f);
 | 
						buf[3] = b32_5to8((rand_seed) & 0x1f);
 | 
				
			||||||
	rand_seed++;
 | 
						rand_seed++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	strncat(buf, s, 512);
 | 
						strncat(buf, s, 128);
 | 
				
			||||||
	strncat(buf, ".", 512);
 | 
						strncat(buf, ".", 2);
 | 
				
			||||||
	strncat(buf, topdomain, 512 - strlen(buf));
 | 
						strncat(buf, topdomain, 512 - strlen(buf));
 | 
				
			||||||
	send_query(fd, buf);
 | 
						send_query(fd, buf);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
send_downenctest(int fd, char downenc, int variant, char *s, int slen)
 | 
					send_downenctest(int fd, char downenc, int variant)
 | 
				
			||||||
/* Note: content/handling of s is not defined yet. */
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char buf[512] = "y_____.";
 | 
						char prefix[4] = "y__";
 | 
				
			||||||
 | 
						prefix[1] = tolower(downenc);
 | 
				
			||||||
 | 
						prefix[2] = b32_5to8(variant);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	buf[1] = tolower(downenc);
 | 
						/* Use send_query directly if we ever send more data here. */
 | 
				
			||||||
	buf[2] = b32_5to8(variant);
 | 
						send_handshake_query(fd, prefix);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	buf[3] = b32_5to8((rand_seed >> 10) & 0x1f);
 | 
					 | 
				
			||||||
	buf[4] = b32_5to8((rand_seed >> 5) & 0x1f);
 | 
					 | 
				
			||||||
	buf[5] = b32_5to8((rand_seed ) & 0x1f);
 | 
					 | 
				
			||||||
	rand_seed++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	strncat(buf, topdomain, 512 - strlen(buf));
 | 
					 | 
				
			||||||
	send_query(fd, buf);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
send_codec_switch(int fd, int userid, int bits)
 | 
					send_lazy_switch(int fd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char buf[512] = "s_____.";
 | 
						char sw_lazy[] = { 'o', b32_5to8(userid), 'i', 0 };
 | 
				
			||||||
	buf[1] = b32_5to8(userid);
 | 
					 | 
				
			||||||
	buf[2] = b32_5to8(bits);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	buf[3] = b32_5to8((rand_seed >> 10) & 0x1f);
 | 
					 | 
				
			||||||
	buf[4] = b32_5to8((rand_seed >> 5) & 0x1f);
 | 
					 | 
				
			||||||
	buf[5] = b32_5to8((rand_seed ) & 0x1f);
 | 
					 | 
				
			||||||
	rand_seed++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	strncat(buf, topdomain, 512 - strlen(buf));
 | 
					 | 
				
			||||||
	send_query(fd, buf);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
send_downenc_switch(int fd, int userid)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	char buf[512] = "o_____.";
 | 
					 | 
				
			||||||
	buf[1] = b32_5to8(userid);
 | 
					 | 
				
			||||||
	buf[2] = tolower(downenc);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	buf[3] = b32_5to8((rand_seed >> 10) & 0x1f);
 | 
					 | 
				
			||||||
	buf[4] = b32_5to8((rand_seed >> 5) & 0x1f);
 | 
					 | 
				
			||||||
	buf[5] = b32_5to8((rand_seed ) & 0x1f);
 | 
					 | 
				
			||||||
	rand_seed++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	strncat(buf, topdomain, 512 - strlen(buf));
 | 
					 | 
				
			||||||
	send_query(fd, buf);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
send_lazy_switch(int fd, int userid)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	char buf[512] = "o_____.";
 | 
					 | 
				
			||||||
	buf[1] = b32_5to8(userid);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (lazymode)
 | 
						if (lazymode)
 | 
				
			||||||
		buf[2] = 'l';
 | 
							sw_lazy[2] = 'l';
 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		buf[2] = 'i';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	buf[3] = b32_5to8((rand_seed >> 10) & 0x1f);
 | 
						send_handshake_query(fd, sw_lazy);
 | 
				
			||||||
	buf[4] = b32_5to8((rand_seed >> 5) & 0x1f);
 | 
					 | 
				
			||||||
	buf[5] = b32_5to8((rand_seed ) & 0x1f);
 | 
					 | 
				
			||||||
	rand_seed++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	strncat(buf, topdomain, 512 - strlen(buf));
 | 
					 | 
				
			||||||
	send_query(fd, buf);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
| 
						 | 
					@ -1395,7 +1337,7 @@ handshake_version(int dns_fd, int *seed)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; running && i < 5; i++) {
 | 
						for (i = 0; running && i < 5; i++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		send_version(dns_fd, VERSION);
 | 
							send_version(dns_fd, PROTOCOL_VERSION);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		read = handshake_waitdns(dns_fd, in, sizeof(in), 'v', 'V', i+1);
 | 
							read = handshake_waitdns(dns_fd, in, sizeof(in), 'v', 'V', i+1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1411,11 +1353,12 @@ handshake_version(int dns_fd, int *seed)
 | 
				
			||||||
				userid_char = hex[userid & 15];
 | 
									userid_char = hex[userid & 15];
 | 
				
			||||||
				userid_char2 = hex2[userid & 15];
 | 
									userid_char2 = hex2[userid & 15];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				fprintf(stderr, "Version ok, both using protocol v 0x%08x. You are user #%d\n", VERSION, userid);
 | 
									fprintf(stderr, "Version ok, both using protocol v 0x%08x. You are user #%d\n",
 | 
				
			||||||
 | 
										PROTOCOL_VERSION, userid);
 | 
				
			||||||
				return 0;
 | 
									return 0;
 | 
				
			||||||
			} else if (strncmp("VNAK", in, 4) == 0) {
 | 
								} else if (strncmp("VNAK", in, 4) == 0) {
 | 
				
			||||||
				warnx("You use protocol v 0x%08x, server uses v 0x%08x. Giving up",
 | 
									warnx("You use protocol v 0x%08x, server uses v 0x%08x. Giving up",
 | 
				
			||||||
						VERSION, payload);
 | 
											PROTOCOL_VERSION, payload);
 | 
				
			||||||
				return 1;
 | 
									return 1;
 | 
				
			||||||
			} else if (strncmp("VFUL", in, 4) == 0) {
 | 
								} else if (strncmp("VFUL", in, 4) == 0) {
 | 
				
			||||||
				warnx("Server full, all %d slots are taken. Try again later", payload);
 | 
									warnx("Server full, all %d slots are taken. Try again later", payload);
 | 
				
			||||||
| 
						 | 
					@ -1443,7 +1386,7 @@ handshake_login(int dns_fd, int seed)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	login_calculate(login, 16, password, seed);
 | 
						login_calculate(login, 16, password, seed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i=0; running && i<5 ;i++) {
 | 
						for (i = 0; running && i < 5; i++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		send_login(dns_fd, login, 16);
 | 
							send_login(dns_fd, login, 16);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1454,6 +1397,9 @@ handshake_login(int dns_fd, int seed)
 | 
				
			||||||
			if (strncmp("LNAK", in, 4) == 0) {
 | 
								if (strncmp("LNAK", in, 4) == 0) {
 | 
				
			||||||
				fprintf(stderr, "Bad password\n");
 | 
									fprintf(stderr, "Bad password\n");
 | 
				
			||||||
				return 1;
 | 
									return 1;
 | 
				
			||||||
 | 
								} else if (strncmp("BADIP", in, 5) == 0) {
 | 
				
			||||||
 | 
									warnx("BADIP: Server rejected sender IP address (maybe iodined -c will help)");
 | 
				
			||||||
 | 
									return 1;
 | 
				
			||||||
			} else if (sscanf(in, "%64[^-]-%64[^-]-%d-%d",
 | 
								} else if (sscanf(in, "%64[^-]-%64[^-]-%d-%d",
 | 
				
			||||||
				server, client, &mtu, &netmask) == 4) {
 | 
									server, client, &mtu, &netmask) == 4) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1482,31 +1428,43 @@ static int
 | 
				
			||||||
handshake_raw_udp(int dns_fd, int seed)
 | 
					handshake_raw_udp(int dns_fd, int seed)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct timeval tv;
 | 
						struct timeval tv;
 | 
				
			||||||
 | 
						char get_ip[] = { 'i', b32_5to8(userid), 0 };
 | 
				
			||||||
	char in[4096];
 | 
						char in[4096];
 | 
				
			||||||
	fd_set fds;
 | 
						fd_set fds;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	int r;
 | 
						int r;
 | 
				
			||||||
	int len;
 | 
						int len;
 | 
				
			||||||
	unsigned remoteaddr = 0;
 | 
						int got_addr;
 | 
				
			||||||
	struct in_addr server;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fprintf(stderr, "Testing raw UDP data to the server (skip with -r)");
 | 
						memset(&raw_serv, 0, sizeof(raw_serv));
 | 
				
			||||||
	for (i=0; running && i<3 ;i++) {
 | 
						got_addr = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		send_ip_request(dns_fd, userid);
 | 
						fprintf(stderr, "Requesting server address to attempt raw UDP mode (skip with -r) ");
 | 
				
			||||||
 | 
						fflush(stderr);
 | 
				
			||||||
 | 
						for (i = 0; running && i < 3; i++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							send_handshake_query(dns_fd, get_ip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		len = handshake_waitdns(dns_fd, in, sizeof(in), 'i', 'I', i+1);
 | 
							len = handshake_waitdns(dns_fd, in, sizeof(in), 'i', 'I', i+1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (len == 5 && in[0] == 'I') {
 | 
							if (len == 5 && in[0] == 'I') {
 | 
				
			||||||
			/* Received IP address */
 | 
								/* Received IPv4 address */
 | 
				
			||||||
			remoteaddr = (in[1] & 0xff);
 | 
								struct sockaddr_in *raw4_serv = (struct sockaddr_in *) &raw_serv;
 | 
				
			||||||
			remoteaddr <<= 8;
 | 
								raw4_serv->sin_family = AF_INET;
 | 
				
			||||||
			remoteaddr |= (in[2] & 0xff);
 | 
								memcpy(&raw4_serv->sin_addr, &in[1], sizeof(struct in_addr));
 | 
				
			||||||
			remoteaddr <<= 8;
 | 
								raw4_serv->sin_port = htons(53);
 | 
				
			||||||
			remoteaddr |= (in[3] & 0xff);
 | 
								raw_serv_len = sizeof(struct sockaddr_in);
 | 
				
			||||||
			remoteaddr <<= 8;
 | 
								got_addr = 1;
 | 
				
			||||||
			remoteaddr |= (in[4] & 0xff);
 | 
								break;
 | 
				
			||||||
			server.s_addr = ntohl(remoteaddr);
 | 
							}
 | 
				
			||||||
 | 
							if (len == 17 && in[0] == 'I') {
 | 
				
			||||||
 | 
								/* Received IPv6 address */
 | 
				
			||||||
 | 
								struct sockaddr_in6 *raw6_serv = (struct sockaddr_in6 *) &raw_serv;
 | 
				
			||||||
 | 
								raw6_serv->sin6_family = AF_INET6;
 | 
				
			||||||
 | 
								memcpy(&raw6_serv->sin6_addr, &in[1], sizeof(struct in6_addr));
 | 
				
			||||||
 | 
								raw6_serv->sin6_port = htons(53);
 | 
				
			||||||
 | 
								raw_serv_len = sizeof(struct sockaddr_in6);
 | 
				
			||||||
 | 
								got_addr = 1;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1517,34 +1475,29 @@ handshake_raw_udp(int dns_fd, int seed)
 | 
				
			||||||
	if (!running)
 | 
						if (!running)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!remoteaddr) {
 | 
						if (!got_addr) {
 | 
				
			||||||
		fprintf(stderr, "Failed to get raw server IP, will use DNS mode.\n");
 | 
							fprintf(stderr, "Failed to get raw server IP, will use DNS mode.\n");
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	fprintf(stderr, "Server is at %s, trying raw login: ", inet_ntoa(server));
 | 
						fprintf(stderr, "Server is at %s, trying raw login: (skip with -r) ",
 | 
				
			||||||
 | 
							format_addr(&raw_serv, raw_serv_len));
 | 
				
			||||||
	fflush(stderr);
 | 
						fflush(stderr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Store address to iodined server */
 | 
					 | 
				
			||||||
	memset(&raw_serv, 0, sizeof(raw_serv));
 | 
					 | 
				
			||||||
	raw_serv.sin_family = AF_INET;
 | 
					 | 
				
			||||||
	raw_serv.sin_port = htons(53);
 | 
					 | 
				
			||||||
	raw_serv.sin_addr = server;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* do login against port 53 on remote server
 | 
						/* do login against port 53 on remote server
 | 
				
			||||||
	 * based on the old seed. If reply received,
 | 
						 * based on the old seed. If reply received,
 | 
				
			||||||
	 * switch to raw udp mode */
 | 
						 * switch to raw udp mode */
 | 
				
			||||||
	for (i=0; running && i<4 ;i++) {
 | 
						for (i = 0; running && i < 4; i++) {
 | 
				
			||||||
		tv.tv_sec = i + 1;
 | 
							tv.tv_sec = i + 1;
 | 
				
			||||||
		tv.tv_usec = 0;
 | 
							tv.tv_usec = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		send_raw_udp_login(dns_fd, userid, seed);
 | 
							send_raw_udp_login(dns_fd, seed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		FD_ZERO(&fds);
 | 
							FD_ZERO(&fds);
 | 
				
			||||||
		FD_SET(dns_fd, &fds);
 | 
							FD_SET(dns_fd, &fds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
 | 
							r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if(r > 0) {
 | 
							if (r > 0) {
 | 
				
			||||||
			/* recv() needed for windows, dont change to read() */
 | 
								/* recv() needed for windows, dont change to read() */
 | 
				
			||||||
			len = recv(dns_fd, in, sizeof(in), 0);
 | 
								len = recv(dns_fd, in, sizeof(in), 0);
 | 
				
			||||||
			if (len >= (16 + RAW_HDR_LEN)) {
 | 
								if (len >= (16 + RAW_HDR_LEN)) {
 | 
				
			||||||
| 
						 | 
					@ -1568,7 +1521,7 @@ handshake_raw_udp(int dns_fd, int seed)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
handshake_upenctest(int dns_fd, char *s)
 | 
					handshake_upenctest(int dns_fd, const char *s)
 | 
				
			||||||
/* NOTE: *s may be max 59 chars; must start with "aA" for case-swap check
 | 
					/* NOTE: *s may be max 59 chars; must start with "aA" for case-swap check
 | 
				
			||||||
   Returns:
 | 
					   Returns:
 | 
				
			||||||
   -1: case swap, no need for any further test: error printed; or Ctrl-C
 | 
					   -1: case swap, no need for any further test: error printed; or Ctrl-C
 | 
				
			||||||
| 
						 | 
					@ -1578,13 +1531,13 @@ handshake_upenctest(int dns_fd, char *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char in[4096];
 | 
						char in[4096];
 | 
				
			||||||
	unsigned char *uin = (unsigned char *) in;
 | 
						unsigned char *uin = (unsigned char *) in;
 | 
				
			||||||
	unsigned char *us = (unsigned char *) s;
 | 
						const unsigned char *us = (const unsigned char *) s;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	int read;
 | 
						int read;
 | 
				
			||||||
	int slen;
 | 
						int slen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	slen = strlen(s);
 | 
						slen = strlen(s);
 | 
				
			||||||
	for (i=0; running && i<3 ;i++) {
 | 
						for (i = 0; running && i < 3; i++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		send_upenctest(dns_fd, s);
 | 
							send_upenctest(dns_fd, s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1660,14 +1613,14 @@ handshake_upenc_autodetect(int dns_fd)
 | 
				
			||||||
	   [A-Z] as first, and [A-Z0-9] as last char _per label_.
 | 
						   [A-Z] as first, and [A-Z0-9] as last char _per label_.
 | 
				
			||||||
	   Test by having '-' as last char.
 | 
						   Test by having '-' as last char.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
        char *pat64="aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ+0129-";
 | 
						const char *pat64 = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ+0129-";
 | 
				
			||||||
        char *pat64u="aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ_0129-";
 | 
						const char *pat64u = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ_0129-";
 | 
				
			||||||
        char *pat128a="aA-Aaahhh-Drink-mal-ein-J\344germeister-";
 | 
						const char *pat128a = "aA-Aaahhh-Drink-mal-ein-J\344germeister-";
 | 
				
			||||||
        char *pat128b="aA-La-fl\373te-na\357ve-fran\347aise-est-retir\351-\340-Cr\350te";
 | 
						const char *pat128b = "aA-La-fl\373te-na\357ve-fran\347aise-est-retir\351-\340-Cr\350te";
 | 
				
			||||||
        char *pat128c="aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ";
 | 
						const char *pat128c = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ";
 | 
				
			||||||
        char *pat128d="aA0123456789\274\275\276\277"
 | 
						const char *pat128d = "aA0123456789\274\275\276\277"
 | 
				
			||||||
		"\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317";
 | 
							"\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317";
 | 
				
			||||||
        char *pat128e="aA"
 | 
						const char *pat128e="aA"
 | 
				
			||||||
			"\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
 | 
								"\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
 | 
				
			||||||
			"\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357"
 | 
								"\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357"
 | 
				
			||||||
			"\360\361\362\363\364\365\366\367\370\371\372\373\374\375";
 | 
								"\360\361\362\363\364\365\366\367\370\371\372\373\374\375";
 | 
				
			||||||
| 
						 | 
					@ -1752,9 +1705,9 @@ handshake_downenctest(int dns_fd, char trycodec)
 | 
				
			||||||
	char *s = DOWNCODECCHECK1;
 | 
						char *s = DOWNCODECCHECK1;
 | 
				
			||||||
	int slen = DOWNCODECCHECK1_LEN;
 | 
						int slen = DOWNCODECCHECK1_LEN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i=0; running && i<3 ;i++) {
 | 
						for (i = 0; running && i < 3; i++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		send_downenctest(dns_fd, trycodec, 1, NULL, 0);
 | 
							send_downenctest(dns_fd, trycodec, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		read = handshake_waitdns(dns_fd, in, sizeof(in), 'y', 'Y', i+1);
 | 
							read = handshake_waitdns(dns_fd, in, sizeof(in), 'y', 'Y', i+1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1854,7 +1807,7 @@ handshake_qtypetest(int dns_fd, int timeout)
 | 
				
			||||||
	   byte values can be returned, which is needed for NULL/PRIVATE
 | 
						   byte values can be returned, which is needed for NULL/PRIVATE
 | 
				
			||||||
	   to work. */
 | 
						   to work. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	send_downenctest(dns_fd, trycodec, 1, NULL, 0);
 | 
						send_downenctest(dns_fd, trycodec, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	read = handshake_waitdns(dns_fd, in, sizeof(in), 'y', 'Y', timeout);
 | 
						read = handshake_waitdns(dns_fd, in, sizeof(in), 'y', 'Y', timeout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1978,9 +1931,9 @@ handshake_edns0_check(int dns_fd)
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		trycodec = 'T';
 | 
							trycodec = 'T';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i=0; running && i<3 ;i++) {
 | 
						for (i = 0; running && i < 3; i++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		send_downenctest(dns_fd, trycodec, 1, NULL, 0);
 | 
							send_downenctest(dns_fd, trycodec, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		read = handshake_waitdns(dns_fd, in, sizeof(in), 'y', 'Y', i+1);
 | 
							read = handshake_waitdns(dns_fd, in, sizeof(in), 'y', 'Y', i+1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2012,26 +1965,27 @@ handshake_edns0_check(int dns_fd)
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
handshake_switch_codec(int dns_fd, int bits)
 | 
					handshake_switch_codec(int dns_fd, int bits)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						char sw_codec[] = { 's', b32_5to8(userid), b32_5to8(bits), 0 };
 | 
				
			||||||
	char in[4096];
 | 
						char in[4096];
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	int read;
 | 
						int read;
 | 
				
			||||||
	struct encoder *tempenc;
 | 
						const struct encoder *tempenc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (bits == 5)
 | 
						if (bits == 5)
 | 
				
			||||||
		tempenc = get_base32_encoder();
 | 
							tempenc = &base32_ops;
 | 
				
			||||||
	else if (bits == 6)
 | 
						else if (bits == 6)
 | 
				
			||||||
		tempenc = get_base64_encoder();
 | 
							tempenc = &base64_ops;
 | 
				
			||||||
	else if (bits == 26)	/* "2nd" 6 bits per byte, with underscore */
 | 
						else if (bits == 26)	/* "2nd" 6 bits per byte, with underscore */
 | 
				
			||||||
		tempenc = get_base64u_encoder();
 | 
							tempenc = &base64u_ops;
 | 
				
			||||||
	else if (bits == 7)
 | 
						else if (bits == 7)
 | 
				
			||||||
		tempenc = get_base128_encoder();
 | 
							tempenc = &base128_ops;
 | 
				
			||||||
	else return;
 | 
						else return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fprintf(stderr, "Switching upstream to codec %s\n", tempenc->name);
 | 
						fprintf(stderr, "Switching upstream to codec %s\n", tempenc->name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i=0; running && i<5 ;i++) {
 | 
						for (i = 0; running && i < 5; i++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		send_codec_switch(dns_fd, userid, bits);
 | 
							send_handshake_query(dns_fd, sw_codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		read = handshake_waitdns(dns_fd, in, sizeof(in), 's', 'S', i+1);
 | 
							read = handshake_waitdns(dns_fd, in, sizeof(in), 's', 'S', i+1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2066,6 +2020,7 @@ codec_revert:
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
handshake_switch_downenc(int dns_fd)
 | 
					handshake_switch_downenc(int dns_fd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						char sw_downenc[] = { 'o', b32_5to8(userid), tolower(downenc), 0 };
 | 
				
			||||||
	char in[4096];
 | 
						char in[4096];
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	int read;
 | 
						int read;
 | 
				
			||||||
| 
						 | 
					@ -2082,9 +2037,9 @@ handshake_switch_downenc(int dns_fd)
 | 
				
			||||||
		dname = "Raw";
 | 
							dname = "Raw";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fprintf(stderr, "Switching downstream to codec %s\n", dname);
 | 
						fprintf(stderr, "Switching downstream to codec %s\n", dname);
 | 
				
			||||||
	for (i=0; running && i<5 ;i++) {
 | 
						for (i = 0; running && i < 5; i++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		send_downenc_switch(dns_fd, userid);
 | 
							send_handshake_query(dns_fd, sw_downenc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		read = handshake_waitdns(dns_fd, in, sizeof(in), 'o', 'O', i+1);
 | 
							read = handshake_waitdns(dns_fd, in, sizeof(in), 'o', 'O', i+1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2123,9 +2078,9 @@ handshake_try_lazy(int dns_fd)
 | 
				
			||||||
	int read;
 | 
						int read;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fprintf(stderr, "Switching to lazy mode for low-latency\n");
 | 
						fprintf(stderr, "Switching to lazy mode for low-latency\n");
 | 
				
			||||||
	for (i=0; running && i<5; i++) {
 | 
						for (i = 0; running && i < 5 ;i++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		send_lazy_switch(dns_fd, userid);
 | 
							send_lazy_switch(dns_fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		read = handshake_waitdns(dns_fd, in, sizeof(in), 'o', 'O', i+1);
 | 
							read = handshake_waitdns(dns_fd, in, sizeof(in), 'o', 'O', i+1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2167,9 +2122,9 @@ handshake_lazyoff(int dns_fd)
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	int read;
 | 
						int read;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i=0; running && i<5; i++) {
 | 
						for (i = 0; running && i < 5; i++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		send_lazy_switch(dns_fd, userid);
 | 
							send_lazy_switch(dns_fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		read = handshake_waitdns(dns_fd, in, sizeof(in), 'o', 'O', 1);
 | 
							read = handshake_waitdns(dns_fd, in, sizeof(in), 'o', 'O', 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2273,7 +2228,7 @@ handshake_autoprobe_fragsize(int dns_fd)
 | 
				
			||||||
	fprintf(stderr, "Autoprobing max downstream fragment size... (skip with -m fragsize)\n");
 | 
						fprintf(stderr, "Autoprobing max downstream fragment size... (skip with -m fragsize)\n");
 | 
				
			||||||
	while (running && range > 0 && (range >= 8 || max_fragsize < 300)) {
 | 
						while (running && range > 0 && (range >= 8 || max_fragsize < 300)) {
 | 
				
			||||||
		/* stop the slow probing early when we have enough bytes anyway */
 | 
							/* stop the slow probing early when we have enough bytes anyway */
 | 
				
			||||||
		for (i=0; running && i<3 ;i++) {
 | 
							for (i = 0; running && i < 3; i++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			send_fragsize_probe(dns_fd, proposed_fragsize);
 | 
								send_fragsize_probe(dns_fd, proposed_fragsize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2341,7 +2296,7 @@ handshake_set_fragsize(int dns_fd, int fragsize)
 | 
				
			||||||
	int read;
 | 
						int read;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fprintf(stderr, "Setting downstream fragment size to max %d...\n", fragsize);
 | 
						fprintf(stderr, "Setting downstream fragment size to max %d...\n", fragsize);
 | 
				
			||||||
	for (i=0; running && i<5 ;i++) {
 | 
						for (i = 0; running && i < 5; i++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		send_set_downstream_fragsize(dns_fd, fragsize);
 | 
							send_set_downstream_fragsize(dns_fd, fragsize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										15
									
								
								src/client.h
								
								
								
								
							
							
						
						
									
										15
									
								
								src/client.h
								
								
								
								
							| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -18,23 +18,24 @@
 | 
				
			||||||
#ifndef __CLIENT_H__
 | 
					#ifndef __CLIENT_H__
 | 
				
			||||||
#define __CLIENT_H__
 | 
					#define __CLIENT_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void client_init();
 | 
					void client_init(void);
 | 
				
			||||||
void client_stop();
 | 
					void client_stop(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum connection client_get_conn();
 | 
					enum connection client_get_conn(void);
 | 
				
			||||||
const char *client_get_raw_addr();
 | 
					const char *client_get_raw_addr(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void client_set_nameserver(struct sockaddr_storage *, int);
 | 
					void client_set_nameserver(struct sockaddr_storage *, int);
 | 
				
			||||||
void client_set_topdomain(const char *cp);
 | 
					void client_set_topdomain(const char *cp);
 | 
				
			||||||
void client_set_password(const char *cp);
 | 
					void client_set_password(const char *cp);
 | 
				
			||||||
int client_set_qtype(char *qtype);
 | 
					int client_set_qtype(char *qtype);
 | 
				
			||||||
char *client_get_qtype();
 | 
					char *client_get_qtype(void);
 | 
				
			||||||
void client_set_downenc(char *encoding);
 | 
					void client_set_downenc(char *encoding);
 | 
				
			||||||
void client_set_selecttimeout(int select_timeout);
 | 
					void client_set_selecttimeout(int select_timeout);
 | 
				
			||||||
void client_set_lazymode(int lazy_mode);
 | 
					void client_set_lazymode(int lazy_mode);
 | 
				
			||||||
void client_set_hostname_maxlen(int i);
 | 
					void client_set_hostname_maxlen(int i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int client_handshake(int dns_fd, int raw_mode, int autodetect_frag_size, int fragsize);
 | 
					int client_handshake(int dns_fd, int raw_mode, int autodetect_frag_size,
 | 
				
			||||||
 | 
							     int fragsize);
 | 
				
			||||||
int client_tunnel(int tun_fd, int dns_fd);
 | 
					int client_tunnel(int tun_fd, int dns_fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										139
									
								
								src/common.c
								
								
								
								
							
							
						
						
									
										139
									
								
								src/common.c
								
								
								
								
							| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 * Copyright (c) 2007 Albert Lee <trisk@acm.jhu.edu>.
 | 
					 * Copyright (c) 2007 Albert Lee <trisk@acm.jhu.edu>.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -101,18 +101,16 @@ int setgroups(int count, int *groups)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
check_superuser(void (*usage_fn)(void))
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
#ifndef WINDOWS32
 | 
					#ifndef WINDOWS32
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					check_superuser(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
	if (geteuid() != 0) {
 | 
						if (geteuid() != 0) {
 | 
				
			||||||
		warnx("Run as root and you'll be happy.\n");
 | 
							warnx("Run as root and you'll be happy.");
 | 
				
			||||||
		usage_fn();
 | 
							exit(-1);
 | 
				
			||||||
		/* NOTREACHED */
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *
 | 
					char *
 | 
				
			||||||
format_addr(struct sockaddr_storage *sockaddr, int sockaddr_len)
 | 
					format_addr(struct sockaddr_storage *sockaddr, int sockaddr_len)
 | 
				
			||||||
| 
						 | 
					@ -173,7 +171,13 @@ get_addr(char *host, int port, int addr_family, int flags, struct sockaddr_stora
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
open_dns(struct sockaddr_storage *sockaddr, size_t sockaddr_len)
 | 
					open_dns(struct sockaddr_storage *sockaddr, size_t sockaddr_len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int flag = 1;
 | 
						return open_dns_opt(sockaddr, sockaddr_len, -1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					open_dns_opt(struct sockaddr_storage *sockaddr, size_t sockaddr_len, int v6only)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int flag;
 | 
				
			||||||
	int fd;
 | 
						int fd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((fd = socket(sockaddr->ss_family, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
 | 
						if ((fd = socket(sockaddr->ss_family, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
 | 
				
			||||||
| 
						 | 
					@ -187,20 +191,21 @@ open_dns(struct sockaddr_storage *sockaddr, size_t sockaddr_len)
 | 
				
			||||||
	setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void*) &flag, sizeof(flag));
 | 
						setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void*) &flag, sizeof(flag));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef WINDOWS32
 | 
					#ifndef WINDOWS32
 | 
				
			||||||
	/* To get destination address from each UDP datagram, see iodined.c:read_dns() */
 | 
					 | 
				
			||||||
	setsockopt(fd, IPPROTO_IP, DSTADDR_SOCKOPT, (const void*) &flag, sizeof(flag));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fd_set_close_on_exec(fd);
 | 
						fd_set_close_on_exec(fd);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (sockaddr->ss_family == AF_INET6 && v6only >= 0) {
 | 
				
			||||||
 | 
							setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const void*) &v6only, sizeof(v6only));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef IP_OPT_DONT_FRAG
 | 
					#ifdef IP_OPT_DONT_FRAG
 | 
				
			||||||
	/* Set dont-fragment ip header flag */
 | 
						/* Set dont-fragment ip header flag */
 | 
				
			||||||
	flag = DONT_FRAG_VALUE;
 | 
						flag = DONT_FRAG_VALUE;
 | 
				
			||||||
	setsockopt(fd, IPPROTO_IP, IP_OPT_DONT_FRAG, (const void*) &flag, sizeof(flag));
 | 
						setsockopt(fd, IPPROTO_IP, IP_OPT_DONT_FRAG, (const void*) &flag, sizeof(flag));
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if(bind(fd, (struct sockaddr*) sockaddr, sockaddr_len) < 0)
 | 
						if (bind(fd, (struct sockaddr*) sockaddr, sockaddr_len) < 0)
 | 
				
			||||||
		err(1, "bind");
 | 
							err(1, "bind() to %s", format_addr(sockaddr, sockaddr_len));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fprintf(stderr, "Opened IPv%d UDP socket\n", sockaddr->ss_family == AF_INET6 ? 6 : 4);
 | 
						fprintf(stderr, "Opened IPv%d UDP socket\n", sockaddr->ss_family == AF_INET6 ? 6 : 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -300,7 +305,7 @@ read_password(char *buf, size_t len)
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fprintf(stderr, "Enter password: ");
 | 
						fprintf(stderr, "Enter tunnel password: ");
 | 
				
			||||||
	fflush(stderr);
 | 
						fflush(stderr);
 | 
				
			||||||
#ifndef WINDOWS32
 | 
					#ifndef WINDOWS32
 | 
				
			||||||
	fscanf(stdin, "%79[^\n]", pwd);
 | 
						fscanf(stdin, "%79[^\n]", pwd);
 | 
				
			||||||
| 
						 | 
					@ -327,7 +332,7 @@ read_password(char *buf, size_t len)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
check_topdomain(char *str, char **errormsg)
 | 
					check_topdomain(char *str, int allow_wildcard, char **errormsg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	int dots = 0;
 | 
						int dots = 0;
 | 
				
			||||||
| 
						 | 
					@ -347,8 +352,8 @@ check_topdomain(char *str, char **errormsg)
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for( i = 0; i < strlen(str); i++) {
 | 
						for (i = 0; i < strlen(str); i++) {
 | 
				
			||||||
		if(str[i] == '.') {
 | 
							if (str[i] == '.') {
 | 
				
			||||||
			dots++;
 | 
								dots++;
 | 
				
			||||||
			if (chunklen == 0) {
 | 
								if (chunklen == 0) {
 | 
				
			||||||
				if (errormsg) *errormsg = "Consecutive dots";
 | 
									if (errormsg) *errormsg = "Consecutive dots";
 | 
				
			||||||
| 
						 | 
					@ -362,9 +367,21 @@ check_topdomain(char *str, char **errormsg)
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			chunklen++;
 | 
								chunklen++;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if( (str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') ||
 | 
							if ((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') ||
 | 
				
			||||||
				isdigit(str[i]) || str[i] == '-' || str[i] == '.' ) {
 | 
									isdigit(str[i]) || str[i] == '-' || str[i] == '.') {
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
							} else if (allow_wildcard && str[i] == '*') {
 | 
				
			||||||
 | 
								/* First char allowed to be wildcard, if followed by dot */
 | 
				
			||||||
 | 
								if (i == 0) {
 | 
				
			||||||
 | 
									if (str[i+1] == '.') {
 | 
				
			||||||
 | 
										continue;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if (errormsg) *errormsg = "Wildcard (*) must be followed by dot";
 | 
				
			||||||
 | 
									return 1;
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									if (errormsg) *errormsg = "Wildcard (*) only allowed as first char";
 | 
				
			||||||
 | 
									return 1;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			if (errormsg) *errormsg = "Contains illegal character (allowed: [a-zA-Z0-9-.])";
 | 
								if (errormsg) *errormsg = "Contains illegal character (allowed: [a-zA-Z0-9-.])";
 | 
				
			||||||
			return 1;
 | 
								return 1;
 | 
				
			||||||
| 
						 | 
					@ -387,6 +404,52 @@ check_topdomain(char *str, char **errormsg)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					query_datalen(const char *qname, const char *topdomain)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* Return number of data bytes embedded in DNS query name,
 | 
				
			||||||
 | 
						 * or -1 if domains do not match.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						int qpos = strlen(qname);
 | 
				
			||||||
 | 
						int tpos = strlen(topdomain);
 | 
				
			||||||
 | 
						if (tpos < 3 || qpos < tpos) {
 | 
				
			||||||
 | 
							/* Domain or query name too short */
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						/* Backward string compare */
 | 
				
			||||||
 | 
						qpos--;
 | 
				
			||||||
 | 
						tpos--;
 | 
				
			||||||
 | 
						while (qpos >= 0) {
 | 
				
			||||||
 | 
							if (topdomain[tpos] == '*') {
 | 
				
			||||||
 | 
								/* Wild match, is first in topdomain */
 | 
				
			||||||
 | 
								if (qname[qpos] == '*') {
 | 
				
			||||||
 | 
									/* Don't match against stars in query name */
 | 
				
			||||||
 | 
									return -1;
 | 
				
			||||||
 | 
								} else if (qpos == 0 || qname[qpos-1] == '.') {
 | 
				
			||||||
 | 
									/* Reached start of query name or chunk separator */
 | 
				
			||||||
 | 
									return qpos;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								qpos--;
 | 
				
			||||||
 | 
							} else if (tolower(qname[qpos]) == tolower(topdomain[tpos])) {
 | 
				
			||||||
 | 
								/* Matching char, exclude wildcard in query name */
 | 
				
			||||||
 | 
								if (tpos == 0) {
 | 
				
			||||||
 | 
									/* Fully matched domain */
 | 
				
			||||||
 | 
									if (qpos == 0 || qname[qpos-1] == '.') {
 | 
				
			||||||
 | 
										/* Start of name or has dot before matching topdomain */
 | 
				
			||||||
 | 
										return qpos;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									/* Query name has longer chunk than topdomain */
 | 
				
			||||||
 | 
									return -1;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								tpos--;
 | 
				
			||||||
 | 
								qpos--;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(WINDOWS32) || defined(ANDROID)
 | 
					#if defined(WINDOWS32) || defined(ANDROID)
 | 
				
			||||||
#ifndef ANDROID
 | 
					#ifndef ANDROID
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
| 
						 | 
					@ -398,12 +461,9 @@ inet_aton(const char *cp, struct in_addr *inp)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
warn(const char *fmt, ...)
 | 
					vwarn(const char *fmt, va_list list)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	va_list list;
 | 
						if (fmt) vfprintf(stderr, fmt, list);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	va_start(list, fmt);
 | 
					 | 
				
			||||||
	if (fmt) fprintf(stderr, fmt, list);
 | 
					 | 
				
			||||||
#ifndef ANDROID
 | 
					#ifndef ANDROID
 | 
				
			||||||
	if (errno == 0) {
 | 
						if (errno == 0) {
 | 
				
			||||||
		fprintf(stderr, ": WSA error %d\n", WSAGetLastError());
 | 
							fprintf(stderr, ": WSA error %d\n", WSAGetLastError());
 | 
				
			||||||
| 
						 | 
					@ -411,17 +471,15 @@ warn(const char *fmt, ...)
 | 
				
			||||||
		fprintf(stderr, ": %s\n", strerror(errno));
 | 
							fprintf(stderr, ": %s\n", strerror(errno));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	va_end(list);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
warnx(const char *fmt, ...)
 | 
					warn(const char *fmt, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	va_list list;
 | 
						va_list list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	va_start(list, fmt);
 | 
						va_start(list, fmt);
 | 
				
			||||||
	if (fmt) fprintf(stderr, fmt, list);
 | 
						vwarn(fmt, list);
 | 
				
			||||||
	fprintf(stderr, "\n");
 | 
					 | 
				
			||||||
	va_end(list);
 | 
						va_end(list);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -431,18 +489,35 @@ err(int eval, const char *fmt, ...)
 | 
				
			||||||
	va_list list;
 | 
						va_list list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	va_start(list, fmt);
 | 
						va_start(list, fmt);
 | 
				
			||||||
	warn(fmt, list);
 | 
						vwarn(fmt, list);
 | 
				
			||||||
	va_end(list);
 | 
						va_end(list);
 | 
				
			||||||
	exit(eval);
 | 
						exit(eval);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					vwarnx(const char *fmt, va_list list)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (fmt) vfprintf(stderr, fmt, list);
 | 
				
			||||||
 | 
						fprintf(stderr, "\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					warnx(const char *fmt, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						va_list list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_start(list, fmt);
 | 
				
			||||||
 | 
						vwarnx(fmt, list);
 | 
				
			||||||
 | 
						va_end(list);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
errx(int eval, const char *fmt, ...)
 | 
					errx(int eval, const char *fmt, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	va_list list;
 | 
						va_list list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	va_start(list, fmt);
 | 
						va_start(list, fmt);
 | 
				
			||||||
	warnx(fmt, list);
 | 
						vwarnx(fmt, list);
 | 
				
			||||||
	va_end(list);
 | 
						va_end(list);
 | 
				
			||||||
	exit(eval);
 | 
						exit(eval);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										49
									
								
								src/common.h
								
								
								
								
							
							
						
						
									
										49
									
								
								src/common.h
								
								
								
								
							| 
						 | 
					@ -1,8 +1,8 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2015 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -32,6 +32,7 @@
 | 
				
			||||||
#define RAW_HDR_GET_USR(x) ((x)[RAW_HDR_CMD] & RAW_HDR_USR_MASK)
 | 
					#define RAW_HDR_GET_USR(x) ((x)[RAW_HDR_CMD] & RAW_HDR_USR_MASK)
 | 
				
			||||||
extern const unsigned char raw_header[RAW_HDR_LEN];
 | 
					extern const unsigned char raw_header[RAW_HDR_LEN];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
#ifdef WINDOWS32
 | 
					#ifdef WINDOWS32
 | 
				
			||||||
#include "windows.h"
 | 
					#include "windows.h"
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
| 
						 | 
					@ -53,14 +54,6 @@ extern const unsigned char raw_header[RAW_HDR_LEN];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define QUERY_NAME_SIZE 256
 | 
					#define QUERY_NAME_SIZE 256
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined IP_RECVDSTADDR
 | 
					 | 
				
			||||||
# define DSTADDR_SOCKOPT IP_RECVDSTADDR
 | 
					 | 
				
			||||||
# define dstaddr(x) ((struct in_addr *) CMSG_DATA(x))
 | 
					 | 
				
			||||||
#elif defined IP_PKTINFO
 | 
					 | 
				
			||||||
# define DSTADDR_SOCKOPT IP_PKTINFO
 | 
					 | 
				
			||||||
# define dstaddr(x) (&(((struct in_pktinfo *)(CMSG_DATA(x)))->ipi_addr))
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined IP_MTU_DISCOVER
 | 
					#if defined IP_MTU_DISCOVER
 | 
				
			||||||
  /* Linux */
 | 
					  /* Linux */
 | 
				
			||||||
# define IP_OPT_DONT_FRAG IP_MTU_DISCOVER
 | 
					# define IP_OPT_DONT_FRAG IP_MTU_DISCOVER
 | 
				
			||||||
| 
						 | 
					@ -76,7 +69,8 @@ extern const unsigned char raw_header[RAW_HDR_LEN];
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define T_PRIVATE 65399
 | 
					#define T_PRIVATE 65399
 | 
				
			||||||
/* Undefined RR type; "private use" range, see http://www.bind9.net/dns-parameters */
 | 
					/* Undefined RR type; "private use" range, see
 | 
				
			||||||
 | 
					 * http://www.bind9.net/dns-parameters */
 | 
				
			||||||
#define T_UNSET 65432
 | 
					#define T_UNSET 65432
 | 
				
			||||||
/* Unused RR type, never actually sent */
 | 
					/* Unused RR type, never actually sent */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -95,45 +89,58 @@ struct query {
 | 
				
			||||||
	unsigned short type;
 | 
						unsigned short type;
 | 
				
			||||||
	unsigned short rcode;
 | 
						unsigned short rcode;
 | 
				
			||||||
	unsigned short id;
 | 
						unsigned short id;
 | 
				
			||||||
	struct in_addr destination;
 | 
						struct sockaddr_storage destination;
 | 
				
			||||||
 | 
						socklen_t dest_len;
 | 
				
			||||||
	struct sockaddr_storage from;
 | 
						struct sockaddr_storage from;
 | 
				
			||||||
	int fromlen;
 | 
						socklen_t fromlen;
 | 
				
			||||||
	unsigned short id2;
 | 
						unsigned short id2;
 | 
				
			||||||
	struct sockaddr from2;
 | 
						struct sockaddr_storage from2;
 | 
				
			||||||
	int fromlen2;
 | 
						socklen_t fromlen2;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum connection {
 | 
					enum connection {
 | 
				
			||||||
	CONN_RAW_UDP,
 | 
						CONN_RAW_UDP = 0,
 | 
				
			||||||
	CONN_DNS_NULL,
 | 
						CONN_DNS_NULL,
 | 
				
			||||||
	CONN_MAX
 | 
						CONN_MAX
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void check_superuser(void (*usage_fn)(void));
 | 
					#ifdef WINDOWS32
 | 
				
			||||||
 | 
					static inline void check_superuser(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					void check_superuser(void);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
char *format_addr(struct sockaddr_storage *sockaddr, int sockaddr_len);
 | 
					char *format_addr(struct sockaddr_storage *sockaddr, int sockaddr_len);
 | 
				
			||||||
int get_addr(char *, int, int, int, struct sockaddr_storage *);
 | 
					int get_addr(char *, int, int, int, struct sockaddr_storage *);
 | 
				
			||||||
int open_dns(struct sockaddr_storage *, size_t);
 | 
					int open_dns(struct sockaddr_storage *, size_t);
 | 
				
			||||||
 | 
					int open_dns_opt(struct sockaddr_storage *sockaddr, size_t sockaddr_len,
 | 
				
			||||||
 | 
							 int v6only);
 | 
				
			||||||
int open_dns_from_host(char *host, int port, int addr_family, int flags);
 | 
					int open_dns_from_host(char *host, int port, int addr_family, int flags);
 | 
				
			||||||
void close_dns(int);
 | 
					void close_dns(int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void do_chroot(char *);
 | 
					void do_chroot(char *);
 | 
				
			||||||
void do_setcon(char *);
 | 
					void do_setcon(char *);
 | 
				
			||||||
void do_detach();
 | 
					void do_detach(void);
 | 
				
			||||||
void do_pidfile(char *);
 | 
					void do_pidfile(char *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void read_password(char*, size_t);
 | 
					void read_password(char*, size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int check_topdomain(char *, char **);
 | 
					int check_topdomain(char *, int, char **);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int query_datalen(const char *qname, const char *topdomain);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(WINDOWS32) || defined(ANDROID)
 | 
					#if defined(WINDOWS32) || defined(ANDROID)
 | 
				
			||||||
#ifndef ANDROID
 | 
					#ifndef ANDROID
 | 
				
			||||||
int inet_aton(const char *cp, struct in_addr *inp);
 | 
					int inet_aton(const char *cp, struct in_addr *inp);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void err(int eval, const char *fmt, ...);
 | 
					void vwarn(const char *fmt, va_list list);
 | 
				
			||||||
void warn(const char *fmt, ...);
 | 
					void warn(const char *fmt, ...);
 | 
				
			||||||
void errx(int eval, const char *fmt, ...);
 | 
					void err(int eval, const char *fmt, ...);
 | 
				
			||||||
 | 
					void vwarnx(const char *fmt, va_list list);
 | 
				
			||||||
void warnx(const char *fmt, ...);
 | 
					void warnx(const char *fmt, ...);
 | 
				
			||||||
 | 
					void errx(int eval, const char *fmt, ...);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int recent_seqno(int , int);
 | 
					int recent_seqno(int , int);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										192
									
								
								src/dns.c
								
								
								
								
							
							
						
						
									
										192
									
								
								src/dns.c
								
								
								
								
							| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -27,9 +27,6 @@
 | 
				
			||||||
#ifdef WINDOWS32
 | 
					#ifdef WINDOWS32
 | 
				
			||||||
#include "windows.h"
 | 
					#include "windows.h"
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#ifdef ANDROID
 | 
					 | 
				
			||||||
#include "android_dns.h"
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#include <arpa/nameser.h>
 | 
					#include <arpa/nameser.h>
 | 
				
			||||||
#ifdef DARWIN
 | 
					#ifdef DARWIN
 | 
				
			||||||
#define BIND_8_COMPAT
 | 
					#define BIND_8_COMPAT
 | 
				
			||||||
| 
						 | 
					@ -38,6 +35,9 @@
 | 
				
			||||||
#include <netinet/in.h>
 | 
					#include <netinet/in.h>
 | 
				
			||||||
#include <arpa/inet.h>
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
#include <err.h>
 | 
					#include <err.h>
 | 
				
			||||||
 | 
					#ifdef ANDROID
 | 
				
			||||||
 | 
					#include "android_dns.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,8 +49,8 @@ int dnsc_use_edns0 = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CHECKLEN(x) if (buflen < (x) + (unsigned)(p-buf))  return 0
 | 
					#define CHECKLEN(x) if (buflen < (x) + (unsigned)(p-buf))  return 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr,
 | 
				
			||||||
dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_t datalen)
 | 
						       const char *data, size_t datalen)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	HEADER *header;
 | 
						HEADER *header;
 | 
				
			||||||
	short name;
 | 
						short name;
 | 
				
			||||||
| 
						 | 
					@ -91,7 +91,8 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_
 | 
				
			||||||
		/* Answer section */
 | 
							/* Answer section */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (q->type == T_CNAME || q->type == T_A) {
 | 
							if (q->type == T_CNAME || q->type == T_A) {
 | 
				
			||||||
			/* data is expected to be like "Hblabla.host.name.com\0" */
 | 
								/* data is expected to be like
 | 
				
			||||||
 | 
								 * "Hblabla.host.name.com\0" */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			char *startp;
 | 
								char *startp;
 | 
				
			||||||
			int namelen;
 | 
								int namelen;
 | 
				
			||||||
| 
						 | 
					@ -120,7 +121,7 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_
 | 
				
			||||||
			   For SRV, see RFC2782.
 | 
								   For SRV, see RFC2782.
 | 
				
			||||||
			 */
 | 
								 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			char *mxdata = data;
 | 
								const char *mxdata = data;
 | 
				
			||||||
			char *startp;
 | 
								char *startp;
 | 
				
			||||||
			int namelen;
 | 
								int namelen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -177,7 +178,6 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_
 | 
				
			||||||
			ancnt = 1;
 | 
								ancnt = 1;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			/* NULL has raw binary data */
 | 
								/* NULL has raw binary data */
 | 
				
			||||||
 | 
					 | 
				
			||||||
			CHECKLEN(10);
 | 
								CHECKLEN(10);
 | 
				
			||||||
			putshort(&p, name);
 | 
								putshort(&p, name);
 | 
				
			||||||
			putshort(&p, q->type);
 | 
								putshort(&p, q->type);
 | 
				
			||||||
| 
						 | 
					@ -227,10 +227,123 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_
 | 
				
			||||||
	return len;
 | 
						return len;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					/* Only used when iodined gets a AAAA type query */
 | 
				
			||||||
dns_encode_ns_response(char *buf, size_t buflen, struct query *q, char *topdomain)
 | 
					/* Mostly same as dns_encode_caa_response() below */
 | 
				
			||||||
 | 
					int dns_encode_aaaa_response(char *buf, size_t buflen, struct query *q,
 | 
				
			||||||
 | 
								   char *topdomain)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						HEADER *header;
 | 
				
			||||||
 | 
						int len;
 | 
				
			||||||
 | 
						int domain_len;
 | 
				
			||||||
 | 
						char *p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (buflen < sizeof(HEADER))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(buf, 0, buflen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						header = (HEADER*)buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						header->id = htons(q->id);
 | 
				
			||||||
 | 
						header->qr = 1;
 | 
				
			||||||
 | 
						header->opcode = 0;
 | 
				
			||||||
 | 
						header->aa = 1;
 | 
				
			||||||
 | 
						header->tc = 0;
 | 
				
			||||||
 | 
						header->rd = 0;
 | 
				
			||||||
 | 
						header->ra = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p = buf + sizeof(HEADER);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						header->qdcount = htons(1);
 | 
				
			||||||
 | 
						header->ancount = htons(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						domain_len = strlen(q->name) - strlen(topdomain);
 | 
				
			||||||
 | 
						if (domain_len < 0 || domain_len == 1)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						if (strcasecmp(q->name + domain_len, topdomain))
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						if (domain_len >= 1 && q->name[domain_len - 1] != '.')
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Query section */
 | 
				
			||||||
 | 
						putname(&p, buflen - (p - buf), q->name);	/* Name */
 | 
				
			||||||
 | 
						CHECKLEN(4);
 | 
				
			||||||
 | 
						putshort(&p, q->type);			/* Type */
 | 
				
			||||||
 | 
						putshort(&p, C_IN);			/* Class */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						len = p - buf;
 | 
				
			||||||
 | 
						return len;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/* Only used when iodined gets a CAA type query */
 | 
				
			||||||
 | 
					/* Mostly same as dns_encode_ns_response() below */
 | 
				
			||||||
 | 
					int dns_encode_caa_response(char *buf, size_t buflen, struct query *q,
 | 
				
			||||||
 | 
								   char *topdomain)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						HEADER *header;
 | 
				
			||||||
 | 
						int len;
 | 
				
			||||||
 | 
						short name;
 | 
				
			||||||
 | 
						int domain_len;
 | 
				
			||||||
 | 
						char *p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (buflen < sizeof(HEADER))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(buf, 0, buflen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						header = (HEADER*)buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						header->id = htons(q->id);
 | 
				
			||||||
 | 
						header->qr = 1;
 | 
				
			||||||
 | 
						header->opcode = 0;
 | 
				
			||||||
 | 
						header->aa = 1;
 | 
				
			||||||
 | 
						header->tc = 0;
 | 
				
			||||||
 | 
						header->rd = 0;
 | 
				
			||||||
 | 
						header->ra = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p = buf + sizeof(HEADER);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						header->qdcount = htons(1);
 | 
				
			||||||
 | 
						header->ancount = htons(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* pointer to start of name */
 | 
				
			||||||
 | 
						name = 0xc000 | ((p - buf) & 0x3fff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						domain_len = strlen(q->name) - strlen(topdomain);
 | 
				
			||||||
 | 
						if (domain_len < 0 || domain_len == 1)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						if (strcasecmp(q->name + domain_len, topdomain))
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						if (domain_len >= 1 && q->name[domain_len - 1] != '.')
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Query section */
 | 
				
			||||||
 | 
						putname(&p, buflen - (p - buf), q->name);	/* Name */
 | 
				
			||||||
 | 
						CHECKLEN(4);
 | 
				
			||||||
 | 
						putshort(&p, q->type);			/* Type */
 | 
				
			||||||
 | 
						putshort(&p, C_IN);			/* Class */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Answer section */
 | 
				
			||||||
 | 
						CHECKLEN(12);
 | 
				
			||||||
 | 
						putshort(&p, name);			/* Name */
 | 
				
			||||||
 | 
						putshort(&p, q->type);			/* Type */
 | 
				
			||||||
 | 
						putshort(&p, C_IN);			/* Class */
 | 
				
			||||||
 | 
						putlong(&p, 3600);			/* TTL */
 | 
				
			||||||
 | 
						putshort(&p, 22);			/* Data length */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* caa record */
 | 
				
			||||||
 | 
						CHECKLEN(22);
 | 
				
			||||||
 | 
						memcpy(p, "\x00\x05\x69\x73\x73\x75\x65\x6c\x65\x74\x73\x65\x6e\x63\x72\x79\x70" \
 | 
				
			||||||
 | 
								"\x74\x2e\x6f\x72\x67", 22);
 | 
				
			||||||
 | 
						p += 22;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						len = p - buf;
 | 
				
			||||||
 | 
						return len;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Only used when iodined gets an NS type query */
 | 
					/* Only used when iodined gets an NS type query */
 | 
				
			||||||
/* Mostly same as dns_encode_a_response() below */
 | 
					/* Mostly same as dns_encode_a_response() below */
 | 
				
			||||||
 | 
					int dns_encode_ns_response(char *buf, size_t buflen, struct query *q,
 | 
				
			||||||
 | 
								   char *topdomain)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	HEADER *header;
 | 
						HEADER *header;
 | 
				
			||||||
	int len;
 | 
						int len;
 | 
				
			||||||
| 
						 | 
					@ -260,7 +373,6 @@ dns_encode_ns_response(char *buf, size_t buflen, struct query *q, char *topdomai
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	header->qdcount = htons(1);
 | 
						header->qdcount = htons(1);
 | 
				
			||||||
	header->ancount = htons(1);
 | 
						header->ancount = htons(1);
 | 
				
			||||||
	header->arcount = htons(1);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* pointer to start of name */
 | 
						/* pointer to start of name */
 | 
				
			||||||
	name = 0xc000 | ((p - buf) & 0x3fff);
 | 
						name = 0xc000 | ((p - buf) & 0x3fff);
 | 
				
			||||||
| 
						 | 
					@ -299,6 +411,13 @@ dns_encode_ns_response(char *buf, size_t buflen, struct query *q, char *topdomai
 | 
				
			||||||
	putbyte(&p, 's');
 | 
						putbyte(&p, 's');
 | 
				
			||||||
	putshort(&p, topname);			/* Name Server */
 | 
						putshort(&p, topname);			/* Name Server */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Do we have an IPv4 address to send? */
 | 
				
			||||||
 | 
						if (q->destination.ss_family == AF_INET) {
 | 
				
			||||||
 | 
							struct sockaddr_in *dest = (struct sockaddr_in *) &q->destination;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* One additional record coming */
 | 
				
			||||||
 | 
							header->arcount = htons(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Additional data (A-record of NS server) */
 | 
							/* Additional data (A-record of NS server) */
 | 
				
			||||||
		CHECKLEN(12);
 | 
							CHECKLEN(12);
 | 
				
			||||||
		putshort(&p, nsname);		/* Name Server */
 | 
							putshort(&p, nsname);		/* Name Server */
 | 
				
			||||||
| 
						 | 
					@ -308,28 +427,33 @@ dns_encode_ns_response(char *buf, size_t buflen, struct query *q, char *topdomai
 | 
				
			||||||
		putshort(&p, 4);		/* Data length */
 | 
							putshort(&p, 4);		/* Data length */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* ugly hack to output IP address */
 | 
							/* ugly hack to output IP address */
 | 
				
			||||||
	ipp = (char *) &q->destination;
 | 
							ipp = (char *) &dest->sin_addr.s_addr;
 | 
				
			||||||
		CHECKLEN(4);
 | 
							CHECKLEN(4);
 | 
				
			||||||
		putbyte(&p, *(ipp++));
 | 
							putbyte(&p, *(ipp++));
 | 
				
			||||||
		putbyte(&p, *(ipp++));
 | 
							putbyte(&p, *(ipp++));
 | 
				
			||||||
		putbyte(&p, *(ipp++));
 | 
							putbyte(&p, *(ipp++));
 | 
				
			||||||
		putbyte(&p, *ipp);
 | 
							putbyte(&p, *ipp);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	len = p - buf;
 | 
						len = p - buf;
 | 
				
			||||||
	return len;
 | 
						return len;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					/* Only used when iodined gets an A type query for ns.topdomain or
 | 
				
			||||||
dns_encode_a_response(char *buf, size_t buflen, struct query *q)
 | 
					 * www.topdomain . Mostly same as dns_encode_ns_response() above */
 | 
				
			||||||
/* Only used when iodined gets an A type query for ns.topdomain or www.topdomain */
 | 
					int dns_encode_a_response(char *buf, size_t buflen, struct query *q)
 | 
				
			||||||
/* Mostly same as dns_encode_ns_response() above */
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct sockaddr_in *dest = (struct sockaddr_in *) &q->destination;
 | 
				
			||||||
	HEADER *header;
 | 
						HEADER *header;
 | 
				
			||||||
	int len;
 | 
						int len;
 | 
				
			||||||
	short name;
 | 
						short name;
 | 
				
			||||||
	char *ipp;
 | 
						char *ipp;
 | 
				
			||||||
	char *p;
 | 
						char *p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Check if we have an IPv4 address to send */
 | 
				
			||||||
 | 
						if (q->destination.ss_family != AF_INET)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (buflen < sizeof(HEADER))
 | 
						if (buflen < sizeof(HEADER))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -368,7 +492,7 @@ dns_encode_a_response(char *buf, size_t buflen, struct query *q)
 | 
				
			||||||
	putshort(&p, 4);	/* Data length */
 | 
						putshort(&p, 4);	/* Data length */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* ugly hack to output IP address */
 | 
						/* ugly hack to output IP address */
 | 
				
			||||||
	ipp = (char *) &q->destination;
 | 
						ipp = (char *) &dest->sin_addr.s_addr;
 | 
				
			||||||
	CHECKLEN(4);
 | 
						CHECKLEN(4);
 | 
				
			||||||
	putbyte(&p, *(ipp++));
 | 
						putbyte(&p, *(ipp++));
 | 
				
			||||||
	putbyte(&p, *(ipp++));
 | 
						putbyte(&p, *(ipp++));
 | 
				
			||||||
| 
						 | 
					@ -381,8 +505,7 @@ dns_encode_a_response(char *buf, size_t buflen, struct query *q)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef CHECKLEN
 | 
					#undef CHECKLEN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned short
 | 
					unsigned short dns_get_id(char *packet, size_t packetlen)
 | 
				
			||||||
dns_get_id(char *packet, size_t packetlen)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	HEADER *header;
 | 
						HEADER *header;
 | 
				
			||||||
	header = (HEADER*)packet;
 | 
						header = (HEADER*)packet;
 | 
				
			||||||
| 
						 | 
					@ -395,8 +518,8 @@ dns_get_id(char *packet, size_t packetlen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CHECKLEN(x) if (packetlen < (x) + (unsigned)(data-packet))  return 0
 | 
					#define CHECKLEN(x) if (packetlen < (x) + (unsigned)(data-packet))  return 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet,
 | 
				
			||||||
dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, size_t packetlen)
 | 
						       size_t packetlen)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char name[QUERY_NAME_SIZE];
 | 
						char name[QUERY_NAME_SIZE];
 | 
				
			||||||
	char rdata[4*1024];
 | 
						char rdata[4*1024];
 | 
				
			||||||
| 
						 | 
					@ -438,7 +561,7 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (qr) {
 | 
						switch (qr) {
 | 
				
			||||||
	case QR_ANSWER:
 | 
						case QR_ANSWER:
 | 
				
			||||||
		if(qdcount < 1) {
 | 
							if (qdcount < 1) {
 | 
				
			||||||
			/* We need a question */
 | 
								/* We need a question */
 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -494,6 +617,8 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz
 | 
				
			||||||
			readlong(packet, &data, &ttl);
 | 
								readlong(packet, &data, &ttl);
 | 
				
			||||||
			readshort(packet, &data, &rlen);
 | 
								readshort(packet, &data, &rlen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (type == T_CNAME) {
 | 
				
			||||||
 | 
									/* For tunnels, query type A has CNAME type answer */
 | 
				
			||||||
				memset(name, 0, sizeof(name));
 | 
									memset(name, 0, sizeof(name));
 | 
				
			||||||
				readname(packet, packetlen, &data, name, sizeof(name) - 1);
 | 
									readname(packet, packetlen, &data, name, sizeof(name) - 1);
 | 
				
			||||||
				name[sizeof(name)-1] = '\0';
 | 
									name[sizeof(name)-1] = '\0';
 | 
				
			||||||
| 
						 | 
					@ -501,6 +626,19 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz
 | 
				
			||||||
				buf[buflen - 1] = '\0';
 | 
									buf[buflen - 1] = '\0';
 | 
				
			||||||
				rv = strlen(buf);
 | 
									rv = strlen(buf);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								if (type == T_A) {
 | 
				
			||||||
 | 
									/* Answer type A includes only 4 bytes.
 | 
				
			||||||
 | 
									   Not used for tunneling. */
 | 
				
			||||||
 | 
									rv = MIN(rlen, sizeof(rdata));
 | 
				
			||||||
 | 
									rv = readdata(packet, &data, rdata, rv);
 | 
				
			||||||
 | 
									if (rv >= 2 && buf) {
 | 
				
			||||||
 | 
										rv = MIN(rv, buflen);
 | 
				
			||||||
 | 
										memcpy(buf, rdata, rv);
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										rv = 0;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		else if ((type == T_MX || type == T_SRV) && buf) {
 | 
							else if ((type == T_MX || type == T_SRV) && buf) {
 | 
				
			||||||
			/* We support 250 records, 250*(255+header) ~= 64kB.
 | 
								/* We support 250 records, 250*(255+header) ~= 64kB.
 | 
				
			||||||
			   Only exact 10-multiples are accepted, and gaps in
 | 
								   Only exact 10-multiples are accepted, and gaps in
 | 
				
			||||||
| 
						 | 
					@ -515,7 +653,7 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			memset(names, 0, sizeof(names));
 | 
								memset(names, 0, sizeof(names));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for (i=0; i < ancount; i++) {
 | 
								for (i = 0; i < ancount; i++) {
 | 
				
			||||||
				readname(packet, packetlen, &data, name, sizeof(name));
 | 
									readname(packet, packetlen, &data, name, sizeof(name));
 | 
				
			||||||
				CHECKLEN(12);
 | 
									CHECKLEN(12);
 | 
				
			||||||
				readshort(packet, &data, &type);
 | 
									readshort(packet, &data, &type);
 | 
				
			||||||
| 
						 | 
					@ -536,7 +674,8 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz
 | 
				
			||||||
					readname(packet, packetlen, &data,
 | 
										readname(packet, packetlen, &data,
 | 
				
			||||||
						 names[pref / 10 - 1],
 | 
											 names[pref / 10 - 1],
 | 
				
			||||||
						 QUERY_NAME_SIZE - 1);
 | 
											 QUERY_NAME_SIZE - 1);
 | 
				
			||||||
					names[pref / 10 - 1][QUERY_NAME_SIZE-1] = '\0';
 | 
										names[pref / 10 - 1]
 | 
				
			||||||
 | 
											[QUERY_NAME_SIZE-1] = '\0';
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				/* always trust rlen, not name encoding */
 | 
									/* always trust rlen, not name encoding */
 | 
				
			||||||
| 
						 | 
					@ -569,7 +708,8 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz
 | 
				
			||||||
			readlong(packet, &data, &ttl);
 | 
								readlong(packet, &data, &ttl);
 | 
				
			||||||
			readshort(packet, &data, &rlen);
 | 
								readshort(packet, &data, &rlen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			rv = readtxtbin(packet, &data, rlen, rdata, sizeof(rdata));
 | 
								rv = readtxtbin(packet, &data, rlen, rdata,
 | 
				
			||||||
 | 
									        sizeof(rdata));
 | 
				
			||||||
			if (rv >= 1) {
 | 
								if (rv >= 1) {
 | 
				
			||||||
				rv = MIN(rv, buflen);
 | 
									rv = MIN(rv, buflen);
 | 
				
			||||||
				memcpy(buf, rdata, rv);
 | 
									memcpy(buf, rdata, rv);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										11
									
								
								src/dns.h
								
								
								
								
							
							
						
						
									
										11
									
								
								src/dns.h
								
								
								
								
							| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -27,8 +27,13 @@ typedef enum {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int dnsc_use_edns0;
 | 
					extern int dnsc_use_edns0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int dns_encode(char *, size_t, struct query *, qr_t, char *, size_t);
 | 
					int dns_encode(char *, size_t, struct query *, qr_t, const char *, size_t);
 | 
				
			||||||
int dns_encode_ns_response(char *buf, size_t buflen, struct query *q, char *topdomain);
 | 
					int dns_encode_aaaa_response(char *buf, size_t buflen, struct query *q,
 | 
				
			||||||
 | 
								   char *topdomain);
 | 
				
			||||||
 | 
					int dns_encode_caa_response(char *buf, size_t buflen, struct query *q,
 | 
				
			||||||
 | 
								   char *topdomain);
 | 
				
			||||||
 | 
					int dns_encode_ns_response(char *buf, size_t buflen, struct query *q,
 | 
				
			||||||
 | 
								   char *topdomain);
 | 
				
			||||||
int dns_encode_a_response(char *buf, size_t buflen, struct query *q);
 | 
					int dns_encode_a_response(char *buf, size_t buflen, struct query *q);
 | 
				
			||||||
unsigned short dns_get_id(char *packet, size_t packetlen);
 | 
					unsigned short dns_get_id(char *packet, size_t packetlen);
 | 
				
			||||||
int dns_decode(char *, size_t, struct query *, qr_t, char *, size_t);
 | 
					int dns_decode(char *, size_t, struct query *, qr_t, char *, size_t);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -19,10 +19,9 @@
 | 
				
			||||||
#include "common.h"
 | 
					#include "common.h"
 | 
				
			||||||
#include "encoding.h"
 | 
					#include "encoding.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int build_hostname(char *buf, size_t buflen, const char *data,
 | 
				
			||||||
build_hostname(char *buf, size_t buflen,
 | 
							   const size_t datalen, const char *topdomain,
 | 
				
			||||||
		const char *data, const size_t datalen,
 | 
							   const struct encoder *encoder, int maxlen)
 | 
				
			||||||
		const char *topdomain, struct encoder *encoder, int maxlen)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	size_t space;
 | 
						size_t space;
 | 
				
			||||||
	char *b;
 | 
						char *b;
 | 
				
			||||||
| 
						 | 
					@ -30,14 +29,14 @@ build_hostname(char *buf, size_t buflen,
 | 
				
			||||||
	space = MIN((size_t)maxlen, buflen) - strlen(topdomain) - 8;
 | 
						space = MIN((size_t)maxlen, buflen) - strlen(topdomain) - 8;
 | 
				
			||||||
	/* 8 = 5 max header length + 1 dot before topdomain + 2 safety */
 | 
						/* 8 = 5 max header length + 1 dot before topdomain + 2 safety */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!encoder->places_dots())
 | 
						if (!encoder->places_dots)
 | 
				
			||||||
		space -= (space / 57); /* space for dots */
 | 
							space -= (space / 57); /* space for dots */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(buf, 0, buflen);
 | 
						memset(buf, 0, buflen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	encoder->encode(buf, &space, data, datalen);
 | 
						encoder->encode(buf, &space, data, datalen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!encoder->places_dots())
 | 
						if (!encoder->places_dots)
 | 
				
			||||||
		inline_dotify(buf, buflen);
 | 
							inline_dotify(buf, buflen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b = buf;
 | 
						b = buf;
 | 
				
			||||||
| 
						 | 
					@ -55,16 +54,15 @@ build_hostname(char *buf, size_t buflen,
 | 
				
			||||||
	return space;
 | 
						return space;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int unpack_data(char *buf, size_t buflen, char *data, size_t datalen,
 | 
				
			||||||
unpack_data(char *buf, size_t buflen, char *data, size_t datalen, struct encoder *enc)
 | 
							const struct encoder *enc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!enc->eats_dots())
 | 
						if (!enc->eats_dots)
 | 
				
			||||||
		datalen = inline_undotify(data, datalen);
 | 
							datalen = inline_undotify(data, datalen);
 | 
				
			||||||
	return enc->decode(buf, &buflen, data, datalen);
 | 
						return enc->decode(buf, &buflen, data, datalen);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int inline_dotify(char *buf, size_t buflen)
 | 
				
			||||||
inline_dotify(char *buf, size_t buflen)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned dots;
 | 
						unsigned dots;
 | 
				
			||||||
	unsigned pos;
 | 
						unsigned pos;
 | 
				
			||||||
| 
						 | 
					@ -101,8 +99,7 @@ inline_dotify(char *buf, size_t buflen)
 | 
				
			||||||
	return total;
 | 
						return total;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int inline_undotify(char *buf, size_t len)
 | 
				
			||||||
inline_undotify(char *buf, size_t len)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned pos;
 | 
						unsigned pos;
 | 
				
			||||||
	unsigned dots;
 | 
						unsigned dots;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,14 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson
 | 
				
			||||||
 | 
					 * Copyright (c) 2017 Ralf Ramsauer
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Authors:
 | 
				
			||||||
 | 
					 *   Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 | 
					 *   Erok Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 | 
					 *   Ralf Ramsauer <ralf@ramses-pyramidenbau.de>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -18,27 +24,42 @@
 | 
				
			||||||
#ifndef _ENCODING_H_
 | 
					#ifndef _ENCODING_H_
 | 
				
			||||||
#define _ENCODING_H_
 | 
					#define _ENCODING_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* All-0, all-1, 01010101, 10101010: each 4 times to make sure the pattern
 | 
					/* All-0, all-1, 01010101, 10101010: each 4 times to make sure the pattern
 | 
				
			||||||
   spreads across multiple encoded chars -> 16 bytes total.
 | 
					   spreads across multiple encoded chars -> 16 bytes total.
 | 
				
			||||||
   Followed by 32 bytes from my /dev/random; should be enough.
 | 
					   Followed by 32 bytes from my /dev/random; should be enough.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define DOWNCODECCHECK1      "\000\000\000\000\377\377\377\377\125\125\125\125\252\252\252\252\201\143\310\322\307\174\262\027\137\117\316\311\111\055\122\041\141\251\161\040\045\263\006\163\346\330\104\060\171\120\127\277"
 | 
					#define DOWNCODECCHECK1 \
 | 
				
			||||||
 | 
						"\000\000\000\000\377\377\377\377\125\125\125\125\252\252\252\252" \
 | 
				
			||||||
 | 
						"\201\143\310\322\307\174\262\027\137\117\316\311\111\055\122\041" \
 | 
				
			||||||
 | 
						"\141\251\161\040\045\263\006\163\346\330\104\060\171\120\127\277"
 | 
				
			||||||
#define DOWNCODECCHECK1_LEN  48
 | 
					#define DOWNCODECCHECK1_LEN  48
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct encoder {
 | 
					struct encoder {
 | 
				
			||||||
	char name[8];
 | 
						const char name[8];
 | 
				
			||||||
	int (*encode) (char *, size_t *, const void *, size_t);
 | 
						int (*encode)(char *dst, size_t *dstlen, const void *src, size_t srclen);
 | 
				
			||||||
	int (*decode) (void *, size_t *, const char *, size_t);
 | 
						int (*decode)(void *dst, size_t *dstlen, const char *src, size_t srclen);
 | 
				
			||||||
	int (*places_dots) (void);
 | 
					
 | 
				
			||||||
	int (*eats_dots) (void);
 | 
						const bool places_dots;
 | 
				
			||||||
	int (*blocksize_raw)(void);
 | 
						const bool eats_dots;
 | 
				
			||||||
	int (*blocksize_encoded)(void);
 | 
					
 | 
				
			||||||
 | 
						const int blocksize_raw;
 | 
				
			||||||
 | 
						const int blocksize_encoded;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int build_hostname(char *, size_t, const char *, const size_t, const char *, struct encoder *, int);
 | 
					int build_hostname(char *, size_t, const char *, const size_t, const char *,
 | 
				
			||||||
int unpack_data(char *, size_t, char *, size_t, struct encoder *);
 | 
							   const struct encoder *, int);
 | 
				
			||||||
 | 
					int unpack_data(char *, size_t, char *, size_t, const struct encoder *);
 | 
				
			||||||
int inline_dotify(char *, size_t);
 | 
					int inline_dotify(char *, size_t);
 | 
				
			||||||
int inline_undotify(char *, size_t);
 | 
					int inline_undotify(char *, size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern const struct encoder base32_ops;
 | 
				
			||||||
 | 
					extern const struct encoder base64_ops;
 | 
				
			||||||
 | 
					extern const struct encoder base64u_ops;
 | 
				
			||||||
 | 
					extern const struct encoder base128_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _ENCODING_H_ */
 | 
					int b32_5to8(int);
 | 
				
			||||||
 | 
					int b32_8to5(int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright (c) 2008-2014 Erik Ekman <yarrick@kryo.se>
 | 
					 * Copyright (c) 2008-2014 Erik Ekman <yarrick@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright (c) 2008-2014 Erik Ekman <yarrick@kryo.se>
 | 
					 * Copyright (c) 2008-2014 Erik Ekman <yarrick@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -33,7 +33,7 @@ struct fw_query {
 | 
				
			||||||
	unsigned short id;
 | 
						unsigned short id;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void fw_query_init();
 | 
					void fw_query_init(void);
 | 
				
			||||||
void fw_query_put(struct fw_query *fw_query);
 | 
					void fw_query_put(struct fw_query *fw_query);
 | 
				
			||||||
void fw_query_get(unsigned short query_id, struct fw_query **fw_query);
 | 
					void fw_query_get(unsigned short query_id, struct fw_query **fw_query);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										98
									
								
								src/iodine.c
								
								
								
								
							
							
						
						
									
										98
									
								
								src/iodine.c
								
								
								
								
							| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,7 @@
 | 
				
			||||||
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
					 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
| 
						 | 
					@ -48,6 +49,8 @@ WSADATA wsa_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(BSD) && !defined(__GLIBC__)
 | 
					#if !defined(BSD) && !defined(__GLIBC__)
 | 
				
			||||||
static char *__progname;
 | 
					static char *__progname;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					extern char *__progname;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PASSWORD_ENV_VAR "IODINE_PASS"
 | 
					#define PASSWORD_ENV_VAR "IODINE_PASS"
 | 
				
			||||||
| 
						 | 
					@ -61,63 +64,64 @@ sighandler(int sig)
 | 
				
			||||||
#if defined(__GNUC__) || defined(__clang__)
 | 
					#if defined(__GNUC__) || defined(__clang__)
 | 
				
			||||||
/* mark as no return to help some compilers to avoid warnings
 | 
					/* mark as no return to help some compilers to avoid warnings
 | 
				
			||||||
 * about use of uninitialized variables */
 | 
					 * about use of uninitialized variables */
 | 
				
			||||||
static void usage() __attribute__((noreturn));
 | 
					static inline void usage(void) __attribute__((noreturn));
 | 
				
			||||||
 | 
					static inline void help(FILE * stream, bool verbose) __attribute__((noreturn));
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void help(FILE *stream, bool verbose)
 | 
				
			||||||
usage() {
 | 
					{
 | 
				
			||||||
	extern char *__progname;
 | 
						fprintf(stream,
 | 
				
			||||||
 | 
							"iodine IP over DNS tunneling client\n\n"
 | 
				
			||||||
 | 
							"Usage: %s [-46fhrv] [-u user] [-t chrootdir] [-d device] [-P password]\n"
 | 
				
			||||||
 | 
							"              [-m maxfragsize] [-M maxlen] [-T type] [-O enc] [-L 0|1] [-I sec]\n"
 | 
				
			||||||
 | 
							"              [-z context] [-F pidfile] [nameserver] topdomain\n", __progname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fprintf(stderr, "Usage: %s [-v] [-h] [-f] [-r] [-u user] [-t chrootdir] [-d device] "
 | 
						if (!verbose)
 | 
				
			||||||
			"[-P password] [-m maxfragsize] [-M maxlen] [-T type] [-O enc] [-L 0|1] [-I sec] "
 | 
					 | 
				
			||||||
			"[-z context] [-F pidfile] [nameserver] topdomain\n", __progname);
 | 
					 | 
				
			||||||
		exit(2);
 | 
							exit(2);
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
						fprintf(stream,
 | 
				
			||||||
help() {
 | 
							"\nOptions to try if connection doesn't work:\n"
 | 
				
			||||||
	extern char *__progname;
 | 
							"  -4 to connect only to IPv4\n"
 | 
				
			||||||
 | 
							"  -6 to connect only to IPv6\n"
 | 
				
			||||||
	fprintf(stderr, "iodine IP over DNS tunneling client\n");
 | 
							"  -T force dns type: NULL, PRIVATE, TXT, SRV, MX, CNAME, A (default: autodetect)\n"
 | 
				
			||||||
	fprintf(stderr, "Usage: %s [-v] [-h] [-f] [-r] [-u user] [-t chrootdir] [-d device] "
 | 
							"  -O force downstream encoding for -T other than NULL: Base32, Base64, Base64u,\n"
 | 
				
			||||||
			"[-P password] [-m maxfragsize] [-M maxlen] [-T type] [-O enc] [-L 0|1] [-I sec] "
 | 
							"     Base128, or (only for TXT:) Raw  (default: autodetect)\n"
 | 
				
			||||||
			"[-z context] [-F pidfile] [nameserver] topdomain\n", __progname);
 | 
							"  -I max interval between requests (default 4 sec) to prevent DNS timeouts\n"
 | 
				
			||||||
	fprintf(stderr, "Options to try if connection doesn't work:\n");
 | 
							"  -L 1: use lazy mode for low-latency (default). 0: don't (implies -I1)\n"
 | 
				
			||||||
	fprintf(stderr, "  -T force dns type: NULL, PRIVATE, TXT, SRV, MX, CNAME, A (default: autodetect)\n");
 | 
							"  -m max size of downstream fragments (default: autodetect)\n"
 | 
				
			||||||
	fprintf(stderr, "  -O force downstream encoding for -T other than NULL: Base32, Base64, Base64u,\n");
 | 
							"  -M max size of upstream hostnames (~100-255, default: 255)\n"
 | 
				
			||||||
	fprintf(stderr, "     Base128, or (only for TXT:) Raw  (default: autodetect)\n");
 | 
							"  -r to skip raw UDP mode attempt\n"
 | 
				
			||||||
	fprintf(stderr, "  -I max interval between requests (default 4 sec) to prevent DNS timeouts\n");
 | 
							"  -P password used for authentication (max 32 chars will be used)\n\n"
 | 
				
			||||||
	fprintf(stderr, "  -L 1: use lazy mode for low-latency (default). 0: don't (implies -I1)\n");
 | 
							"Other options:\n"
 | 
				
			||||||
	fprintf(stderr, "  -m max size of downstream fragments (default: autodetect)\n");
 | 
							"  -v to print version info and exit\n"
 | 
				
			||||||
	fprintf(stderr, "  -M max size of upstream hostnames (~100-255, default: 255)\n");
 | 
							"  -h to print this help and exit\n"
 | 
				
			||||||
	fprintf(stderr, "  -r to skip raw UDP mode attempt\n");
 | 
							"  -f to keep running in foreground\n"
 | 
				
			||||||
	fprintf(stderr, "  -P password used for authentication (max 32 chars will be used)\n");
 | 
							"  -u name to drop privileges and run as user 'name'\n"
 | 
				
			||||||
	fprintf(stderr, "Other options:\n");
 | 
							"  -t dir to chroot to directory dir\n"
 | 
				
			||||||
	fprintf(stderr, "  -v to print version info and exit\n");
 | 
							"  -d device to set tunnel device name\n"
 | 
				
			||||||
	fprintf(stderr, "  -h to print this help and exit\n");
 | 
							"  -z context, to apply specified SELinux context after initialization\n"
 | 
				
			||||||
	fprintf(stderr, "  -f to keep running in foreground\n");
 | 
							"  -F pidfile to write pid to a file\n\n"
 | 
				
			||||||
	fprintf(stderr, "  -u name to drop privileges and run as user 'name'\n");
 | 
							"nameserver is the IP number/hostname of the relaying nameserver. If absent,\n"
 | 
				
			||||||
	fprintf(stderr, "  -t dir to chroot to directory dir\n");
 | 
							"           /etc/resolv.conf is used\n"
 | 
				
			||||||
	fprintf(stderr, "  -d device to set tunnel device name\n");
 | 
							"topdomain is the FQDN that is delegated to the tunnel endpoint.\n");
 | 
				
			||||||
	fprintf(stderr, "  -z context, to apply specified SELinux context after initialization\n");
 | 
					 | 
				
			||||||
	fprintf(stderr, "  -F pidfile to write pid to a file\n");
 | 
					 | 
				
			||||||
	fprintf(stderr, "nameserver is the IP number/hostname of the relaying nameserver. if absent, /etc/resolv.conf is used\n");
 | 
					 | 
				
			||||||
	fprintf(stderr, "topdomain is the FQDN that is delegated to the tunnel endpoint.\n");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	exit(0);
 | 
						exit(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static inline void usage(void)
 | 
				
			||||||
version() {
 | 
					{
 | 
				
			||||||
 | 
						help(stderr, false);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fprintf(stderr, "iodine IP over DNS tunneling client\n");
 | 
					static void version(void)
 | 
				
			||||||
	fprintf(stderr, "Git version: %s\n", GITREVISION);
 | 
					{
 | 
				
			||||||
 | 
						fprintf(stderr, "iodine IP over DNS tunneling client\n"
 | 
				
			||||||
 | 
								"Git version: %s\n", GITREVISION);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	exit(0);
 | 
						exit(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
main(int argc, char **argv)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *nameserv_host;
 | 
						char *nameserv_host;
 | 
				
			||||||
	char *topdomain;
 | 
						char *topdomain;
 | 
				
			||||||
| 
						 | 
					@ -204,7 +208,7 @@ main(int argc, char **argv)
 | 
				
			||||||
			foreground = 1;
 | 
								foreground = 1;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 'h':
 | 
							case 'h':
 | 
				
			||||||
			help();
 | 
								help(stdout, true);
 | 
				
			||||||
			/* NOTREACHED */
 | 
								/* NOTREACHED */
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 'r':
 | 
							case 'r':
 | 
				
			||||||
| 
						 | 
					@ -275,7 +279,7 @@ main(int argc, char **argv)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	check_superuser(usage);
 | 
						check_superuser();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	argc -= optind;
 | 
						argc -= optind;
 | 
				
			||||||
	argv += optind;
 | 
						argv += optind;
 | 
				
			||||||
| 
						 | 
					@ -313,7 +317,7 @@ main(int argc, char **argv)
 | 
				
			||||||
		/* NOTREACHED */
 | 
							/* NOTREACHED */
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if(check_topdomain(topdomain, &errormsg)) {
 | 
						if (check_topdomain(topdomain, 0, &errormsg)) {
 | 
				
			||||||
		warnx("Invalid topdomain: %s", errormsg);
 | 
							warnx("Invalid topdomain: %s", errormsg);
 | 
				
			||||||
		usage();
 | 
							usage();
 | 
				
			||||||
		/* NOTREACHED */
 | 
							/* NOTREACHED */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										894
									
								
								src/iodined.c
								
								
								
								
							
							
						
						
									
										894
									
								
								src/iodined.c
								
								
								
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,7 @@
 | 
				
			||||||
#include <arpa/inet.h>
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "login.h"
 | 
				
			||||||
#include "md5.h"
 | 
					#include "md5.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/osflags
								
								
								
								
							
							
						
						
									
										14
									
								
								src/osflags
								
								
								
								
							| 
						 | 
					@ -1,5 +1,7 @@
 | 
				
			||||||
#!/bin/sh
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					: "${PKG_CONFIG:=pkg-config}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
case $2 in
 | 
					case $2 in
 | 
				
			||||||
link)
 | 
					link)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,7 +21,8 @@ link)
 | 
				
			||||||
		Linux)
 | 
							Linux)
 | 
				
			||||||
			FLAGS="";
 | 
								FLAGS="";
 | 
				
			||||||
			[ -e /usr/include/selinux/selinux.h ] && FLAGS="$FLAGS -lselinux";
 | 
								[ -e /usr/include/selinux/selinux.h ] && FLAGS="$FLAGS -lselinux";
 | 
				
			||||||
			[ -e /usr/include/systemd/sd-daemon.h ] && FLAGS="$FLAGS -lsystemd-daemon";
 | 
								"$PKG_CONFIG" --exists libsystemd-daemon && FLAGS="$FLAGS $($PKG_CONFIG --libs libsystemd-daemon)";
 | 
				
			||||||
 | 
								"$PKG_CONFIG" --exists libsystemd && FLAGS="$FLAGS $($PKG_CONFIG --libs libsystemd)";
 | 
				
			||||||
			echo $FLAGS;
 | 
								echo $FLAGS;
 | 
				
			||||||
		;;
 | 
							;;
 | 
				
			||||||
	esac
 | 
						esac
 | 
				
			||||||
| 
						 | 
					@ -32,12 +35,19 @@ cflags)
 | 
				
			||||||
		BeOS)
 | 
							BeOS)
 | 
				
			||||||
			echo '-Dsocklen_t=int';
 | 
								echo '-Dsocklen_t=int';
 | 
				
			||||||
		;;
 | 
							;;
 | 
				
			||||||
 | 
							Darwin)
 | 
				
			||||||
 | 
								echo '-D__APPLE_USE_RFC_3542';
 | 
				
			||||||
 | 
							;;
 | 
				
			||||||
		Linux)
 | 
							Linux)
 | 
				
			||||||
			FLAGS="-D_GNU_SOURCE"
 | 
								FLAGS="-D_GNU_SOURCE"
 | 
				
			||||||
			[ -e /usr/include/selinux/selinux.h ] && FLAGS="$FLAGS -DHAVE_SETCON";
 | 
								[ -e /usr/include/selinux/selinux.h ] && FLAGS="$FLAGS -DHAVE_SETCON";
 | 
				
			||||||
			[ -e /usr/include/systemd/sd-daemon.h ] && FLAGS="$FLAGS -DHAVE_SYSTEMD";
 | 
								"$PKG_CONFIG" --exists libsystemd-daemon && FLAGS="$FLAGS -DHAVE_SYSTEMD";
 | 
				
			||||||
 | 
								"$PKG_CONFIG" --exists libsystemd && FLAGS="$FLAGS -DHAVE_SYSTEMD";
 | 
				
			||||||
			echo $FLAGS;
 | 
								echo $FLAGS;
 | 
				
			||||||
		;;
 | 
							;;
 | 
				
			||||||
 | 
							GNU/kFreeBSD|GNU)
 | 
				
			||||||
 | 
								echo '-D_GNU_SOURCE'
 | 
				
			||||||
 | 
							;;
 | 
				
			||||||
	esac
 | 
						esac
 | 
				
			||||||
;;
 | 
					;;
 | 
				
			||||||
*)
 | 
					*)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										10
									
								
								src/read.c
								
								
								
								
							
							
						
						
									
										10
									
								
								src/read.c
								
								
								
								
							| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -19,6 +19,8 @@
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "read.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
readname_loop(char *packet, int packetlen, char **src, char *dst, size_t length, size_t loop)
 | 
					readname_loop(char *packet, int packetlen, char **src, char *dst, size_t length, size_t loop)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -39,7 +41,7 @@ readname_loop(char *packet, int packetlen, char **src, char *dst, size_t length,
 | 
				
			||||||
		c = *s++;
 | 
							c = *s++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* is this a compressed label? */
 | 
							/* is this a compressed label? */
 | 
				
			||||||
		if((c & 0xc0) == 0xc0) {
 | 
							if ((c & 0xc0) == 0xc0) {
 | 
				
			||||||
			offset = (((s[-1] & 0x3f) << 8) | (s[0] & 0xff));
 | 
								offset = (((s[-1] & 0x3f) << 8) | (s[0] & 0xff));
 | 
				
			||||||
			if (offset > packetlen) {
 | 
								if (offset > packetlen) {
 | 
				
			||||||
				if (len == 0) {
 | 
									if (len == 0) {
 | 
				
			||||||
| 
						 | 
					@ -228,7 +230,7 @@ putlong(char **dst, uint32_t value)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
putdata(char **dst, char *data, size_t len)
 | 
					putdata(char **dst, const char *data, size_t len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	memcpy(*dst, data, len);
 | 
						memcpy(*dst, data, len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -237,7 +239,7 @@ putdata(char **dst, char *data, size_t len)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
puttxtbin(char **buf, size_t bufremain, char *from, size_t fromremain)
 | 
					puttxtbin(char **buf, size_t bufremain, const char *from, size_t fromremain)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned char uc;
 | 
						unsigned char uc;
 | 
				
			||||||
	unsigned char *ucp = &uc;
 | 
						unsigned char *ucp = &uc;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,7 @@ int putname(char **, size_t, const char *);
 | 
				
			||||||
int putbyte(char **, unsigned char);
 | 
					int putbyte(char **, unsigned char);
 | 
				
			||||||
int putshort(char **, unsigned short);
 | 
					int putshort(char **, unsigned short);
 | 
				
			||||||
int putlong(char **, uint32_t);
 | 
					int putlong(char **, uint32_t);
 | 
				
			||||||
int putdata(char **, char *, size_t);
 | 
					int putdata(char **, const char *, size_t);
 | 
				
			||||||
int puttxtbin(char **, size_t, char *, size_t);
 | 
					int puttxtbin(char **, size_t, const char *, size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										180
									
								
								src/tun.c
								
								
								
								
							
							
						
						
									
										180
									
								
								src/tun.c
								
								
								
								
							| 
						 | 
					@ -1,8 +1,9 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 | 
					 * 2013 Peter Sagerson <psagers.github@ignorare.net>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -25,10 +26,23 @@
 | 
				
			||||||
#include <sys/stat.h>
 | 
					#include <sys/stat.h>
 | 
				
			||||||
#include <fcntl.h>
 | 
					#include <fcntl.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DARWIN
 | 
				
			||||||
 | 
					#include <ctype.h>
 | 
				
			||||||
 | 
					#include <sys/kern_control.h>
 | 
				
			||||||
 | 
					#include <sys/sys_domain.h>
 | 
				
			||||||
 | 
					#include <sys/ioctl.h>
 | 
				
			||||||
 | 
					#include <net/if_utun.h>
 | 
				
			||||||
 | 
					#include <netinet/ip.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef IFCONFIGPATH
 | 
					#ifndef IFCONFIGPATH
 | 
				
			||||||
#define IFCONFIGPATH "PATH=/sbin:/bin "
 | 
					#define IFCONFIGPATH "PATH=/sbin:/bin "
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef ROUTEPATH
 | 
				
			||||||
 | 
					#define ROUTEPATH "PATH=/sbin:/bin "
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef WINDOWS32
 | 
					#ifdef WINDOWS32
 | 
				
			||||||
#include "windows.h"
 | 
					#include "windows.h"
 | 
				
			||||||
#include <winioctl.h>
 | 
					#include <winioctl.h>
 | 
				
			||||||
| 
						 | 
					@ -47,6 +61,7 @@ static void get_name(char *ifname, int namelen, char *dev_name);
 | 
				
			||||||
#define TAP_DEVICE_SPACE "\\\\.\\Global\\"
 | 
					#define TAP_DEVICE_SPACE "\\\\.\\Global\\"
 | 
				
			||||||
#define TAP_VERSION_ID_0801 "tap0801"
 | 
					#define TAP_VERSION_ID_0801 "tap0801"
 | 
				
			||||||
#define TAP_VERSION_ID_0901 "tap0901"
 | 
					#define TAP_VERSION_ID_0901 "tap0901"
 | 
				
			||||||
 | 
					#define TAP_VERSION_ID_0901_ROOT "root\\tap0901"
 | 
				
			||||||
#define KEY_COMPONENT_ID "ComponentId"
 | 
					#define KEY_COMPONENT_ID "ComponentId"
 | 
				
			||||||
#define NET_CFG_INST_ID "NetCfgInstanceId"
 | 
					#define NET_CFG_INST_ID "NetCfgInstanceId"
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
| 
						 | 
					@ -81,7 +96,7 @@ open_tun(const char *tun_device)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((tun_fd = open(tunnel, O_RDWR)) < 0) {
 | 
						if ((tun_fd = open(tunnel, O_RDWR)) < 0) {
 | 
				
			||||||
		warn("open_tun: %s: %s", tunnel, strerror(errno));
 | 
							warn("open_tun: %s", tunnel);
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -102,7 +117,7 @@ open_tun(const char *tun_device)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (errno != EBUSY) {
 | 
							if (errno != EBUSY) {
 | 
				
			||||||
			warn("open_tun: ioctl[TUNSETIFF]: %s", strerror(errno));
 | 
								warn("open_tun: ioctl[TUNSETIFF]");
 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
| 
						 | 
					@ -117,7 +132,7 @@ open_tun(const char *tun_device)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (errno != EBUSY) {
 | 
								if (errno != EBUSY) {
 | 
				
			||||||
				warn("open_tun: ioctl[TUNSETIFF]: %s", strerror(errno));
 | 
									warn("open_tun: ioctl[TUNSETIFF]");
 | 
				
			||||||
				return -1;
 | 
									return -1;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -141,7 +156,7 @@ get_device(char *device, int device_len, const char *wanted_dev)
 | 
				
			||||||
	status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TAP_ADAPTER_KEY, 0, KEY_READ, &adapter_key);
 | 
						status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TAP_ADAPTER_KEY, 0, KEY_READ, &adapter_key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (status != ERROR_SUCCESS) {
 | 
						if (status != ERROR_SUCCESS) {
 | 
				
			||||||
		warnx("Error opening registry key " TAP_ADAPTER_KEY );
 | 
							warnx("Error opening registry key " TAP_ADAPTER_KEY);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -161,7 +176,7 @@ get_device(char *device, int device_len, const char *wanted_dev)
 | 
				
			||||||
		if (status == ERROR_NO_MORE_ITEMS) {
 | 
							if (status == ERROR_NO_MORE_ITEMS) {
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		} else if (status != ERROR_SUCCESS) {
 | 
							} else if (status != ERROR_SUCCESS) {
 | 
				
			||||||
			warnx("Error enumerating subkeys of registry key " TAP_ADAPTER_KEY );
 | 
								warnx("Error enumerating subkeys of registry key " TAP_ADAPTER_KEY);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -179,7 +194,8 @@ get_device(char *device, int device_len, const char *wanted_dev)
 | 
				
			||||||
			goto next;
 | 
								goto next;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (strncmp(TAP_VERSION_ID_0801, component, strlen(TAP_VERSION_ID_0801)) == 0 ||
 | 
							if (strncmp(TAP_VERSION_ID_0801, component, strlen(TAP_VERSION_ID_0801)) == 0 ||
 | 
				
			||||||
			strncmp(TAP_VERSION_ID_0901, component, strlen(TAP_VERSION_ID_0901)) == 0) {
 | 
								strncmp(TAP_VERSION_ID_0901, component, strlen(TAP_VERSION_ID_0901)) == 0 ||
 | 
				
			||||||
 | 
								strncmp(TAP_VERSION_ID_0901_ROOT, component, strlen(TAP_VERSION_ID_0901_ROOT)) == 0) {
 | 
				
			||||||
			/* We found a TAP32 device, get its NetCfgInstanceId */
 | 
								/* We found a TAP32 device, get its NetCfgInstanceId */
 | 
				
			||||||
			char iid_string[256] = NET_CFG_INST_ID;
 | 
								char iid_string[256] = NET_CFG_INST_ID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -315,6 +331,95 @@ open_tun(const char *tun_device)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else /* BSD and friends */
 | 
					#else /* BSD and friends */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DARWIN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Extract the device number from the name, if given. The value returned will
 | 
				
			||||||
 | 
					 * be suitable for sockaddr_ctl.sc_unit, which means 0 for auto-assign, or
 | 
				
			||||||
 | 
					 * (n + 1) for manual.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					utun_unit(const char *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const char *unit_str = dev;
 | 
				
			||||||
 | 
						int unit = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!dev)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (*unit_str != '\0' && !isdigit(*unit_str))
 | 
				
			||||||
 | 
							unit_str++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (isdigit(*unit_str))
 | 
				
			||||||
 | 
							unit = strtol(unit_str, NULL, 10) + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return unit;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					open_utun(const char *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sockaddr_ctl addr;
 | 
				
			||||||
 | 
						struct ctl_info info;
 | 
				
			||||||
 | 
						char ifname[10];
 | 
				
			||||||
 | 
						socklen_t ifname_len = sizeof(ifname);
 | 
				
			||||||
 | 
						int unit;
 | 
				
			||||||
 | 
						int fd = -1;
 | 
				
			||||||
 | 
						int err = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
 | 
				
			||||||
 | 
						if (fd < 0) {
 | 
				
			||||||
 | 
							warn("open_utun: socket(PF_SYSTEM)");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Look up the kernel controller ID for utun devices. */
 | 
				
			||||||
 | 
						bzero(&info, sizeof(info));
 | 
				
			||||||
 | 
						strncpy(info.ctl_name, UTUN_CONTROL_NAME, MAX_KCTL_NAME);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = ioctl(fd, CTLIOCGINFO, &info);
 | 
				
			||||||
 | 
						if (err != 0) {
 | 
				
			||||||
 | 
							warn("open_utun: ioctl(CTLIOCGINFO)");
 | 
				
			||||||
 | 
							close(fd);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Connecting to the socket creates the utun device. */
 | 
				
			||||||
 | 
						addr.sc_len = sizeof(addr);
 | 
				
			||||||
 | 
						addr.sc_family = AF_SYSTEM;
 | 
				
			||||||
 | 
						addr.ss_sysaddr = AF_SYS_CONTROL;
 | 
				
			||||||
 | 
						addr.sc_id = info.ctl_id;
 | 
				
			||||||
 | 
						unit = utun_unit(dev);
 | 
				
			||||||
 | 
						if (unit < 0) {
 | 
				
			||||||
 | 
							close(fd);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						addr.sc_unit = unit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
 | 
				
			||||||
 | 
						if (err != 0) {
 | 
				
			||||||
 | 
							warn("open_utun: connect");
 | 
				
			||||||
 | 
							close(fd);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Retrieve the assigned interface name. */
 | 
				
			||||||
 | 
						err = getsockopt(fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, ifname, &ifname_len);
 | 
				
			||||||
 | 
						if (err != 0) {
 | 
				
			||||||
 | 
							warn("open_utun: getsockopt(UTUN_OPT_IFNAME)");
 | 
				
			||||||
 | 
							close(fd);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						strncpy(if_name, ifname, sizeof(if_name));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fprintf(stderr, "Opened %s\n", ifname);
 | 
				
			||||||
 | 
						fd_set_close_on_exec(fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return fd;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
open_tun(const char *tun_device)
 | 
					open_tun(const char *tun_device)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -323,12 +428,21 @@ open_tun(const char *tun_device)
 | 
				
			||||||
	char tun_name[50];
 | 
						char tun_name[50];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (tun_device != NULL) {
 | 
						if (tun_device != NULL) {
 | 
				
			||||||
 | 
					#ifdef DARWIN
 | 
				
			||||||
 | 
							if (!strncmp(tun_device, "utun", 4)) {
 | 
				
			||||||
 | 
								tun_fd = open_utun(tun_device);
 | 
				
			||||||
 | 
								if (tun_fd >= 0) {
 | 
				
			||||||
 | 
									return tun_fd;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		snprintf(tun_name, sizeof(tun_name), "/dev/%s", tun_device);
 | 
							snprintf(tun_name, sizeof(tun_name), "/dev/%s", tun_device);
 | 
				
			||||||
		strncpy(if_name, tun_device, sizeof(if_name));
 | 
							strncpy(if_name, tun_device, sizeof(if_name));
 | 
				
			||||||
		if_name[sizeof(if_name)-1] = '\0';
 | 
							if_name[sizeof(if_name)-1] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ((tun_fd = open(tun_name, O_RDWR)) < 0) {
 | 
							if ((tun_fd = open(tun_name, O_RDWR)) < 0) {
 | 
				
			||||||
			warn("open_tun: %s: %s", tun_name, strerror(errno));
 | 
								warn("open_tun: %s", tun_name);
 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -350,6 +464,17 @@ open_tun(const char *tun_device)
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DARWIN
 | 
				
			||||||
 | 
							fprintf(stderr, "No tun devices found, trying utun\n");
 | 
				
			||||||
 | 
							for (i = 0; i < TUN_MAX_TRY; i++) {
 | 
				
			||||||
 | 
								snprintf(tun_name, sizeof(tun_name), "utun%d", i);
 | 
				
			||||||
 | 
								tun_fd = open_utun(tun_name);
 | 
				
			||||||
 | 
								if (tun_fd >= 0) {
 | 
				
			||||||
 | 
									return tun_fd;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		warn("open_tun: Failed to open tunneling device");
 | 
							warn("open_tun: Failed to open tunneling device");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -404,25 +529,43 @@ read_tun(int tun_fd, char *buf, size_t len)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					tun_uses_header(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined (FREEBSD) || defined (NETBSD)
 | 
				
			||||||
 | 
						/* FreeBSD/NetBSD has no header */
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					#elif defined (DARWIN)
 | 
				
			||||||
 | 
						/* Darwin tun has no header, Darwin utun does */
 | 
				
			||||||
 | 
						return !strncmp(if_name, "utun", 4);
 | 
				
			||||||
 | 
					#else  /* LINUX/OPENBSD */
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
write_tun(int tun_fd, char *data, size_t len)
 | 
					write_tun(int tun_fd, char *data, size_t len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#if defined (FREEBSD) || defined (DARWIN) || defined(NETBSD)
 | 
						if (!tun_uses_header()) {
 | 
				
			||||||
		data += 4;
 | 
							data += 4;
 | 
				
			||||||
		len -= 4;
 | 
							len -= 4;
 | 
				
			||||||
#else /* !FREEBSD/DARWIN */
 | 
						} else {
 | 
				
			||||||
#ifdef LINUX
 | 
					#ifdef LINUX
 | 
				
			||||||
 | 
							// Linux prefixes with 32 bits ethertype
 | 
				
			||||||
 | 
							// 0x0800 for IPv4, 0x86DD for IPv6
 | 
				
			||||||
		data[0] = 0x00;
 | 
							data[0] = 0x00;
 | 
				
			||||||
		data[1] = 0x00;
 | 
							data[1] = 0x00;
 | 
				
			||||||
		data[2] = 0x08;
 | 
							data[2] = 0x08;
 | 
				
			||||||
		data[3] = 0x00;
 | 
							data[3] = 0x00;
 | 
				
			||||||
#else /* OPENBSD */
 | 
					#else /* OPENBSD and DARWIN(utun) */
 | 
				
			||||||
 | 
							// BSDs prefix with 32 bits address family
 | 
				
			||||||
 | 
							// AF_INET for IPv4, AF_INET6 for IPv6
 | 
				
			||||||
		data[0] = 0x00;
 | 
							data[0] = 0x00;
 | 
				
			||||||
		data[1] = 0x00;
 | 
							data[1] = 0x00;
 | 
				
			||||||
		data[2] = 0x00;
 | 
							data[2] = 0x00;
 | 
				
			||||||
		data[3] = 0x02;
 | 
							data[3] = 0x02;
 | 
				
			||||||
#endif /* !LINUX */
 | 
					#endif
 | 
				
			||||||
#endif /* FREEBSD */
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (write(tun_fd, data, len) != len) {
 | 
						if (write(tun_fd, data, len) != len) {
 | 
				
			||||||
		warn("write_tun");
 | 
							warn("write_tun");
 | 
				
			||||||
| 
						 | 
					@ -434,8 +577,7 @@ write_tun(int tun_fd, char *data, size_t len)
 | 
				
			||||||
ssize_t
 | 
					ssize_t
 | 
				
			||||||
read_tun(int tun_fd, char *buf, size_t len)
 | 
					read_tun(int tun_fd, char *buf, size_t len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#if defined (FREEBSD) || defined (DARWIN) || defined(NETBSD)
 | 
						if (!tun_uses_header()) {
 | 
				
			||||||
	/* FreeBSD/Darwin/NetBSD has no header */
 | 
					 | 
				
			||||||
		int bytes;
 | 
							int bytes;
 | 
				
			||||||
		memset(buf, 0, 4);
 | 
							memset(buf, 0, 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -445,9 +587,9 @@ read_tun(int tun_fd, char *buf, size_t len)
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			return bytes + 4;
 | 
								return bytes + 4;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
#else /* !FREEBSD */
 | 
						} else {
 | 
				
			||||||
		return read(tun_fd, buf, len);
 | 
							return read(tun_fd, buf, len);
 | 
				
			||||||
#endif /* !FREEBSD */
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -502,12 +644,12 @@ tun_setip(const char *ip, const char *other_ip, int netbits)
 | 
				
			||||||
	netip.s_addr = inet_addr(ip);
 | 
						netip.s_addr = inet_addr(ip);
 | 
				
			||||||
	netip.s_addr = netip.s_addr & net.s_addr;
 | 
						netip.s_addr = netip.s_addr & net.s_addr;
 | 
				
			||||||
	r = system(cmdline);
 | 
						r = system(cmdline);
 | 
				
			||||||
	if(r != 0) {
 | 
						if (r != 0) {
 | 
				
			||||||
		return r;
 | 
							return r;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		snprintf(cmdline, sizeof(cmdline),
 | 
							snprintf(cmdline, sizeof(cmdline),
 | 
				
			||||||
				"/sbin/route add %s/%d %s",
 | 
									ROUTEPATH "route add %s/%d %s",
 | 
				
			||||||
				inet_ntoa(netip), netbits, ip);
 | 
									inet_ntoa(netip), netbits, ip);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	fprintf(stderr, "Adding route %s/%d to %s\n", inet_ntoa(netip), netbits, ip);
 | 
						fprintf(stderr, "Adding route %s/%d to %s\n", inet_ntoa(netip), netbits, ip);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										47
									
								
								src/user.c
								
								
								
								
							
							
						
						
									
										47
									
								
								src/user.c
								
								
								
								
							| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -37,12 +37,11 @@
 | 
				
			||||||
struct tun_user *users;
 | 
					struct tun_user *users;
 | 
				
			||||||
unsigned usercount;
 | 
					unsigned usercount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int init_users(in_addr_t my_ip, int netbits)
 | 
				
			||||||
init_users(in_addr_t my_ip, int netbits)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	int skip = 0;
 | 
						int skip = 0;
 | 
				
			||||||
	char newip[16];
 | 
						char newip[32];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int maxusers;
 | 
						int maxusers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -77,6 +76,7 @@ init_users(in_addr_t my_ip, int netbits)
 | 
				
			||||||
		users[i].disabled = 0;
 | 
							users[i].disabled = 0;
 | 
				
			||||||
		users[i].authenticated = 0;
 | 
							users[i].authenticated = 0;
 | 
				
			||||||
		users[i].authenticated_raw = 0;
 | 
							users[i].authenticated_raw = 0;
 | 
				
			||||||
 | 
							users[i].options_locked = 0;
 | 
				
			||||||
		users[i].active = 0;
 | 
							users[i].active = 0;
 | 
				
			||||||
 		/* Rest is reset on login ('V' packet) */
 | 
					 		/* Rest is reset on login ('V' packet) */
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -84,34 +84,14 @@ init_users(in_addr_t my_ip, int netbits)
 | 
				
			||||||
	return usercount;
 | 
						return usercount;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char*
 | 
					const char *users_get_first_ip(void)
 | 
				
			||||||
users_get_first_ip()
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct in_addr ip;
 | 
						struct in_addr ip;
 | 
				
			||||||
	ip.s_addr = users[0].tun_ip;
 | 
						ip.s_addr = users[0].tun_ip;
 | 
				
			||||||
	return strdup(inet_ntoa(ip));
 | 
						return strdup(inet_ntoa(ip));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int find_user_by_ip(uint32_t ip)
 | 
				
			||||||
users_waiting_on_reply()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int ret;
 | 
					 | 
				
			||||||
	int i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret = 0;
 | 
					 | 
				
			||||||
	for (i = 0; i < usercount; i++) {
 | 
					 | 
				
			||||||
		if (users[i].active && !users[i].disabled &&
 | 
					 | 
				
			||||||
			users[i].last_pkt + 60 > time(NULL) &&
 | 
					 | 
				
			||||||
			users[i].q.id != 0 && users[i].conn == CONN_DNS_NULL) {
 | 
					 | 
				
			||||||
			ret++;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ret;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int
 | 
					 | 
				
			||||||
find_user_by_ip(uint32_t ip)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
| 
						 | 
					@ -130,13 +110,12 @@ find_user_by_ip(uint32_t ip)
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					 | 
				
			||||||
all_users_waiting_to_send()
 | 
					 | 
				
			||||||
/* If this returns true, then reading from tun device is blocked.
 | 
					/* If this returns true, then reading from tun device is blocked.
 | 
				
			||||||
   So only return true when all clients have at least one packet in
 | 
					   So only return true when all clients have at least one packet in
 | 
				
			||||||
   the outpacket-queue, so that sending back-to-back is possible
 | 
					   the outpacket-queue, so that sending back-to-back is possible
 | 
				
			||||||
   without going through another select loop.
 | 
					   without going through another select loop.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					int all_users_waiting_to_send(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	time_t now;
 | 
						time_t now;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
| 
						 | 
					@ -163,8 +142,7 @@ all_users_waiting_to_send()
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int find_available_user(void)
 | 
				
			||||||
find_available_user()
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ret = -1;
 | 
						int ret = -1;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
| 
						 | 
					@ -174,6 +152,7 @@ find_available_user()
 | 
				
			||||||
			users[i].active = 1;
 | 
								users[i].active = 1;
 | 
				
			||||||
			users[i].authenticated = 0;
 | 
								users[i].authenticated = 0;
 | 
				
			||||||
			users[i].authenticated_raw = 0;
 | 
								users[i].authenticated_raw = 0;
 | 
				
			||||||
 | 
								users[i].options_locked = 0;
 | 
				
			||||||
			users[i].last_pkt = time(NULL);
 | 
								users[i].last_pkt = time(NULL);
 | 
				
			||||||
			users[i].fragsize = 4096;
 | 
								users[i].fragsize = 4096;
 | 
				
			||||||
			users[i].conn = CONN_DNS_NULL;
 | 
								users[i].conn = CONN_DNS_NULL;
 | 
				
			||||||
| 
						 | 
					@ -184,8 +163,7 @@ find_available_user()
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void user_switch_codec(int userid, const struct encoder *enc)
 | 
				
			||||||
user_switch_codec(int userid, struct encoder *enc)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (userid < 0 || userid >= usercount)
 | 
						if (userid < 0 || userid >= usercount)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -193,13 +171,12 @@ user_switch_codec(int userid, struct encoder *enc)
 | 
				
			||||||
	users[userid].encoder = enc;
 | 
						users[userid].encoder = enc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void user_set_conn_type(int userid, enum connection c)
 | 
				
			||||||
user_set_conn_type(int userid, enum connection c)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (userid < 0 || userid >= usercount)
 | 
						if (userid < 0 || userid >= usercount)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (c < 0 || c >= CONN_MAX)
 | 
						if (c < CONN_RAW_UDP || c >= CONN_MAX)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	users[userid].conn = c;
 | 
						users[userid].conn = c;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										17
									
								
								src/user.h
								
								
								
								
							
							
						
						
									
										17
									
								
								src/user.h
								
								
								
								
							| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -39,18 +39,20 @@ struct tun_user {
 | 
				
			||||||
	int active;
 | 
						int active;
 | 
				
			||||||
	int authenticated;
 | 
						int authenticated;
 | 
				
			||||||
	int authenticated_raw;
 | 
						int authenticated_raw;
 | 
				
			||||||
 | 
						int options_locked;
 | 
				
			||||||
	int disabled;
 | 
						int disabled;
 | 
				
			||||||
	time_t last_pkt;
 | 
						time_t last_pkt;
 | 
				
			||||||
	int seed;
 | 
						int seed;
 | 
				
			||||||
	in_addr_t tun_ip;
 | 
						in_addr_t tun_ip;
 | 
				
			||||||
	struct in_addr host;
 | 
						struct sockaddr_storage host;
 | 
				
			||||||
 | 
						socklen_t hostlen;
 | 
				
			||||||
	struct query q;
 | 
						struct query q;
 | 
				
			||||||
	struct query q_sendrealsoon;
 | 
						struct query q_sendrealsoon;
 | 
				
			||||||
	int q_sendrealsoon_new;
 | 
						int q_sendrealsoon_new;
 | 
				
			||||||
	struct packet inpacket;
 | 
						struct packet inpacket;
 | 
				
			||||||
	struct packet outpacket;
 | 
						struct packet outpacket;
 | 
				
			||||||
	int outfragresent;
 | 
						int outfragresent;
 | 
				
			||||||
	struct encoder *encoder;
 | 
						const struct encoder *encoder;
 | 
				
			||||||
	char downenc;
 | 
						char downenc;
 | 
				
			||||||
	int out_acked_seqno;
 | 
						int out_acked_seqno;
 | 
				
			||||||
	int out_acked_fragment;
 | 
						int out_acked_fragment;
 | 
				
			||||||
| 
						 | 
					@ -79,12 +81,11 @@ struct tun_user {
 | 
				
			||||||
extern struct tun_user *users;
 | 
					extern struct tun_user *users;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int init_users(in_addr_t, int);
 | 
					int init_users(in_addr_t, int);
 | 
				
			||||||
const char* users_get_first_ip();
 | 
					const char* users_get_first_ip(void);
 | 
				
			||||||
int users_waiting_on_reply();
 | 
					 | 
				
			||||||
int find_user_by_ip(uint32_t);
 | 
					int find_user_by_ip(uint32_t);
 | 
				
			||||||
int all_users_waiting_to_send();
 | 
					int all_users_waiting_to_send(void);
 | 
				
			||||||
int find_available_user();
 | 
					int find_available_user(void);
 | 
				
			||||||
void user_switch_codec(int userid, struct encoder *enc);
 | 
					void user_switch_codec(int userid, const struct encoder *enc);
 | 
				
			||||||
void user_set_conn_type(int userid, enum connection c);
 | 
					void user_set_conn_type(int userid, enum connection c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										12
									
								
								src/util.c
								
								
								
								
							
							
						
						
									
										12
									
								
								src/util.c
								
								
								
								
							| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -17,12 +17,12 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include "common.h"
 | 
					#include "common.h"
 | 
				
			||||||
 | 
					#include "util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *
 | 
					char *get_resolvconf_addr(void)
 | 
				
			||||||
get_resolvconf_addr()
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char addr[16];
 | 
						static char addr[16];
 | 
				
			||||||
	char *rv;
 | 
						char *rv = NULL;
 | 
				
			||||||
#ifndef WINDOWS32
 | 
					#ifndef WINDOWS32
 | 
				
			||||||
	char buf[80];
 | 
						char buf[80];
 | 
				
			||||||
	FILE *fp;
 | 
						FILE *fp;
 | 
				
			||||||
| 
						 | 
					@ -36,9 +36,6 @@ get_resolvconf_addr()
 | 
				
			||||||
		rv = addr;
 | 
							rv = addr;
 | 
				
			||||||
	pclose(fp);
 | 
						pclose(fp);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
 | 
					 | 
				
			||||||
	rv = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((fp = fopen("/etc/resolv.conf", "r")) == NULL)
 | 
						if ((fp = fopen("/etc/resolv.conf", "r")) == NULL)
 | 
				
			||||||
		err(1, "/etc/resolv.conf");
 | 
							err(1, "/etc/resolv.conf");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,7 +55,6 @@ get_resolvconf_addr()
 | 
				
			||||||
	ULONG       buflen;
 | 
						ULONG       buflen;
 | 
				
			||||||
	DWORD       ret;
 | 
						DWORD       ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rv = NULL;
 | 
					 | 
				
			||||||
	fixed_info = malloc(sizeof(FIXED_INFO));
 | 
						fixed_info = malloc(sizeof(FIXED_INFO));
 | 
				
			||||||
	buflen = sizeof(FIXED_INFO);
 | 
						buflen = sizeof(FIXED_INFO);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										19
									
								
								src/util.h
								
								
								
								
							
							
						
						
									
										19
									
								
								src/util.h
								
								
								
								
							| 
						 | 
					@ -1,7 +1,24 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
				
			||||||
 | 
					 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
				
			||||||
 | 
					 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef __UTIL_H__
 | 
					#ifndef __UTIL_H__
 | 
				
			||||||
#define __UTIL_H__
 | 
					#define __UTIL_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *get_resolvconf_addr();
 | 
					char *get_resolvconf_addr(void);
 | 
				
			||||||
void socket_setrtable(int fd, int rtable);
 | 
					void socket_setrtable(int fd, int rtable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -20,7 +20,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* This is the version of the network protocol
 | 
					/* This is the version of the network protocol
 | 
				
			||||||
   It is usually equal to the latest iodine version number */
 | 
					   It is usually equal to the latest iodine version number */
 | 
				
			||||||
#define VERSION 0x00000502
 | 
					#define PROTOCOL_VERSION 0x00000502
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _VERSION_H_ */
 | 
					#endif /* _VERSION_H_ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -73,8 +73,7 @@ typedef struct {
 | 
				
			||||||
	unsigned arcount :16;	/* number of resource entries */
 | 
						unsigned arcount :16;	/* number of resource entries */
 | 
				
			||||||
} HEADER;
 | 
					} HEADER;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ip
 | 
					struct ip {
 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
	unsigned int ip_hl:4;	/* header length */
 | 
						unsigned int ip_hl:4;	/* header length */
 | 
				
			||||||
	unsigned int ip_v:4;	/* version */
 | 
						unsigned int ip_v:4;	/* version */
 | 
				
			||||||
	u_char ip_tos;		/* type of service */
 | 
						u_char ip_tos;		/* type of service */
 | 
				
			||||||
| 
						 | 
					@ -89,7 +88,7 @@ struct ip
 | 
				
			||||||
	u_char ip_p;		/* protocol */
 | 
						u_char ip_p;		/* protocol */
 | 
				
			||||||
	u_short ip_sum;		/* checksum */
 | 
						u_short ip_sum;		/* checksum */
 | 
				
			||||||
	struct in_addr ip_src, ip_dst; /* source and dest address */
 | 
						struct in_addr ip_src, ip_dst; /* source and dest address */
 | 
				
			||||||
  };
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DWORD WINAPI tun_reader(LPVOID arg);
 | 
					DWORD WINAPI tun_reader(LPVOID arg);
 | 
				
			||||||
struct tun_data {
 | 
					struct tun_data {
 | 
				
			||||||
| 
						 | 
					@ -99,4 +98,7 @@ struct tun_data {
 | 
				
			||||||
	int addrlen;
 | 
						int addrlen;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* No-op for now. */
 | 
				
			||||||
 | 
					#define syslog(...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -22,7 +22,6 @@
 | 
				
			||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "encoding.h"
 | 
					#include "encoding.h"
 | 
				
			||||||
#include "base32.h"
 | 
					 | 
				
			||||||
#include "test.h"
 | 
					#include "test.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TUPLES 5
 | 
					#define TUPLES 5
 | 
				
			||||||
| 
						 | 
					@ -43,17 +42,14 @@ START_TEST(test_base32_encode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	size_t len;
 | 
						size_t len;
 | 
				
			||||||
	char buf[4096];
 | 
						char buf[4096];
 | 
				
			||||||
	struct encoder *b32;
 | 
					 | 
				
			||||||
	int val;
 | 
						int val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b32 = get_base32_encoder();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	len = sizeof(buf);
 | 
						len = sizeof(buf);
 | 
				
			||||||
	val = b32->encode(buf, &len, testpairs[_i].a, strlen(testpairs[_i].a));
 | 
						val = base32_ops.encode(buf, &len, testpairs[_i].a, strlen(testpairs[_i].a));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(val == strlen(testpairs[_i].b));
 | 
						ck_assert(val == strlen(testpairs[_i].b));
 | 
				
			||||||
	fail_unless(strcmp(buf, testpairs[_i].b) == 0,
 | 
						ck_assert_str_eq(buf, testpairs[_i].b);
 | 
				
			||||||
			"'%s' != '%s'", buf, testpairs[_i].b);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,17 +57,13 @@ START_TEST(test_base32_decode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	size_t len;
 | 
						size_t len;
 | 
				
			||||||
	char buf[4096];
 | 
						char buf[4096];
 | 
				
			||||||
	struct encoder *b32;
 | 
					 | 
				
			||||||
	int val;
 | 
						int val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b32 = get_base32_encoder();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	len = sizeof(buf);
 | 
						len = sizeof(buf);
 | 
				
			||||||
	val = b32->decode(buf, &len, testpairs[_i].b, strlen(testpairs[_i].b));
 | 
						val = base32_ops.decode(buf, &len, testpairs[_i].b, strlen(testpairs[_i].b));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(val == strlen(testpairs[_i].a));
 | 
						ck_assert(val == strlen(testpairs[_i].a));
 | 
				
			||||||
	fail_unless(strcmp(buf, testpairs[_i].a) == 0,
 | 
						ck_assert_str_eq(buf, testpairs[_i].a);
 | 
				
			||||||
			"'%s' != '%s'", buf, testpairs[_i].a);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,7 +74,7 @@ START_TEST(test_base32_5to8_8to5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < 32; i++) {
 | 
						for (i = 0; i < 32; i++) {
 | 
				
			||||||
		c = b32_5to8(i);
 | 
							c = b32_5to8(i);
 | 
				
			||||||
		fail_unless(b32_8to5(c) == i);
 | 
							ck_assert(b32_8to5(c) == i);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
| 
						 | 
					@ -93,14 +85,11 @@ START_TEST(test_base32_blksize)
 | 
				
			||||||
	size_t enclen;
 | 
						size_t enclen;
 | 
				
			||||||
	char *rawbuf;
 | 
						char *rawbuf;
 | 
				
			||||||
	char *encbuf;
 | 
						char *encbuf;
 | 
				
			||||||
	struct encoder *b32;
 | 
					 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	int val;
 | 
						int val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b32 = get_base32_encoder();
 | 
						rawlen = base32_ops.blocksize_raw;
 | 
				
			||||||
 | 
						enclen = base32_ops.blocksize_encoded;
 | 
				
			||||||
	rawlen = b32->blocksize_raw();
 | 
					 | 
				
			||||||
	enclen = b32->blocksize_encoded();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rawbuf = malloc(rawlen + 16);
 | 
						rawbuf = malloc(rawlen + 16);
 | 
				
			||||||
	encbuf = malloc(enclen + 16);
 | 
						encbuf = malloc(enclen + 16);
 | 
				
			||||||
| 
						 | 
					@ -110,21 +99,21 @@ START_TEST(test_base32_blksize)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	rawbuf[i] = 0;
 | 
						rawbuf[i] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	val = b32->encode(encbuf, &enclen, rawbuf, rawlen);
 | 
						val = base32_ops.encode(encbuf, &enclen, rawbuf, rawlen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(rawlen == 5, "raw length was %d not 5", rawlen);
 | 
						ck_assert_msg(rawlen == 5, "raw length was %zu not 5", rawlen);
 | 
				
			||||||
	fail_unless(enclen == 5, "encoded %d bytes, not 5", enclen);
 | 
						ck_assert_msg(enclen == 5, "encoded %zu bytes, not 5", enclen);
 | 
				
			||||||
	fail_unless(val == 8, "encoded string %s was length %d", encbuf, val);
 | 
						ck_assert_msg(val == 8, "encoded string %s was length %d", encbuf, val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(rawbuf, 0, rawlen + 16);
 | 
						memset(rawbuf, 0, rawlen + 16);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	enclen = val;
 | 
						enclen = val;
 | 
				
			||||||
	val = b32->decode(rawbuf, &rawlen, encbuf, enclen);
 | 
						val = base32_ops.decode(rawbuf, &rawlen, encbuf, enclen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(rawlen == 5, "raw length was %d not 5", rawlen);
 | 
						ck_assert_msg(rawlen == 5, "raw length was %zu not 5", rawlen);
 | 
				
			||||||
	fail_unless(val == 5, "val was not 5 but %d", val);
 | 
						ck_assert_msg(val == 5, "val was not 5 but %d", val);
 | 
				
			||||||
	for (i = 0; i < rawlen; i++) {
 | 
						for (i = 0; i < rawlen; i++) {
 | 
				
			||||||
		fail_unless(rawbuf[i] == 'A');
 | 
							ck_assert(rawbuf[i] == 'A');
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -22,7 +22,6 @@
 | 
				
			||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "encoding.h"
 | 
					#include "encoding.h"
 | 
				
			||||||
#include "base64.h"
 | 
					 | 
				
			||||||
#include "test.h"
 | 
					#include "test.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TUPLES 5
 | 
					#define TUPLES 5
 | 
				
			||||||
| 
						 | 
					@ -69,17 +68,13 @@ START_TEST(test_base64_encode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	size_t len;
 | 
						size_t len;
 | 
				
			||||||
	char buf[4096];
 | 
						char buf[4096];
 | 
				
			||||||
	struct encoder *b64;
 | 
					 | 
				
			||||||
	int val;
 | 
						int val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b64 = get_base64_encoder();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	len = sizeof(buf);
 | 
						len = sizeof(buf);
 | 
				
			||||||
	val = b64->encode(buf, &len, testpairs[_i].a, strlen(testpairs[_i].a));
 | 
						val = base64_ops.encode(buf, &len, testpairs[_i].a, strlen(testpairs[_i].a));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(val == strlen(testpairs[_i].b));
 | 
						ck_assert(val == strlen(testpairs[_i].b));
 | 
				
			||||||
	fail_unless(strcmp(buf, testpairs[_i].b) == 0,
 | 
						ck_assert_str_eq(buf, testpairs[_i].b);
 | 
				
			||||||
			"'%s' != '%s'", buf, testpairs[_i].b);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,17 +82,13 @@ START_TEST(test_base64_decode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	size_t len;
 | 
						size_t len;
 | 
				
			||||||
	char buf[4096];
 | 
						char buf[4096];
 | 
				
			||||||
	struct encoder *b64;
 | 
					 | 
				
			||||||
	int val;
 | 
						int val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b64 = get_base64_encoder();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	len = sizeof(buf);
 | 
						len = sizeof(buf);
 | 
				
			||||||
	val = b64->decode(buf, &len, testpairs[_i].b, strlen(testpairs[_i].b));
 | 
						val = base64_ops.decode(buf, &len, testpairs[_i].b, strlen(testpairs[_i].b));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(val == strlen(testpairs[_i].a));
 | 
						ck_assert(val == strlen(testpairs[_i].a));
 | 
				
			||||||
	fail_unless(strcmp(buf, testpairs[_i].a) == 0,
 | 
						ck_assert_str_eq(buf, testpairs[_i].a);
 | 
				
			||||||
			"'%s' != '%s'", buf, testpairs[_i].a);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,14 +98,11 @@ START_TEST(test_base64_blksize)
 | 
				
			||||||
	size_t enclen;
 | 
						size_t enclen;
 | 
				
			||||||
	char *rawbuf;
 | 
						char *rawbuf;
 | 
				
			||||||
	char *encbuf;
 | 
						char *encbuf;
 | 
				
			||||||
	struct encoder *b64;
 | 
					 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	int val;
 | 
						int val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b64 = get_base64_encoder();
 | 
						rawlen = base64_ops.blocksize_raw;
 | 
				
			||||||
 | 
						enclen = base64_ops.blocksize_encoded;
 | 
				
			||||||
	rawlen = b64->blocksize_raw();
 | 
					 | 
				
			||||||
	enclen = b64->blocksize_encoded();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rawbuf = malloc(rawlen + 16);
 | 
						rawbuf = malloc(rawlen + 16);
 | 
				
			||||||
	encbuf = malloc(enclen + 16);
 | 
						encbuf = malloc(enclen + 16);
 | 
				
			||||||
| 
						 | 
					@ -124,21 +112,21 @@ START_TEST(test_base64_blksize)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	rawbuf[i] = 0;
 | 
						rawbuf[i] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	val = b64->encode(encbuf, &enclen, rawbuf, rawlen);
 | 
						val = base64_ops.encode(encbuf, &enclen, rawbuf, rawlen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(rawlen == 3, "raw length was %d not 3", rawlen);
 | 
						ck_assert_msg(rawlen == 3, "raw length was %zu not 3", rawlen);
 | 
				
			||||||
	fail_unless(enclen == 3, "encoded %d bytes, not 3", enclen);
 | 
						ck_assert_msg(enclen == 3, "encoded %zu bytes, not 3", enclen);
 | 
				
			||||||
	fail_unless(val == 4, "encoded string %s was length %d", encbuf, val);
 | 
						ck_assert_msg(val == 4, "encoded string %s was length %d", encbuf, val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(rawbuf, 0, rawlen + 16);
 | 
						memset(rawbuf, 0, rawlen + 16);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	enclen = val;
 | 
						enclen = val;
 | 
				
			||||||
	val = b64->decode(rawbuf, &rawlen, encbuf, enclen);
 | 
						val = base64_ops.decode(rawbuf, &rawlen, encbuf, enclen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(rawlen == 3, "raw length was %d not 3", rawlen);
 | 
						ck_assert_msg(rawlen == 3, "raw length was %zu not 3", rawlen);
 | 
				
			||||||
	fail_unless(val == 3);
 | 
						ck_assert(val == 3);
 | 
				
			||||||
	for (i = 0; i < rawlen; i++) {
 | 
						for (i = 0; i < rawlen; i++) {
 | 
				
			||||||
		fail_unless(rawbuf[i] == 'A');
 | 
							ck_assert(rawbuf[i] == 'A');
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										224
									
								
								tests/common.c
								
								
								
								
							
							
						
						
									
										224
									
								
								tests/common.c
								
								
								
								
							| 
						 | 
					@ -1,3 +1,20 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
				
			||||||
 | 
					 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
				
			||||||
 | 
					 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <check.h>
 | 
					#include <check.h>
 | 
				
			||||||
#include <common.h>
 | 
					#include <common.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
| 
						 | 
					@ -6,16 +23,20 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
START_TEST(test_topdomain_ok)
 | 
					START_TEST(test_topdomain_ok)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *error;
 | 
						char *error = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_if(check_topdomain("foo.0123456789.qwertyuiop.asdfghjkl.zxcvbnm.com", &error));
 | 
						ck_assert(check_topdomain("foo.0123456789.qwertyuiop.asdfghjkl.zxcvbnm.com", 0, &error) == 0);
 | 
				
			||||||
 | 
						ck_assert(error == NULL);
 | 
				
			||||||
 | 
						/* Allowing wildcard */
 | 
				
			||||||
 | 
						ck_assert(check_topdomain("foo.0123456789.qwertyuiop.asdfghjkl.zxcvbnm.com", 1, &error) == 0);
 | 
				
			||||||
 | 
						ck_assert(error == NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Not allowed to start with dot */
 | 
						/* Not allowed to start with dot */
 | 
				
			||||||
	fail_unless(check_topdomain(".foo.0123456789.qwertyuiop.asdfghjkl.zxcvbnm.com", &error));
 | 
						ck_assert(check_topdomain(".foo.0123456789.qwertyuiop.asdfghjkl.zxcvbnm.com", 0, &error));
 | 
				
			||||||
	fail_if(strcmp("Starts with a dot", error));
 | 
						ck_assert_str_eq("Starts with a dot", error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Test missing error msg ptr */
 | 
						/* Test missing error msg ptr */
 | 
				
			||||||
	fail_unless(check_topdomain(".foo", NULL));
 | 
						ck_assert(check_topdomain(".foo", 0, NULL));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,29 +45,33 @@ START_TEST(test_topdomain_length)
 | 
				
			||||||
	char *error;
 | 
						char *error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Test empty and too short */
 | 
						/* Test empty and too short */
 | 
				
			||||||
	fail_unless(check_topdomain("", &error));
 | 
						ck_assert(check_topdomain("", 0, &error));
 | 
				
			||||||
	fail_if(strcmp("Too short (< 3)", error));
 | 
						ck_assert_str_eq("Too short (< 3)", error);
 | 
				
			||||||
	fail_unless(check_topdomain("a", &error));
 | 
						error = NULL;
 | 
				
			||||||
	fail_if(strcmp("Too short (< 3)", error));
 | 
						ck_assert(check_topdomain("a", 0, &error));
 | 
				
			||||||
	fail_unless(check_topdomain(".a", &error));
 | 
						ck_assert_str_eq("Too short (< 3)", error);
 | 
				
			||||||
	fail_if(strcmp("Too short (< 3)", error));
 | 
						error = NULL;
 | 
				
			||||||
	fail_unless(check_topdomain("a.", &error));
 | 
						ck_assert(check_topdomain(".a", 0, &error));
 | 
				
			||||||
	fail_if(strcmp("Too short (< 3)", error));
 | 
						ck_assert_str_eq("Too short (< 3)", error);
 | 
				
			||||||
	fail_unless(check_topdomain("ab", &error));
 | 
						error = NULL;
 | 
				
			||||||
	fail_if(strcmp("Too short (< 3)", error));
 | 
						ck_assert(check_topdomain("a.", 0, &error));
 | 
				
			||||||
	fail_if(check_topdomain("a.b", &error));
 | 
						ck_assert_str_eq("Too short (< 3)", error);
 | 
				
			||||||
	fail_if(strcmp("Too short (< 3)", error));
 | 
						error = NULL;
 | 
				
			||||||
 | 
						ck_assert(check_topdomain("ab", 0, &error));
 | 
				
			||||||
 | 
						ck_assert_str_eq("Too short (< 3)", error);
 | 
				
			||||||
 | 
						error = NULL;
 | 
				
			||||||
 | 
						ck_assert(check_topdomain("a.b", 0, &error) == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Test too long (over 128, need rest of space for data) */
 | 
						/* Test too long (over 128, need rest of space for data) */
 | 
				
			||||||
	fail_unless(check_topdomain(
 | 
						ck_assert(check_topdomain(
 | 
				
			||||||
		"abcd12345.abcd12345.abcd12345.abcd12345.abcd12345."
 | 
							"abcd12345.abcd12345.abcd12345.abcd12345.abcd12345."
 | 
				
			||||||
		"abcd12345.abcd12345.abcd12345.abcd12345.abcd12345."
 | 
							"abcd12345.abcd12345.abcd12345.abcd12345.abcd12345."
 | 
				
			||||||
		"abcd12345.abcd12345.foo129xxx", &error));
 | 
							"abcd12345.abcd12345.foo129xxx", 0, &error));
 | 
				
			||||||
	fail_if(strcmp("Too long (> 128)", error));
 | 
						ck_assert_str_eq("Too long (> 128)", error);
 | 
				
			||||||
	fail_if(check_topdomain(
 | 
						ck_assert(check_topdomain(
 | 
				
			||||||
		"abcd12345.abcd12345.abcd12345.abcd12345.abcd12345."
 | 
							"abcd12345.abcd12345.abcd12345.abcd12345.abcd12345."
 | 
				
			||||||
		"abcd12345.abcd12345.abcd12345.abcd12345.abcd12345."
 | 
							"abcd12345.abcd12345.abcd12345.abcd12345.abcd12345."
 | 
				
			||||||
		"abcd12345.abcd12345.foo128xx", &error));
 | 
							"abcd12345.abcd12345.foo128xx", 0, &error) == 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,36 +80,112 @@ START_TEST(test_topdomain_chunks)
 | 
				
			||||||
	char *error;
 | 
						char *error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Must have at least one dot */
 | 
						/* Must have at least one dot */
 | 
				
			||||||
	fail_if(check_topdomain("abcde.gh", &error));
 | 
						ck_assert(check_topdomain("abcde.gh", 0, &error) == 0);
 | 
				
			||||||
	fail_unless(check_topdomain("abcdefgh", &error));
 | 
						ck_assert(check_topdomain("abcdefgh", 0, &error));
 | 
				
			||||||
	fail_if(strcmp("No dots", error));
 | 
						ck_assert_str_eq("No dots", error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Not two consecutive dots */
 | 
						/* Not two consecutive dots */
 | 
				
			||||||
	fail_unless(check_topdomain("abc..defgh", &error));
 | 
						ck_assert(check_topdomain("abc..defgh", 0, &error));
 | 
				
			||||||
	fail_if(strcmp("Consecutive dots", error));
 | 
						ck_assert_str_eq("Consecutive dots", error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Not end with a dots */
 | 
						/* Not end with a dots */
 | 
				
			||||||
	fail_unless(check_topdomain("abc.defgh.", &error));
 | 
						ck_assert(check_topdomain("abc.defgh.", 0, &error));
 | 
				
			||||||
	fail_if(strcmp("Ends with a dot", error));
 | 
						ck_assert_str_eq("Ends with a dot", error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* No chunk longer than 63 chars */
 | 
						/* No chunk longer than 63 chars */
 | 
				
			||||||
	fail_if(check_topdomain("123456789012345678901234567890"
 | 
						ck_assert(check_topdomain("123456789012345678901234567890"
 | 
				
			||||||
		"123456789012345678901234567890333.com", &error));
 | 
							"123456789012345678901234567890333.com", 0, &error) == 0);
 | 
				
			||||||
	fail_unless(check_topdomain("123456789012345678901234567890"
 | 
						ck_assert(check_topdomain("123456789012345678901234567890"
 | 
				
			||||||
		"1234567890123456789012345678904444.com", &error));
 | 
							"1234567890123456789012345678904444.com", 0, &error));
 | 
				
			||||||
	fail_if(strcmp("Too long domain part (> 63)", error));
 | 
						ck_assert_str_eq("Too long domain part (> 63)", error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_if(check_topdomain("abc.123456789012345678901234567890"
 | 
						ck_assert(check_topdomain("abc.123456789012345678901234567890"
 | 
				
			||||||
		"123456789012345678901234567890333.com", &error));
 | 
							"123456789012345678901234567890333.com", 0, &error) == 0);
 | 
				
			||||||
	fail_unless(check_topdomain("abc.123456789012345678901234567890"
 | 
						ck_assert(check_topdomain("abc.123456789012345678901234567890"
 | 
				
			||||||
		"1234567890123456789012345678904444.com", &error));
 | 
							"1234567890123456789012345678904444.com", 0, &error));
 | 
				
			||||||
	fail_if(strcmp("Too long domain part (> 63)", error));
 | 
						ck_assert_str_eq("Too long domain part (> 63)", error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_if(check_topdomain("abc.123456789012345678901234567890"
 | 
						ck_assert(check_topdomain("abc.123456789012345678901234567890"
 | 
				
			||||||
		"123456789012345678901234567890333", &error));
 | 
							"123456789012345678901234567890333", 0, &error) == 0);
 | 
				
			||||||
	fail_unless(check_topdomain("abc.123456789012345678901234567890"
 | 
						ck_assert(check_topdomain("abc.123456789012345678901234567890"
 | 
				
			||||||
		"1234567890123456789012345678904444", &error));
 | 
							"1234567890123456789012345678904444", 0, &error));
 | 
				
			||||||
	fail_if(strcmp("Too long domain part (> 63)", error));
 | 
						ck_assert_str_eq("Too long domain part (> 63)", error);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					START_TEST(test_topdomain_wild)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char *error = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ck_assert(check_topdomain("*.a", 0, &error) == 1);
 | 
				
			||||||
 | 
						ck_assert_str_eq("Contains illegal character (allowed: [a-zA-Z0-9-.])", error);
 | 
				
			||||||
 | 
						error = NULL;
 | 
				
			||||||
 | 
						ck_assert(check_topdomain("*.a", 1, &error) == 0);
 | 
				
			||||||
 | 
						ck_assert(error == NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ck_assert(check_topdomain("b*.a", 0, &error) == 1);
 | 
				
			||||||
 | 
						ck_assert_str_eq("Contains illegal character (allowed: [a-zA-Z0-9-.])", error);
 | 
				
			||||||
 | 
						error = NULL;
 | 
				
			||||||
 | 
						ck_assert(check_topdomain("b*.a", 1, &error) == 1);
 | 
				
			||||||
 | 
						ck_assert_str_eq("Wildcard (*) only allowed as first char", error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ck_assert(check_topdomain("*b.a", 0, &error) == 1);
 | 
				
			||||||
 | 
						ck_assert_str_eq("Contains illegal character (allowed: [a-zA-Z0-9-.])", error);
 | 
				
			||||||
 | 
						error = NULL;
 | 
				
			||||||
 | 
						ck_assert(check_topdomain("*b.a", 1, &error) == 1);
 | 
				
			||||||
 | 
						ck_assert_str_eq("Wildcard (*) must be followed by dot", error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ck_assert(check_topdomain("*.*.a", 0, &error) == 1);
 | 
				
			||||||
 | 
						ck_assert_str_eq("Contains illegal character (allowed: [a-zA-Z0-9-.])", error);
 | 
				
			||||||
 | 
						error = NULL;
 | 
				
			||||||
 | 
						ck_assert(check_topdomain("*.*.a", 1, &error) == 1);
 | 
				
			||||||
 | 
						ck_assert_str_eq("Wildcard (*) only allowed as first char", error);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					START_TEST(test_query_datalen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char *topdomain = "r.foo.com";
 | 
				
			||||||
 | 
						/* With data */
 | 
				
			||||||
 | 
						ck_assert(query_datalen("foobar.r.foo.com", topdomain) == 7);
 | 
				
			||||||
 | 
						ck_assert(query_datalen("foobar.r.FoO.Com", topdomain) == 7);
 | 
				
			||||||
 | 
						ck_assert(query_datalen("foo.bar.r.FoO.Com", topdomain) == 8);
 | 
				
			||||||
 | 
						ck_assert(query_datalen(".r.foo.com", topdomain) == 1);
 | 
				
			||||||
 | 
						/* Without data */
 | 
				
			||||||
 | 
						ck_assert(query_datalen("r.foo.com", topdomain) == 0);
 | 
				
			||||||
 | 
						ck_assert(query_datalen("R.foo.com", topdomain) == 0);
 | 
				
			||||||
 | 
						/* Shorter query name */
 | 
				
			||||||
 | 
						ck_assert(query_datalen("foo.com", topdomain) == -1);
 | 
				
			||||||
 | 
						/* Mismatched query name */
 | 
				
			||||||
 | 
						ck_assert(query_datalen("b.foo.com", topdomain) == -1);
 | 
				
			||||||
 | 
						ck_assert(query_datalen("*.foo.com", topdomain) == -1);
 | 
				
			||||||
 | 
						/* Query name overlaps topdomain, but is longer */
 | 
				
			||||||
 | 
						ck_assert(query_datalen("bar.foo.com", topdomain) == -1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					START_TEST(test_query_datalen_wild)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char *topdomain = "*.foo.com";
 | 
				
			||||||
 | 
						/* With data */
 | 
				
			||||||
 | 
						ck_assert(query_datalen("foobar.a.foo.com", topdomain) == 7);
 | 
				
			||||||
 | 
						ck_assert(query_datalen("foobar.r.FoO.Com", topdomain) == 7);
 | 
				
			||||||
 | 
						ck_assert(query_datalen("foo.bar.r.FoO.Com", topdomain) == 8);
 | 
				
			||||||
 | 
						ck_assert(query_datalen("foo.Ab.foo.cOm", topdomain) == 4);
 | 
				
			||||||
 | 
						ck_assert(query_datalen("foo.Abcd.Foo.com", topdomain) == 4);
 | 
				
			||||||
 | 
						ck_assert(query_datalen("***.STARs.foo.com", topdomain) == 4);
 | 
				
			||||||
 | 
						ck_assert(query_datalen(".a.foo.com", topdomain) == 1);
 | 
				
			||||||
 | 
						ck_assert(query_datalen(".ab.foo.com", topdomain) == 1);
 | 
				
			||||||
 | 
						/* Without data */
 | 
				
			||||||
 | 
						ck_assert(query_datalen("rr.foo.com", topdomain) == 0);
 | 
				
			||||||
 | 
						ck_assert(query_datalen("b.foo.com", topdomain) == 0);
 | 
				
			||||||
 | 
						ck_assert(query_datalen("B.foo.com", topdomain) == 0);
 | 
				
			||||||
 | 
						/* Shorter query name */
 | 
				
			||||||
 | 
						ck_assert(query_datalen("foo.com", topdomain) == -1);
 | 
				
			||||||
 | 
						/* Wildcard part of query name matching topdomain */
 | 
				
			||||||
 | 
						ck_assert(query_datalen("aa.*.foo.com", topdomain) == -1);
 | 
				
			||||||
 | 
						/* Mismatched query name */
 | 
				
			||||||
 | 
						ck_assert(query_datalen("bar.r.boo.com", topdomain) == -1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -97,14 +198,14 @@ START_TEST(test_parse_format_ipv4)
 | 
				
			||||||
	int addr_len;
 | 
						int addr_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	addr_len = get_addr(host, 53, AF_INET, 0, &addr);
 | 
						addr_len = get_addr(host, 53, AF_INET, 0, &addr);
 | 
				
			||||||
	fail_unless(addr_len == sizeof(struct sockaddr_in));
 | 
						ck_assert(addr_len == sizeof(struct sockaddr_in));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	v4addr = (struct sockaddr_in *) &addr;
 | 
						v4addr = (struct sockaddr_in *) &addr;
 | 
				
			||||||
	fail_unless(v4addr->sin_addr.s_addr == htonl(0xc0a8020a));
 | 
						ck_assert(v4addr->sin_addr.s_addr == htonl(0xc0a8020a));
 | 
				
			||||||
	fail_unless(v4addr->sin_port == htons(53));
 | 
						ck_assert(v4addr->sin_port == htons(53));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	formatted = format_addr(&addr, addr_len);
 | 
						formatted = format_addr(&addr, addr_len);
 | 
				
			||||||
	fail_if(strcmp(host, formatted));
 | 
						ck_assert_str_eq(host, formatted);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,14 +218,14 @@ START_TEST(test_parse_format_ipv4_listen_all)
 | 
				
			||||||
	int addr_len;
 | 
						int addr_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	addr_len = get_addr(NULL, 53, AF_INET, AI_PASSIVE, &addr);
 | 
						addr_len = get_addr(NULL, 53, AF_INET, AI_PASSIVE, &addr);
 | 
				
			||||||
	fail_unless(addr_len == sizeof(struct sockaddr_in));
 | 
						ck_assert(addr_len == sizeof(struct sockaddr_in));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	v4addr = (struct sockaddr_in *) &addr;
 | 
						v4addr = (struct sockaddr_in *) &addr;
 | 
				
			||||||
	fail_unless(v4addr->sin_addr.s_addr == htonl(0x00000000));
 | 
						ck_assert(v4addr->sin_addr.s_addr == htonl(0x00000000));
 | 
				
			||||||
	fail_unless(v4addr->sin_port == htons(53));
 | 
						ck_assert(v4addr->sin_port == htons(53));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	formatted = format_addr(&addr, addr_len);
 | 
						formatted = format_addr(&addr, addr_len);
 | 
				
			||||||
	fail_if(strcmp(host, formatted));
 | 
						ck_assert_str_eq(host, formatted);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -142,14 +243,14 @@ START_TEST(test_parse_format_ipv6)
 | 
				
			||||||
	int addr_len;
 | 
						int addr_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	addr_len = get_addr(host, 53, AF_UNSPEC, 0, &addr);
 | 
						addr_len = get_addr(host, 53, AF_UNSPEC, 0, &addr);
 | 
				
			||||||
	fail_unless(addr_len == sizeof(struct sockaddr_in6));
 | 
						ck_assert(addr_len == sizeof(struct sockaddr_in6));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	v6addr = (struct sockaddr_in6 *) &addr;
 | 
						v6addr = (struct sockaddr_in6 *) &addr;
 | 
				
			||||||
	fail_if(memcmp(&v6addr->sin6_addr, v6_bits, sizeof(v6_bits)));
 | 
						ck_assert(memcmp(&v6addr->sin6_addr, v6_bits, sizeof(v6_bits)) == 0);
 | 
				
			||||||
	fail_unless(v6addr->sin6_port == htons(53));
 | 
						ck_assert(v6addr->sin6_port == htons(53));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	formatted = format_addr(&addr, addr_len);
 | 
						formatted = format_addr(&addr, addr_len);
 | 
				
			||||||
	fail_if(strcmp(compact, formatted));
 | 
						ck_assert_str_eq(compact, formatted);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -167,15 +268,15 @@ START_TEST(test_parse_format_ipv4_mapped_ipv6)
 | 
				
			||||||
	int addr_len;
 | 
						int addr_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	addr_len = get_addr(v4mapped, 53, AF_INET6, 0, &addr);
 | 
						addr_len = get_addr(v4mapped, 53, AF_INET6, 0, &addr);
 | 
				
			||||||
	fail_unless(addr_len == sizeof(struct sockaddr_in6));
 | 
						ck_assert(addr_len == sizeof(struct sockaddr_in6));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	v6addr = (struct sockaddr_in6 *) &addr;
 | 
						v6addr = (struct sockaddr_in6 *) &addr;
 | 
				
			||||||
	fail_if(memcmp(&v6addr->sin6_addr, v6_bits, sizeof(v6_bits)));
 | 
						ck_assert(memcmp(&v6addr->sin6_addr, v6_bits, sizeof(v6_bits)) == 0);
 | 
				
			||||||
	fail_unless(v6addr->sin6_port == htons(53));
 | 
						ck_assert(v6addr->sin6_port == htons(53));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Format as IPv4 address */
 | 
						/* Format as IPv4 address */
 | 
				
			||||||
	formatted = format_addr(&addr, addr_len);
 | 
						formatted = format_addr(&addr, addr_len);
 | 
				
			||||||
	fail_if(strcmp(host, formatted));
 | 
						ck_assert_str_eq(host, formatted);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -189,6 +290,9 @@ test_common_create_tests()
 | 
				
			||||||
	tcase_add_test(tc, test_topdomain_ok);
 | 
						tcase_add_test(tc, test_topdomain_ok);
 | 
				
			||||||
	tcase_add_test(tc, test_topdomain_length);
 | 
						tcase_add_test(tc, test_topdomain_length);
 | 
				
			||||||
	tcase_add_test(tc, test_topdomain_chunks);
 | 
						tcase_add_test(tc, test_topdomain_chunks);
 | 
				
			||||||
 | 
						tcase_add_test(tc, test_topdomain_wild);
 | 
				
			||||||
 | 
						tcase_add_test(tc, test_query_datalen);
 | 
				
			||||||
 | 
						tcase_add_test(tc, test_query_datalen_wild);
 | 
				
			||||||
	tcase_add_test(tc, test_parse_format_ipv4);
 | 
						tcase_add_test(tc, test_parse_format_ipv4);
 | 
				
			||||||
	tcase_add_test(tc, test_parse_format_ipv4_listen_all);
 | 
						tcase_add_test(tc, test_parse_format_ipv4_listen_all);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										53
									
								
								tests/dns.c
								
								
								
								
							
							
						
						
									
										53
									
								
								tests/dns.c
								
								
								
								
							| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -33,7 +33,6 @@
 | 
				
			||||||
#include "common.h"
 | 
					#include "common.h"
 | 
				
			||||||
#include "dns.h"
 | 
					#include "dns.h"
 | 
				
			||||||
#include "encoding.h"
 | 
					#include "encoding.h"
 | 
				
			||||||
#include "base32.h"
 | 
					 | 
				
			||||||
#include "test.h"
 | 
					#include "test.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void dump_packet(char *, size_t);
 | 
					static void dump_packet(char *, size_t);
 | 
				
			||||||
| 
						 | 
					@ -70,7 +69,7 @@ START_TEST(test_encode_query)
 | 
				
			||||||
	char buf[512];
 | 
						char buf[512];
 | 
				
			||||||
	char resolv[512];
 | 
						char resolv[512];
 | 
				
			||||||
	struct query q;
 | 
						struct query q;
 | 
				
			||||||
	struct encoder *enc;
 | 
						const struct encoder *enc;
 | 
				
			||||||
	char *d;
 | 
						char *d;
 | 
				
			||||||
	size_t len;
 | 
						size_t len;
 | 
				
			||||||
	size_t enclen;
 | 
						size_t enclen;
 | 
				
			||||||
| 
						 | 
					@ -83,7 +82,7 @@ START_TEST(test_encode_query)
 | 
				
			||||||
	q.type = T_NULL;
 | 
						q.type = T_NULL;
 | 
				
			||||||
	q.id = 1337;
 | 
						q.id = 1337;
 | 
				
			||||||
	d = resolv;
 | 
						d = resolv;
 | 
				
			||||||
	enc = get_base32_encoder();
 | 
						enc = &base32_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	*d++ = 'A';
 | 
						*d++ = 'A';
 | 
				
			||||||
	enc->encode(d, &enclen, innerData, strlen(innerData));
 | 
						enc->encode(d, &enclen, innerData, strlen(innerData));
 | 
				
			||||||
| 
						 | 
					@ -101,8 +100,10 @@ START_TEST(test_encode_query)
 | 
				
			||||||
		dump_packet(query_packet, len);
 | 
							dump_packet(query_packet, len);
 | 
				
			||||||
		dump_packet(buf, ret);
 | 
							dump_packet(buf, ret);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	fail_unless(strncmp(query_packet, buf, sizeof(query_packet)) == 0, "Did not compile expected packet");
 | 
						ck_assert_msg(strncmp(query_packet, buf, sizeof(query_packet)) == 0,
 | 
				
			||||||
	fail_unless(ret == len, "Bad packet length: %d, expected %d", ret, len);
 | 
							"Did not compile expected packet");
 | 
				
			||||||
 | 
						ck_assert_msg(ret == len,
 | 
				
			||||||
 | 
							"Bad packet length: %d, expected %zu", ret, len);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -111,22 +112,25 @@ START_TEST(test_decode_query)
 | 
				
			||||||
	char buf[512];
 | 
						char buf[512];
 | 
				
			||||||
	char *domain;
 | 
						char *domain;
 | 
				
			||||||
	struct query q;
 | 
						struct query q;
 | 
				
			||||||
	struct encoder *enc;
 | 
						const struct encoder *enc;
 | 
				
			||||||
	size_t len;
 | 
						size_t len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(&q, 0, sizeof(struct query));
 | 
						memset(&q, 0, sizeof(struct query));
 | 
				
			||||||
	memset(&buf, 0, sizeof(buf));
 | 
						memset(&buf, 0, sizeof(buf));
 | 
				
			||||||
	q.id = 0;
 | 
						q.id = 0;
 | 
				
			||||||
	len = sizeof(query_packet) - 1;
 | 
						len = sizeof(query_packet) - 1;
 | 
				
			||||||
	enc = get_base32_encoder();
 | 
						enc = &base32_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dns_decode(buf, sizeof(buf), &q, QR_QUERY, query_packet, len);
 | 
						dns_decode(buf, sizeof(buf), &q, QR_QUERY, query_packet, len);
 | 
				
			||||||
	domain = strstr(q.name, topdomain);
 | 
						domain = strstr(q.name, topdomain);
 | 
				
			||||||
	len = sizeof(buf);
 | 
						len = sizeof(buf);
 | 
				
			||||||
	unpack_data(buf, len, &(q.name[1]), (int) (domain - q.name) - 1, enc);
 | 
						unpack_data(buf, len, &(q.name[1]), (int) (domain - q.name) - 1, enc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(strncmp(buf, innerData, strlen(innerData)) == 0, "Did not extract expected host: '%s'", buf);
 | 
						ck_assert_msg(strncmp(buf, innerData, strlen(innerData)) == 0,
 | 
				
			||||||
	fail_unless(strlen(buf) == strlen(innerData), "Bad host length: %d, expected %d: '%s'", strlen(buf), strlen(innerData), buf);
 | 
							"Did not extract expected host: '%s'", buf);
 | 
				
			||||||
 | 
						ck_assert_msg(strlen(buf) == strlen(innerData),
 | 
				
			||||||
 | 
							"Bad host length: %zu, expected %zu: '%s'",
 | 
				
			||||||
 | 
							strlen(buf), strlen(innerData), buf);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,8 +152,10 @@ START_TEST(test_encode_response)
 | 
				
			||||||
	ret = dns_encode(buf, len, &q, QR_ANSWER, msgData, strlen(msgData));
 | 
						ret = dns_encode(buf, len, &q, QR_ANSWER, msgData, strlen(msgData));
 | 
				
			||||||
	len = sizeof(answer_packet) - 1; /* Skip extra null character */
 | 
						len = sizeof(answer_packet) - 1; /* Skip extra null character */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(strncmp(answer_packet, buf, sizeof(answer_packet)) == 0, "Did not compile expected packet");
 | 
						ck_assert_msg(strncmp(answer_packet, buf, sizeof(answer_packet)) == 0,
 | 
				
			||||||
	fail_unless(ret == len, "Bad packet length: %d, expected %d", ret, len);
 | 
							"Did not compile expected packet");
 | 
				
			||||||
 | 
						ck_assert_msg(ret == len,
 | 
				
			||||||
 | 
							"Bad packet length: %d, expected %d", ret, len);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -164,9 +170,11 @@ START_TEST(test_decode_response)
 | 
				
			||||||
	memset(&buf, 0, sizeof(buf));
 | 
						memset(&buf, 0, sizeof(buf));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = dns_decode(buf, len, &q, QR_ANSWER, answer_packet, sizeof(answer_packet)-1);
 | 
						ret = dns_decode(buf, len, &q, QR_ANSWER, answer_packet, sizeof(answer_packet)-1);
 | 
				
			||||||
	fail_unless(ret == strlen(msgData), "Bad data length: %d, expected %d", ret, strlen(msgData));
 | 
						ck_assert_msg(ret == strlen(msgData),
 | 
				
			||||||
	fail_unless(strncmp(msgData, buf, strlen(msgData)) == 0, "Did not extract expected data");
 | 
							"Bad data length: %d, expected %zu", ret, strlen(msgData));
 | 
				
			||||||
	fail_unless(q.id == 0x0539);
 | 
						ck_assert_msg(strncmp(msgData, buf, strlen(msgData)) == 0,
 | 
				
			||||||
 | 
							"Did not extract expected data");
 | 
				
			||||||
 | 
						ck_assert(q.id == 0x0539);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -181,9 +189,12 @@ START_TEST(test_decode_response_with_high_trans_id)
 | 
				
			||||||
	memset(&buf, 0, sizeof(buf));
 | 
						memset(&buf, 0, sizeof(buf));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = dns_decode(buf, len, &q, QR_ANSWER, answer_packet_high_trans_id, sizeof(answer_packet_high_trans_id)-1);
 | 
						ret = dns_decode(buf, len, &q, QR_ANSWER, answer_packet_high_trans_id, sizeof(answer_packet_high_trans_id)-1);
 | 
				
			||||||
	fail_unless(ret == strlen(msgData), "Bad data length: %d, expected %d", ret, strlen(msgData));
 | 
						ck_assert_msg(ret == strlen(msgData),
 | 
				
			||||||
	fail_unless(strncmp(msgData, buf, strlen(msgData)) == 0, "Did not extract expected data");
 | 
							"Bad data length: %d, expected %zu", ret, strlen(msgData));
 | 
				
			||||||
	fail_unless(q.id == 0x8539, "q.id was %08X instead of %08X!", q.id, 0x8539);
 | 
						ck_assert_msg(strncmp(msgData, buf, strlen(msgData)) == 0,
 | 
				
			||||||
 | 
							"Did not extract expected data");
 | 
				
			||||||
 | 
						ck_assert_msg(q.id == 0x8539,
 | 
				
			||||||
 | 
							"q.id was %08X instead of %08X!", q.id, 0x8539);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -197,7 +208,7 @@ START_TEST(test_get_id_short_packet)
 | 
				
			||||||
	memset(&buf, 5, sizeof(buf));
 | 
						memset(&buf, 5, sizeof(buf));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	id = dns_get_id(buf, len);
 | 
						id = dns_get_id(buf, len);
 | 
				
			||||||
	fail_unless(id == 0);
 | 
						ck_assert(id == 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -206,7 +217,7 @@ START_TEST(test_get_id_low)
 | 
				
			||||||
	unsigned short id;
 | 
						unsigned short id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	id = dns_get_id(answer_packet, sizeof(answer_packet));
 | 
						id = dns_get_id(answer_packet, sizeof(answer_packet));
 | 
				
			||||||
	fail_unless(id == 1337);
 | 
						ck_assert(id == 1337);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -215,7 +226,7 @@ START_TEST(test_get_id_high)
 | 
				
			||||||
	unsigned short id;
 | 
						unsigned short id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	id = dns_get_id(answer_packet_high_trans_id, sizeof(answer_packet_high_trans_id));
 | 
						id = dns_get_id(answer_packet_high_trans_id, sizeof(answer_packet_high_trans_id));
 | 
				
			||||||
	fail_unless(id == 0x8539);
 | 
						ck_assert(id == 0x8539);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -22,8 +22,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "encoding.h"
 | 
					#include "encoding.h"
 | 
				
			||||||
#include "test.h"
 | 
					#include "test.h"
 | 
				
			||||||
#include "base32.h"
 | 
					 | 
				
			||||||
#include "base64.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TUPLES 4
 | 
					#define TUPLES 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,8 +50,7 @@ START_TEST(test_inline_dotify)
 | 
				
			||||||
	b = temp;
 | 
						b = temp;
 | 
				
			||||||
	inline_dotify(b, sizeof(temp));
 | 
						inline_dotify(b, sizeof(temp));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(strcmp(dottests[_i].b, temp) == 0,
 | 
						ck_assert_str_eq(dottests[_i].b, temp);
 | 
				
			||||||
			"'%s' != '%s'", temp, dottests[_i].b);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,8 +64,7 @@ START_TEST(test_inline_undotify)
 | 
				
			||||||
	b = temp;
 | 
						b = temp;
 | 
				
			||||||
	inline_undotify(b, sizeof(temp));
 | 
						inline_undotify(b, sizeof(temp));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(strcmp(dottests[_i].a, temp) == 0,
 | 
						ck_assert_str_eq(dottests[_i].a, temp);
 | 
				
			||||||
			"'%s' != '%s'", temp, dottests[_i].a);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,10 +83,11 @@ START_TEST(test_build_hostname)
 | 
				
			||||||
	buflen = sizeof(buf);
 | 
						buflen = sizeof(buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 1; i < sizeof(data); i++) {
 | 
						for (i = 1; i < sizeof(data); i++) {
 | 
				
			||||||
		int len = build_hostname(buf, buflen, data, i, topdomain, get_base32_encoder(), sizeof(buf));
 | 
							int len = build_hostname(buf, buflen, data, i, topdomain, &base32_ops, sizeof(buf));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		fail_if(len > i);
 | 
							ck_assert(len <= i);
 | 
				
			||||||
		fail_if(strstr(buf, ".."), "Found double dots when encoding data len %d! buf: %s", i, buf);
 | 
							ck_assert_msg(strstr(buf, "..") == NULL,
 | 
				
			||||||
 | 
								"Found double dots when encoding data len %d! buf: %s", i, buf);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright (c) 2009-2014 Erik Ekman <yarrick@kryo.se>
 | 
					 * Copyright (c) 2009-2014 Erik Ekman <yarrick@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -31,14 +31,14 @@ START_TEST(test_fw_query_simple)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Test empty cache */
 | 
						/* Test empty cache */
 | 
				
			||||||
	fw_query_get(0x848A, &qp);
 | 
						fw_query_get(0x848A, &qp);
 | 
				
			||||||
	fail_unless(qp == NULL);
 | 
						ck_assert(qp == NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fw_query_put(&q);
 | 
						fw_query_put(&q);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Test cache with one entry */
 | 
						/* Test cache with one entry */
 | 
				
			||||||
	fw_query_get(0x848A, &qp);
 | 
						fw_query_get(0x848A, &qp);
 | 
				
			||||||
	fail_unless(qp->addrlen == q.addrlen);
 | 
						ck_assert(qp->addrlen == q.addrlen);
 | 
				
			||||||
	fail_unless(qp->id == q.id);
 | 
						ck_assert(qp->id == q.id);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,8 +62,8 @@ START_TEST(test_fw_query_edge)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* The query should still be cached */
 | 
						/* The query should still be cached */
 | 
				
			||||||
	fw_query_get(0x848A, &qp);
 | 
						fw_query_get(0x848A, &qp);
 | 
				
			||||||
	fail_unless(qp->addrlen == 33);
 | 
						ck_assert(qp->addrlen == 33);
 | 
				
			||||||
	fail_unless(qp->id == 0x848A);
 | 
						ck_assert(qp->id == 0x848A);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	q.addrlen++;
 | 
						q.addrlen++;
 | 
				
			||||||
	q.id++;
 | 
						q.id++;
 | 
				
			||||||
| 
						 | 
					@ -71,7 +71,7 @@ START_TEST(test_fw_query_edge)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* but now it is overwritten */
 | 
						/* but now it is overwritten */
 | 
				
			||||||
	fw_query_get(0x848A, &qp);
 | 
						fw_query_get(0x848A, &qp);
 | 
				
			||||||
	fail_unless(qp == NULL);
 | 
						ck_assert(qp == NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -34,7 +34,7 @@ START_TEST(test_login_hash)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(ans, 0, sizeof(ans));
 | 
						memset(ans, 0, sizeof(ans));
 | 
				
			||||||
	login_calculate(ans, len, pass, seed);
 | 
						login_calculate(ans, len, pass, seed);
 | 
				
			||||||
	fail_unless(strncmp(ans, good, len) == 0, NULL);
 | 
						ck_assert(strncmp(ans, good, len) == 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,7 +54,7 @@ START_TEST(test_login_hash_short)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* If len < 16, it should do nothing */
 | 
						/* If len < 16, it should do nothing */
 | 
				
			||||||
	login_calculate(ans, len, pass, seed);
 | 
						login_calculate(ans, len, pass, seed);
 | 
				
			||||||
	fail_if(memcmp(ans, check, sizeof(ans)));
 | 
						ck_assert(memcmp(ans, check, sizeof(ans)) == 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										45
									
								
								tests/read.c
								
								
								
								
							
							
						
						
									
										45
									
								
								tests/read.c
								
								
								
								
							| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -46,13 +46,13 @@ START_TEST(test_read_putshort)
 | 
				
			||||||
	for (i = 0; i < 65536; i++) {
 | 
						for (i = 0; i < 65536; i++) {
 | 
				
			||||||
		p = (char*)&k;
 | 
							p = (char*)&k;
 | 
				
			||||||
		putshort(&p, i);
 | 
							putshort(&p, i);
 | 
				
			||||||
		fail_unless(ntohs(k) == i,
 | 
							ck_assert_msg(ntohs(k) == i,
 | 
				
			||||||
				"Bad value on putshort for %d: %d != %d",
 | 
									"Bad value on putshort for %d: %d != %d",
 | 
				
			||||||
					i, ntohs(k), i);
 | 
										i, ntohs(k), i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		p = (char*)&k;
 | 
							p = (char*)&k;
 | 
				
			||||||
		readshort(NULL, &p, &l);
 | 
							readshort(NULL, &p, &l);
 | 
				
			||||||
		fail_unless(l == i,
 | 
							ck_assert_msg(l == i,
 | 
				
			||||||
				"Bad value on readshort for %d: %d != %d",
 | 
									"Bad value on readshort for %d: %d != %d",
 | 
				
			||||||
					i, l, i);
 | 
										i, l, i);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -73,13 +73,13 @@ START_TEST(test_read_putlong)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		putlong(&p, j);
 | 
							putlong(&p, j);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		fail_unless(ntohl(k) == j,
 | 
							ck_assert_msg(ntohl(k) == j,
 | 
				
			||||||
				"Bad value on putlong for %d: %d != %d", i, ntohl(j), j);
 | 
									"Bad value on putlong for %d: %d != %d", i, ntohl(j), j);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		p = (char*)&k;
 | 
							p = (char*)&k;
 | 
				
			||||||
		readlong(NULL, &p, &l);
 | 
							readlong(NULL, &p, &l);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		fail_unless(l == j,
 | 
							ck_assert_msg(l == j,
 | 
				
			||||||
				"Bad value on readlong for %d: %d != %d", i, l, j);
 | 
									"Bad value on readlong for %d: %d != %d", i, l, j);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -98,8 +98,8 @@ START_TEST(test_read_name_empty_loop)
 | 
				
			||||||
	data = (char*) emptyloop + sizeof(HEADER);
 | 
						data = (char*) emptyloop + sizeof(HEADER);
 | 
				
			||||||
	buf[1023] = 'A';
 | 
						buf[1023] = 'A';
 | 
				
			||||||
	rv = readname((char *) emptyloop, sizeof(emptyloop), &data, buf, 1023);
 | 
						rv = readname((char *) emptyloop, sizeof(emptyloop), &data, buf, 1023);
 | 
				
			||||||
	fail_unless(rv == 0);
 | 
						ck_assert(rv == 0);
 | 
				
			||||||
	fail_unless(buf[1023] == 'A');
 | 
						ck_assert(buf[1023] == 'A');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -116,8 +116,8 @@ START_TEST(test_read_name_inf_loop)
 | 
				
			||||||
	data = (char*) infloop + sizeof(HEADER);
 | 
						data = (char*) infloop + sizeof(HEADER);
 | 
				
			||||||
	buf[4] = '\a';
 | 
						buf[4] = '\a';
 | 
				
			||||||
	rv = readname((char*) infloop, sizeof(infloop), &data, buf, 4);
 | 
						rv = readname((char*) infloop, sizeof(infloop), &data, buf, 4);
 | 
				
			||||||
	fail_unless(rv == 3);
 | 
						ck_assert(rv == 3);
 | 
				
			||||||
	fail_unless(buf[4] == '\a');
 | 
						ck_assert(buf[4] == '\a');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -140,8 +140,8 @@ START_TEST(test_read_name_longname)
 | 
				
			||||||
	data = (char*) longname + sizeof(HEADER);
 | 
						data = (char*) longname + sizeof(HEADER);
 | 
				
			||||||
	buf[256] = '\a';
 | 
						buf[256] = '\a';
 | 
				
			||||||
	rv = readname((char*) longname, sizeof(longname), &data, buf, 256);
 | 
						rv = readname((char*) longname, sizeof(longname), &data, buf, 256);
 | 
				
			||||||
	fail_unless(rv == 256);
 | 
						ck_assert(rv == 256);
 | 
				
			||||||
	fail_unless(buf[256] == '\a');
 | 
						ck_assert(buf[256] == '\a');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -157,7 +157,7 @@ START_TEST(test_read_name_onejump)
 | 
				
			||||||
	memset(buf, 0, sizeof(buf));
 | 
						memset(buf, 0, sizeof(buf));
 | 
				
			||||||
	data = (char*) onejump + sizeof(HEADER);
 | 
						data = (char*) onejump + sizeof(HEADER);
 | 
				
			||||||
	rv = readname((char*) onejump, sizeof(onejump), &data, buf, 256);
 | 
						rv = readname((char*) onejump, sizeof(onejump), &data, buf, 256);
 | 
				
			||||||
	fail_unless(rv == 9);
 | 
						ck_assert(rv == 9);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -179,8 +179,8 @@ START_TEST(test_read_name_badjump_start)
 | 
				
			||||||
		data = (char*) jumper + sizeof(HEADER);
 | 
							data = (char*) jumper + sizeof(HEADER);
 | 
				
			||||||
		rv = readname((char*) jumper, sizeof(badjump), &data, buf, 256);
 | 
							rv = readname((char*) jumper, sizeof(badjump), &data, buf, 256);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		fail_unless(rv == 0);
 | 
							ck_assert(rv == 0);
 | 
				
			||||||
		fail_unless(buf[0] == 0);
 | 
							ck_assert(buf[0] == 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	free(jumper);
 | 
						free(jumper);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -204,9 +204,8 @@ START_TEST(test_read_name_badjump_second)
 | 
				
			||||||
		data = (char*) jumper + sizeof(HEADER);
 | 
							data = (char*) jumper + sizeof(HEADER);
 | 
				
			||||||
		rv = readname((char*) jumper, sizeof(badjump2), &data, buf, 256);
 | 
							rv = readname((char*) jumper, sizeof(badjump2), &data, buf, 256);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		fail_unless(rv == 4);
 | 
							ck_assert(rv == 4);
 | 
				
			||||||
		fail_unless(strcmp("BA.", buf) == 0,
 | 
							ck_assert_str_eq("BA.", buf);
 | 
				
			||||||
				"buf is not BA: %s", buf);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	free(jumper);
 | 
						free(jumper);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -224,8 +223,8 @@ START_TEST(test_putname)
 | 
				
			||||||
	b = buf;
 | 
						b = buf;
 | 
				
			||||||
	ret = putname(&b, 256, domain);
 | 
						ret = putname(&b, 256, domain);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(ret == strlen(domain) + 1);
 | 
						ck_assert(ret == strlen(domain) + 1);
 | 
				
			||||||
	fail_unless(strncmp(buf, out, ret) == 0, "Happy flow failed");
 | 
						ck_assert_msg(strncmp(buf, out, ret) == 0, "Happy flow failed");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -242,8 +241,8 @@ START_TEST(test_putname_nodot)
 | 
				
			||||||
	b = buf;
 | 
						b = buf;
 | 
				
			||||||
	ret = putname(&b, 256, nodot);
 | 
						ret = putname(&b, 256, nodot);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(ret == -1);
 | 
						ck_assert(ret == -1);
 | 
				
			||||||
	fail_unless(b == buf);
 | 
						ck_assert(b == buf);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -264,8 +263,8 @@ START_TEST(test_putname_toolong)
 | 
				
			||||||
	b = buf;
 | 
						b = buf;
 | 
				
			||||||
	ret = putname(&b, 256, toolong);
 | 
						ret = putname(&b, 256, toolong);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(ret == -1);
 | 
						ck_assert(ret == -1);
 | 
				
			||||||
	fail_unless(b == buf);
 | 
						ck_assert(b == buf);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										83
									
								
								tests/user.c
								
								
								
								
							
							
						
						
									
										83
									
								
								tests/user.c
								
								
								
								
							| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
					 * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
 | 
				
			||||||
 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
					 * 2006-2009 Bjorn Andersson <flex@kryo.se>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -38,40 +38,16 @@ START_TEST(test_init_users)
 | 
				
			||||||
	ip = inet_addr("127.0.0.1");
 | 
						ip = inet_addr("127.0.0.1");
 | 
				
			||||||
	count = init_users(ip, 27);
 | 
						count = init_users(ip, 27);
 | 
				
			||||||
	for (i = 0; i < count; i++) {
 | 
						for (i = 0; i < count; i++) {
 | 
				
			||||||
		fail_unless(users[i].id == i);
 | 
							ck_assert(users[i].id == i);
 | 
				
			||||||
		fail_unless(users[i].q.id == 0);
 | 
							ck_assert(users[i].q.id == 0);
 | 
				
			||||||
		fail_unless(users[i].inpacket.len == 0);
 | 
							ck_assert(users[i].inpacket.len == 0);
 | 
				
			||||||
		fail_unless(users[i].outpacket.len == 0);
 | 
							ck_assert(users[i].outpacket.len == 0);
 | 
				
			||||||
		snprintf(givenip, sizeof(givenip), "127.0.0.%d", i + 2);
 | 
							snprintf(givenip, sizeof(givenip), "127.0.0.%d", i + 2);
 | 
				
			||||||
		fail_unless(users[i].tun_ip == inet_addr(givenip));
 | 
							ck_assert(users[i].tun_ip == inet_addr(givenip));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
START_TEST(test_users_waiting)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	in_addr_t ip;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ip = inet_addr("127.0.0.1");
 | 
					 | 
				
			||||||
	init_users(ip, 27);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fail_unless(users_waiting_on_reply() == 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	users[3].active = 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fail_unless(users_waiting_on_reply() == 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	users[3].last_pkt = time(NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fail_unless(users_waiting_on_reply() == 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	users[3].conn = CONN_DNS_NULL;
 | 
					 | 
				
			||||||
	users[3].q.id = 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fail_unless(users_waiting_on_reply() == 1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
END_TEST
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
START_TEST(test_find_user_by_ip)
 | 
					START_TEST(test_find_user_by_ip)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	in_addr_t ip;
 | 
						in_addr_t ip;
 | 
				
			||||||
| 
						 | 
					@ -82,25 +58,25 @@ START_TEST(test_find_user_by_ip)
 | 
				
			||||||
	users[0].conn = CONN_DNS_NULL;
 | 
						users[0].conn = CONN_DNS_NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testip = (unsigned int) inet_addr("10.0.0.1");
 | 
						testip = (unsigned int) inet_addr("10.0.0.1");
 | 
				
			||||||
	fail_unless(find_user_by_ip(testip) == -1);
 | 
						ck_assert(find_user_by_ip(testip) == -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testip = (unsigned int) inet_addr("127.0.0.2");
 | 
						testip = (unsigned int) inet_addr("127.0.0.2");
 | 
				
			||||||
	fail_unless(find_user_by_ip(testip) == -1);
 | 
						ck_assert(find_user_by_ip(testip) == -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	users[0].active = 1;
 | 
						users[0].active = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testip = (unsigned int) inet_addr("127.0.0.2");
 | 
						testip = (unsigned int) inet_addr("127.0.0.2");
 | 
				
			||||||
	fail_unless(find_user_by_ip(testip) == -1);
 | 
						ck_assert(find_user_by_ip(testip) == -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	users[0].last_pkt = time(NULL);
 | 
						users[0].last_pkt = time(NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testip = (unsigned int) inet_addr("127.0.0.2");
 | 
						testip = (unsigned int) inet_addr("127.0.0.2");
 | 
				
			||||||
	fail_unless(find_user_by_ip(testip) == -1);
 | 
						ck_assert(find_user_by_ip(testip) == -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	users[0].authenticated = 1;
 | 
						users[0].authenticated = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testip = (unsigned int) inet_addr("127.0.0.2");
 | 
						testip = (unsigned int) inet_addr("127.0.0.2");
 | 
				
			||||||
	fail_unless(find_user_by_ip(testip) == 0);
 | 
						ck_assert(find_user_by_ip(testip) == 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -111,17 +87,17 @@ START_TEST(test_all_users_waiting_to_send)
 | 
				
			||||||
	ip = inet_addr("127.0.0.1");
 | 
						ip = inet_addr("127.0.0.1");
 | 
				
			||||||
	init_users(ip, 27);
 | 
						init_users(ip, 27);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(all_users_waiting_to_send() == 1);
 | 
						ck_assert(all_users_waiting_to_send() == 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	users[0].conn = CONN_DNS_NULL;
 | 
						users[0].conn = CONN_DNS_NULL;
 | 
				
			||||||
	users[0].active = 1;
 | 
						users[0].active = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(all_users_waiting_to_send() == 1);
 | 
						ck_assert(all_users_waiting_to_send() == 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	users[0].last_pkt = time(NULL);
 | 
						users[0].last_pkt = time(NULL);
 | 
				
			||||||
	users[0].outpacket.len = 0;
 | 
						users[0].outpacket.len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(all_users_waiting_to_send() == 0);
 | 
						ck_assert(all_users_waiting_to_send() == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef OUTPACKETQ_LEN
 | 
					#ifdef OUTPACKETQ_LEN
 | 
				
			||||||
	users[0].outpacketq_filled = 1;
 | 
						users[0].outpacketq_filled = 1;
 | 
				
			||||||
| 
						 | 
					@ -129,7 +105,7 @@ START_TEST(test_all_users_waiting_to_send)
 | 
				
			||||||
	users[0].outpacket.len = 44;
 | 
						users[0].outpacket.len = 44;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(all_users_waiting_to_send() == 1);
 | 
						ck_assert(all_users_waiting_to_send() == 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -144,24 +120,24 @@ START_TEST(test_find_available_user)
 | 
				
			||||||
	for (i = 0; i < USERS; i++) {
 | 
						for (i = 0; i < USERS; i++) {
 | 
				
			||||||
		users[i].authenticated = 1;
 | 
							users[i].authenticated = 1;
 | 
				
			||||||
		users[i].authenticated_raw = 1;
 | 
							users[i].authenticated_raw = 1;
 | 
				
			||||||
		fail_unless(find_available_user() == i);
 | 
							ck_assert(find_available_user() == i);
 | 
				
			||||||
		fail_if(users[i].authenticated);
 | 
							ck_assert(users[i].authenticated == 0);
 | 
				
			||||||
		fail_if(users[i].authenticated_raw);
 | 
							ck_assert(users[i].authenticated_raw == 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < USERS; i++) {
 | 
						for (i = 0; i < USERS; i++) {
 | 
				
			||||||
		fail_unless(find_available_user() == -1);
 | 
							ck_assert(find_available_user() == -1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	users[3].active = 0;
 | 
						users[3].active = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(find_available_user() == 3);
 | 
						ck_assert(find_available_user() == 3);
 | 
				
			||||||
	fail_unless(find_available_user() == -1);
 | 
						ck_assert(find_available_user() == -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	users[3].last_pkt = 55;
 | 
						users[3].last_pkt = 55;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(find_available_user() == 3);
 | 
						ck_assert(find_available_user() == 3);
 | 
				
			||||||
	fail_unless(find_available_user() == -1);
 | 
						ck_assert(find_available_user() == -1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -174,22 +150,22 @@ START_TEST(test_find_available_user_small_net)
 | 
				
			||||||
	init_users(ip, 29); /* this should result in 5 enabled users */
 | 
						init_users(ip, 29); /* this should result in 5 enabled users */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < 5; i++) {
 | 
						for (i = 0; i < 5; i++) {
 | 
				
			||||||
		fail_unless(find_available_user() == i);
 | 
							ck_assert(find_available_user() == i);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < USERS; i++) {
 | 
						for (i = 0; i < USERS; i++) {
 | 
				
			||||||
		fail_unless(find_available_user() == -1);
 | 
							ck_assert(find_available_user() == -1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	users[3].active = 0;
 | 
						users[3].active = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(find_available_user() == 3);
 | 
						ck_assert(find_available_user() == 3);
 | 
				
			||||||
	fail_unless(find_available_user() == -1);
 | 
						ck_assert(find_available_user() == -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	users[3].last_pkt = 55;
 | 
						users[3].last_pkt = 55;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fail_unless(find_available_user() == 3);
 | 
						ck_assert(find_available_user() == 3);
 | 
				
			||||||
	fail_unless(find_available_user() == -1);
 | 
						ck_assert(find_available_user() == -1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_TEST
 | 
					END_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -200,7 +176,6 @@ test_user_create_tests()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tc = tcase_create("User");
 | 
						tc = tcase_create("User");
 | 
				
			||||||
	tcase_add_test(tc, test_init_users);
 | 
						tcase_add_test(tc, test_init_users);
 | 
				
			||||||
	tcase_add_test(tc, test_users_waiting);
 | 
					 | 
				
			||||||
	tcase_add_test(tc, test_find_user_by_ip);
 | 
						tcase_add_test(tc, test_find_user_by_ip);
 | 
				
			||||||
	tcase_add_test(tc, test_all_users_waiting_to_send);
 | 
						tcase_add_test(tc, test_all_users_waiting_to_send);
 | 
				
			||||||
	tcase_add_test(tc, test_find_available_user);
 | 
						tcase_add_test(tc, test_find_available_user);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue