Migrate to ocproxy-based TCP proxy implementation with VPN integration
This commit is contained in:
parent
0278906574
commit
c767d81251
193
.gitignore
vendored
Normal file
193
.gitignore
vendored
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/c,cmake,clion
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=c,cmake,clion
|
||||||
|
|
||||||
|
### C ###
|
||||||
|
# Prerequisites
|
||||||
|
*.d
|
||||||
|
|
||||||
|
# Object files
|
||||||
|
*.o
|
||||||
|
*.ko
|
||||||
|
*.obj
|
||||||
|
*.elf
|
||||||
|
|
||||||
|
# Linker output
|
||||||
|
*.ilk
|
||||||
|
*.map
|
||||||
|
*.exp
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
*.lib
|
||||||
|
*.a
|
||||||
|
*.la
|
||||||
|
*.lo
|
||||||
|
|
||||||
|
# Shared objects (inc. Windows DLLs)
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
*.i*86
|
||||||
|
*.x86_64
|
||||||
|
*.hex
|
||||||
|
|
||||||
|
# Debug files
|
||||||
|
*.dSYM/
|
||||||
|
*.su
|
||||||
|
*.idb
|
||||||
|
*.pdb
|
||||||
|
|
||||||
|
# Kernel Module Compile Results
|
||||||
|
*.mod*
|
||||||
|
*.cmd
|
||||||
|
.tmp_versions/
|
||||||
|
modules.order
|
||||||
|
Module.symvers
|
||||||
|
Mkfile.old
|
||||||
|
dkms.conf
|
||||||
|
|
||||||
|
### CLion ###
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/**/usage.statistics.xml
|
||||||
|
.idea/**/dictionaries
|
||||||
|
.idea/**/shelf
|
||||||
|
|
||||||
|
# AWS User-specific
|
||||||
|
.idea/**/aws.xml
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
.idea/**/contentModel.xml
|
||||||
|
|
||||||
|
# Sensitive or high-churn files
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
.idea/**/dbnavigator.xml
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# Gradle and Maven with auto-import
|
||||||
|
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||||
|
# since they will be recreated, and may cause churn. Uncomment if using
|
||||||
|
# auto-import.
|
||||||
|
# .idea/artifacts
|
||||||
|
# .idea/compiler.xml
|
||||||
|
# .idea/jarRepositories.xml
|
||||||
|
# .idea/modules.xml
|
||||||
|
# .idea/*.iml
|
||||||
|
# .idea/modules
|
||||||
|
# *.iml
|
||||||
|
# *.ipr
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
cmake-build-*/
|
||||||
|
|
||||||
|
# Mongo Explorer plugin
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
# File-based project format
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Cursive Clojure plugin
|
||||||
|
.idea/replstate.xml
|
||||||
|
|
||||||
|
# SonarLint plugin
|
||||||
|
.idea/sonarlint/
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
|
||||||
|
# Editor-based Rest Client
|
||||||
|
.idea/httpRequests
|
||||||
|
|
||||||
|
# Android studio 3.1+ serialized cache file
|
||||||
|
.idea/caches/build_file_checksums.ser
|
||||||
|
|
||||||
|
### CLion Patch ###
|
||||||
|
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
||||||
|
|
||||||
|
# *.iml
|
||||||
|
# modules.xml
|
||||||
|
# .idea/misc.xml
|
||||||
|
# *.ipr
|
||||||
|
|
||||||
|
# Sonarlint plugin
|
||||||
|
# https://plugins.jetbrains.com/plugin/7973-sonarlint
|
||||||
|
.idea/**/sonarlint/
|
||||||
|
|
||||||
|
# SonarQube Plugin
|
||||||
|
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
|
||||||
|
.idea/**/sonarIssues.xml
|
||||||
|
|
||||||
|
# Markdown Navigator plugin
|
||||||
|
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
|
||||||
|
.idea/**/markdown-navigator.xml
|
||||||
|
.idea/**/markdown-navigator-enh.xml
|
||||||
|
.idea/**/markdown-navigator/
|
||||||
|
|
||||||
|
# Cache file creation bug
|
||||||
|
# See https://youtrack.jetbrains.com/issue/JBR-2257
|
||||||
|
.idea/$CACHE_FILE$
|
||||||
|
|
||||||
|
# CodeStream plugin
|
||||||
|
# https://plugins.jetbrains.com/plugin/12206-codestream
|
||||||
|
.idea/codestream.xml
|
||||||
|
|
||||||
|
# Azure Toolkit for IntelliJ plugin
|
||||||
|
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
|
||||||
|
.idea/**/azureSettings.xml
|
||||||
|
|
||||||
|
### CMake ###
|
||||||
|
CMakeLists.txt.user
|
||||||
|
CMakeCache.txt
|
||||||
|
CMakeFiles
|
||||||
|
CMakeScripts
|
||||||
|
Testing
|
||||||
|
Makefile
|
||||||
|
cmake_install.cmake
|
||||||
|
install_manifest.txt
|
||||||
|
compile_commands.json
|
||||||
|
CTestTestfile.cmake
|
||||||
|
_deps
|
||||||
|
|
||||||
|
### CMake Patch ###
|
||||||
|
# External projects
|
||||||
|
*-prefix/
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/c,cmake,clion
|
||||||
|
|
||||||
|
# CMake Doxygen
|
||||||
|
CMakeDoxyfile.in
|
||||||
|
CMakeDoxygenDefaults.cmake
|
||||||
|
/tcpproxy
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "lwip"]
|
||||||
|
path = lwip
|
||||||
|
url = https://git.savannah.nongnu.org/git/lwip.git
|
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
4
.idea/misc.xml
generated
Normal file
4
.idea/misc.xml
generated
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||||
|
</project>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/tcpproxy.iml" filepath="$PROJECT_DIR$/.idea/tcpproxy.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
2
.idea/tcpproxy.iml
generated
Normal file
2
.idea/tcpproxy.iml
generated
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
7
.idea/vcs.xml
generated
Normal file
7
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/lwip" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
28
CMakeLists.txt
Normal file
28
CMakeLists.txt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.25)
|
||||||
|
|
||||||
|
project(tcpproxy C)
|
||||||
|
|
||||||
|
set(LWIP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lwip)
|
||||||
|
set(LWIP_CONTRIB_DIR ${LWIP_DIR}/contrib)
|
||||||
|
set (LWIP_INCLUDE_DIRS
|
||||||
|
"${LWIP_DIR}/src/include"
|
||||||
|
"${LWIP_CONTRIB_DIR}"
|
||||||
|
"${LWIP_CONTRIB_DIR}/ports/unix/port/include"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||||
|
|
||||||
|
|
||||||
|
include(${LWIP_DIR}/src/Filelists.cmake)
|
||||||
|
include(${LWIP_DIR}/contrib/Filelists.cmake)
|
||||||
|
include(${LWIP_DIR}/contrib/ports/unix/Filelists.cmake)
|
||||||
|
|
||||||
|
set(CMAKE_C_STANDARD 11)
|
||||||
|
|
||||||
|
find_library(LIBEVENT event_core)
|
||||||
|
|
||||||
|
|
||||||
|
add_executable(tcpproxy src/main.c ${lwipcontribportunix_SRCS})
|
||||||
|
target_include_directories(tcpproxy PRIVATE ${LWIP_INCLUDE_DIRS})
|
||||||
|
target_compile_options(tcpproxy PRIVATE ${LWIP_COMPILER_FLAGS})
|
||||||
|
target_compile_definitions(tcpproxy PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
|
||||||
|
target_link_libraries(tcpproxy ${LWIP_SANITIZER_LIBS} lwipcontribexamples lwipcontribapps lwipcontribaddons lwipallapps lwipcontribportunix lwipcore lwipmbedtls ${LIBEVENT})
|
||||||
|
|
22
Dockerfile
22
Dockerfile
@ -1,4 +1,18 @@
|
|||||||
FROM haproxy:lts
|
FROM debian:bookworm-slim AS builder
|
||||||
ENV PORT=3890
|
RUN apt-get update && apt-get install -y build-essential cmake 'libevent-dev=2.1.*'
|
||||||
EXPOSE $PORT
|
COPY CMakeLists.txt /app/src/
|
||||||
ADD haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg
|
COPY NOTICE /app/src/
|
||||||
|
COPY lwip /app/src/lwip/
|
||||||
|
COPY src /app/src/src/
|
||||||
|
RUN mkdir /app/build && cd /app/build && cmake /app/src && make && mv tcpproxy ..
|
||||||
|
|
||||||
|
FROM debian:bookworm-slim
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends openconnect libevent-core-2.1-7
|
||||||
|
COPY --from=builder /app/tcpproxy /app/
|
||||||
|
COPY --from=builder /app/src/NOTICE /app/
|
||||||
|
COPY --from=builder /app/src/lwip/COPYING /app/
|
||||||
|
COPY docker-entrypoint.sh /app/
|
||||||
|
ARG HOST
|
||||||
|
EXPOSE 1234
|
||||||
|
USER nobody
|
||||||
|
ENTRYPOINT ["/app/docker-entrypoint.sh"]
|
||||||
|
28
NOTICE
Normal file
28
NOTICE
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
Copyright (c) 2023 Penn Mackintosh <penn@pennmack.co.uk>
|
||||||
|
Adapted from [ocproxy](https://github.com/cernekee/ocproxy) to use upgrade LwIP, remove LDAP functionality
|
||||||
|
Copyright (c) 2016 Google Inc.
|
||||||
|
Copyright (c) 2012-2014 David Edmondson <dme@dme.org>
|
||||||
|
Copyright (c) 2012-2014 Kevin Cernekee <cernekee@gmail.com>
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
3. The name of the author may not be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
3
docker-entrypoint.sh
Executable file
3
docker-entrypoint.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
echo openconnect --script-tun --script "/app/tcpproxy -L 1234:$HOST" "$@"
|
||||||
|
exec openconnect --script-tun --script "/app/tcpproxy -L 1234:$HOST" "$@"
|
11
haproxy.cfg
11
haproxy.cfg
@ -1,11 +0,0 @@
|
|||||||
global
|
|
||||||
|
|
||||||
defaults
|
|
||||||
mode tcp
|
|
||||||
timeout connect 5s
|
|
||||||
timeout client 50s
|
|
||||||
timeout server 50s
|
|
||||||
|
|
||||||
listen tcp-in
|
|
||||||
bind "0.0.0.0:${PORT}"
|
|
||||||
server server1 "${TARGET}"
|
|
1
lwip
Submodule
1
lwip
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit e29870c15e8bf28eac9c811dd236c474f3f2008f
|
330
src/lwipopts.h
Normal file
330
src/lwipopts.h
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_LWIPOPTS_H
|
||||||
|
#define LWIP_LWIPOPTS_H
|
||||||
|
|
||||||
|
#ifdef LWIP_OPTTEST_FILE
|
||||||
|
#include "lwipopts_test.h"
|
||||||
|
#else /* LWIP_OPTTEST_FILE */
|
||||||
|
|
||||||
|
#define LWIP_IPV4 1
|
||||||
|
#define LWIP_IPV6 1
|
||||||
|
|
||||||
|
#define NO_SYS 0
|
||||||
|
#define LWIP_SOCKET 0
|
||||||
|
#define LWIP_NETCONN 0
|
||||||
|
#define LWIP_NETIF_API (NO_SYS==0)
|
||||||
|
|
||||||
|
#define LWIP_IGMP 0
|
||||||
|
#define LWIP_ICMP LWIP_IPV4
|
||||||
|
|
||||||
|
#define LWIP_SNMP LWIP_UDP
|
||||||
|
#ifdef LWIP_HAVE_MBEDTLS
|
||||||
|
#define LWIP_SNMP_V3 (LWIP_SNMP)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LWIP_DNS LWIP_UDP
|
||||||
|
#define LWIP_MDNS_RESPONDER LWIP_UDP
|
||||||
|
|
||||||
|
#define LWIP_NUM_NETIF_CLIENT_DATA (LWIP_MDNS_RESPONDER)
|
||||||
|
|
||||||
|
#define LWIP_HAVE_LOOPIF 1
|
||||||
|
#define LWIP_NETIF_LOOPBACK 1
|
||||||
|
#define LWIP_SINGLE_NETIF 1
|
||||||
|
#define LWIP_LOOPBACK_MAX_PBUFS 10
|
||||||
|
|
||||||
|
#define TCP_LISTEN_BACKLOG 1
|
||||||
|
|
||||||
|
#define LWIP_COMPAT_SOCKETS 1
|
||||||
|
#define LWIP_SO_RCVTIMEO 1
|
||||||
|
#define LWIP_SO_RCVBUF 1
|
||||||
|
|
||||||
|
#define LWIP_TCPIP_CORE_LOCKING 1
|
||||||
|
|
||||||
|
#define LWIP_NETIF_LINK_CALLBACK 1
|
||||||
|
#define LWIP_NETIF_STATUS_CALLBACK 1
|
||||||
|
#define LWIP_NETIF_EXT_STATUS_CALLBACK 1
|
||||||
|
|
||||||
|
#ifdef LWIP_DEBUG
|
||||||
|
|
||||||
|
#define LWIP_DBG_MIN_LEVEL 0
|
||||||
|
#define PPP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define MEM_DEBUG LWIP_DBG_OFF
|
||||||
|
#define MEMP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define PBUF_DEBUG LWIP_DBG_OFF
|
||||||
|
#define API_LIB_DEBUG LWIP_DBG_OFF
|
||||||
|
#define API_MSG_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCPIP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define NETIF_DEBUG LWIP_DBG_OFF
|
||||||
|
#define SOCKETS_DEBUG LWIP_DBG_OFF
|
||||||
|
#define DNS_DEBUG LWIP_DBG_OFF
|
||||||
|
#define AUTOIP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define DHCP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define IP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define IP_REASS_DEBUG LWIP_DBG_OFF
|
||||||
|
#define ICMP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define IGMP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define UDP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_RTO_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_CWND_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_WND_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_FR_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_RST_DEBUG LWIP_DBG_OFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LWIP_DBG_TYPES_ON (LWIP_DBG_ON|LWIP_DBG_TRACE|LWIP_DBG_STATE|LWIP_DBG_FRESH|LWIP_DBG_HALT)
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Memory options ---------- */
|
||||||
|
/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
|
||||||
|
lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
|
||||||
|
byte alignment -> define MEM_ALIGNMENT to 2. */
|
||||||
|
/* MSVC port: intel processors don't need 4-byte alignment,
|
||||||
|
but are faster that way! */
|
||||||
|
#define MEM_ALIGNMENT 4U
|
||||||
|
|
||||||
|
/* MEM_SIZE: the size of the heap memory. If the application will send
|
||||||
|
a lot of data that needs to be copied, this should be set high. */
|
||||||
|
#define MEM_SIZE 1024000
|
||||||
|
|
||||||
|
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
|
||||||
|
sends a lot of data out of ROM (or other static memory), this
|
||||||
|
should be set high. */
|
||||||
|
#define MEMP_NUM_PBUF 1600
|
||||||
|
/* MEMP_NUM_RAW_PCB: the number of UDP protocol control blocks. One
|
||||||
|
per active RAW "connection". */
|
||||||
|
#define MEMP_NUM_RAW_PCB 3
|
||||||
|
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
|
||||||
|
per active UDP "connection". */
|
||||||
|
#define MEMP_NUM_UDP_PCB 8
|
||||||
|
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
|
||||||
|
connections. */
|
||||||
|
#define MEMP_NUM_TCP_PCB 1000
|
||||||
|
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
|
||||||
|
connections. */
|
||||||
|
#define MEMP_NUM_TCP_PCB_LISTEN 80
|
||||||
|
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
|
||||||
|
segments. */
|
||||||
|
#define MEMP_NUM_TCP_SEG 1600
|
||||||
|
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
|
||||||
|
timeouts. */
|
||||||
|
#define MEMP_NUM_SYS_TIMEOUT 300
|
||||||
|
|
||||||
|
/* The following four are used only with the sequential API and can be
|
||||||
|
set to 0 if the application only will use the raw API. */
|
||||||
|
/* MEMP_NUM_NETBUF: the number of struct netbufs. */
|
||||||
|
#define MEMP_NUM_NETBUF 200
|
||||||
|
/* MEMP_NUM_NETCONN: the number of struct netconns. */
|
||||||
|
#define MEMP_NUM_NETCONN 1000
|
||||||
|
/* MEMP_NUM_TCPIP_MSG_*: the number of struct tcpip_msg, which is used
|
||||||
|
for sequential API communication and incoming packets. Used in
|
||||||
|
src/api/tcpip.c. */
|
||||||
|
#define MEMP_NUM_TCPIP_MSG_API 1600
|
||||||
|
#define MEMP_NUM_TCPIP_MSG_INPKT 1600
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Pbuf options ---------- */
|
||||||
|
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
|
||||||
|
#define PBUF_POOL_SIZE 10000
|
||||||
|
|
||||||
|
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
|
||||||
|
#define PBUF_POOL_BUFSIZE 2048
|
||||||
|
|
||||||
|
/** SYS_LIGHTWEIGHT_PROT
|
||||||
|
* define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection
|
||||||
|
* for certain critical regions during buffer allocation, deallocation and memory
|
||||||
|
* allocation and deallocation.
|
||||||
|
*/
|
||||||
|
#define SYS_LIGHTWEIGHT_PROT (NO_SYS==0)
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- TCP options ---------- */
|
||||||
|
#define LWIP_TCP 1
|
||||||
|
#define TCP_TTL 255
|
||||||
|
|
||||||
|
#define LWIP_ALTCP (LWIP_TCP)
|
||||||
|
#ifdef LWIP_HAVE_MBEDTLS
|
||||||
|
#define LWIP_ALTCP_TLS (LWIP_TCP)
|
||||||
|
#define LWIP_ALTCP_TLS_MBEDTLS (LWIP_TCP)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Controls if TCP should queue segments that arrive out of
|
||||||
|
order. Define to 0 if your device is low on memory. */
|
||||||
|
#define TCP_QUEUE_OOSEQ 1
|
||||||
|
|
||||||
|
/* TCP Maximum segment size. */
|
||||||
|
#define TCP_MSS 1024
|
||||||
|
|
||||||
|
/* TCP sender buffer space (bytes). */
|
||||||
|
#define TCP_SND_BUF 65534 /* Match TCP_WND. */
|
||||||
|
|
||||||
|
/* TCP sender buffer space (pbufs). This must be at least = 2 *
|
||||||
|
TCP_SND_BUF/TCP_MSS for things to work. */
|
||||||
|
#define TCP_SND_QUEUELEN (4 * TCP_SND_BUF/TCP_MSS)
|
||||||
|
|
||||||
|
/* TCP writable space (bytes). This must be less than or equal
|
||||||
|
to TCP_SND_BUF. It is the amount of space which must be
|
||||||
|
available in the tcp snd_buf for select to return writable */
|
||||||
|
#define TCP_SNDLOWAT (TCP_SND_BUF/8)
|
||||||
|
|
||||||
|
/* TCP receive window. */
|
||||||
|
#define TCP_WND 65534 /* Avoid wrap. */
|
||||||
|
|
||||||
|
/* Maximum number of retransmissions of data segments. */
|
||||||
|
#define TCP_MAXRTX 12
|
||||||
|
|
||||||
|
/* Maximum number of retransmissions of SYN segments. */
|
||||||
|
#define TCP_SYNMAXRTX 4
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- ARP options ---------- */
|
||||||
|
#define LWIP_ARP 1
|
||||||
|
#define ARP_TABLE_SIZE 0
|
||||||
|
#define ARP_QUEUEING 1
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- IP options ---------- */
|
||||||
|
/* Define IP_FORWARD to 1 if you wish to have the ability to forward
|
||||||
|
IP packets across network interfaces. If you are going to run lwIP
|
||||||
|
on a device with only one network interface, define this to 0. */
|
||||||
|
#define IP_FORWARD 0
|
||||||
|
|
||||||
|
/* IP reassembly and segmentation.These are orthogonal even
|
||||||
|
* if they both deal with IP fragments */
|
||||||
|
#define IP_REASSEMBLY 1
|
||||||
|
#define IP_REASS_MAX_PBUFS (10 * ((1500 + PBUF_POOL_BUFSIZE - 1) / PBUF_POOL_BUFSIZE))
|
||||||
|
#define MEMP_NUM_REASSDATA IP_REASS_MAX_PBUFS
|
||||||
|
#define IP_FRAG 1
|
||||||
|
#define IPV6_FRAG_COPYHEADER 1
|
||||||
|
|
||||||
|
/* ---------- ICMP options ---------- */
|
||||||
|
#define ICMP_TTL 255
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- DHCP options ---------- */
|
||||||
|
/* Define LWIP_DHCP to 1 if you want DHCP configuration of
|
||||||
|
interfaces. */
|
||||||
|
#define LWIP_DHCP LWIP_UDP
|
||||||
|
|
||||||
|
/* 1 if you want to do an ARP check on the offered address
|
||||||
|
(recommended). */
|
||||||
|
#define DHCP_DOES_ARP_CHECK (LWIP_DHCP)
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- AUTOIP options ------- */
|
||||||
|
#define LWIP_AUTOIP (LWIP_DHCP)
|
||||||
|
#define LWIP_DHCP_AUTOIP_COOP (LWIP_DHCP && LWIP_AUTOIP)
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- UDP options ---------- */
|
||||||
|
#define LWIP_UDP 0
|
||||||
|
#define LWIP_UDPLITE LWIP_UDP
|
||||||
|
#define UDP_TTL 255
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- RAW options ---------- */
|
||||||
|
#define LWIP_RAW 0
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Statistics options ---------- */
|
||||||
|
|
||||||
|
#define LWIP_STATS 0
|
||||||
|
#define LWIP_STATS_DISPLAY 0
|
||||||
|
|
||||||
|
#if LWIP_STATS
|
||||||
|
#define LINK_STATS 1
|
||||||
|
#define IP_STATS 1
|
||||||
|
#define ICMP_STATS 1
|
||||||
|
#define IGMP_STATS 1
|
||||||
|
#define IPFRAG_STATS 1
|
||||||
|
#define UDP_STATS 1
|
||||||
|
#define TCP_STATS 1
|
||||||
|
#define MEM_STATS 1
|
||||||
|
#define MEMP_STATS 1
|
||||||
|
#define PBUF_STATS 1
|
||||||
|
#define SYS_STATS 1
|
||||||
|
#endif /* LWIP_STATS */
|
||||||
|
|
||||||
|
/* ---------- NETBIOS options ---------- */
|
||||||
|
#define LWIP_NETBIOS_RESPOND_NAME_QUERY 0
|
||||||
|
|
||||||
|
/* ---------- PPP options ---------- */
|
||||||
|
|
||||||
|
#define PPP_SUPPORT 0 /* Set > 0 for PPP */
|
||||||
|
|
||||||
|
#if PPP_SUPPORT
|
||||||
|
|
||||||
|
#define NUM_PPP 1 /* Max PPP sessions. */
|
||||||
|
|
||||||
|
|
||||||
|
/* Select modules to enable. Ideally these would be set in the makefile but
|
||||||
|
* we're limited by the command line length so you need to modify the settings
|
||||||
|
* in this file.
|
||||||
|
*/
|
||||||
|
#define PPPOE_SUPPORT 1
|
||||||
|
#define PPPOS_SUPPORT 1
|
||||||
|
|
||||||
|
#define PAP_SUPPORT 1 /* Set > 0 for PAP. */
|
||||||
|
#define CHAP_SUPPORT 1 /* Set > 0 for CHAP. */
|
||||||
|
#define MSCHAP_SUPPORT 0 /* Set > 0 for MSCHAP */
|
||||||
|
#define CBCP_SUPPORT 0 /* Set > 0 for CBCP (NOT FUNCTIONAL!) */
|
||||||
|
#define CCP_SUPPORT 0 /* Set > 0 for CCP */
|
||||||
|
#define VJ_SUPPORT 0 /* Set > 0 for VJ header compression. */
|
||||||
|
#define MD5_SUPPORT 1 /* Set > 0 for MD5 (see also CHAP) */
|
||||||
|
|
||||||
|
#endif /* PPP_SUPPORT */
|
||||||
|
|
||||||
|
#endif /* LWIP_OPTTEST_FILE */
|
||||||
|
|
||||||
|
/* The following defines must be done even in OPTTEST mode: */
|
||||||
|
|
||||||
|
#if !defined(NO_SYS) || !NO_SYS /* default is 0 */
|
||||||
|
#if 0
|
||||||
|
void sys_check_core_locking(void);
|
||||||
|
#define LWIP_ASSERT_CORE_LOCKED() sys_check_core_locking()
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LWIP_PLATFORM_ASSERT
|
||||||
|
#if 0
|
||||||
|
/* Define LWIP_PLATFORM_ASSERT to something to catch missing stdio.h includes */
|
||||||
|
void lwip_example_app_platform_assert(const char *msg, int line, const char *file);
|
||||||
|
#define LWIP_PLATFORM_ASSERT(x) lwip_example_app_platform_assert(x, __LINE__, __FILE__)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_LWIPOPTS_H */
|
808
src/main.c
Normal file
808
src/main.c
Normal file
@ -0,0 +1,808 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Penn Mackintosh <penn@pennmack.co.uk>
|
||||||
|
* Adapted from [ocproxy](https://github.com/cernekee/ocproxy) to use upgrade LwIP, remove LDAP functionality
|
||||||
|
* Copyright (c) 2016 Google Inc.
|
||||||
|
* Copyright (c) 2012-2014 David Edmondson <dme@dme.org>
|
||||||
|
* Copyright (c) 2012-2014 Kevin Cernekee <cernekee@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
|
||||||
|
#include <event2/event.h>
|
||||||
|
#include <event2/listener.h>
|
||||||
|
|
||||||
|
//#include "lwip/opt.h"
|
||||||
|
//#include "lwip/debug.h"
|
||||||
|
//#include "lwip/err.h"
|
||||||
|
//#include "lwip/init.h"
|
||||||
|
#include "lwip/ip.h"
|
||||||
|
#include "lwip/tcp.h"
|
||||||
|
#include "lwip/init.h"
|
||||||
|
//#include "lwip/dns.h"
|
||||||
|
//#include "lwip/netif.h"
|
||||||
|
//#include "lwip/stats.h"
|
||||||
|
//#include "lwip/sys.h"
|
||||||
|
//#include "lwip/tcp.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
STATE_NEW = 0,
|
||||||
|
STATE_DNS,
|
||||||
|
STATE_CONNECTING,
|
||||||
|
STATE_DATA,
|
||||||
|
STATE_DEAD,
|
||||||
|
STATE_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CONN_TYPE_REDIR 0
|
||||||
|
|
||||||
|
#define SOCKBUF_LEN 2048
|
||||||
|
|
||||||
|
#define FL_ACTIVATE 1
|
||||||
|
#define FL_DIE_ON_ERROR 2
|
||||||
|
|
||||||
|
#define MAX_IOVEC 128
|
||||||
|
#define MAX_CONN 1024
|
||||||
|
|
||||||
|
struct ocp_sock {
|
||||||
|
/* general */
|
||||||
|
int fd;
|
||||||
|
struct evconnlistener *listener;
|
||||||
|
struct event *ev;
|
||||||
|
struct tcp_pcb *tpcb;
|
||||||
|
int state;
|
||||||
|
int conn_type;
|
||||||
|
struct ocp_sock *next;
|
||||||
|
|
||||||
|
/* for TCP send/receive */
|
||||||
|
int done_len;
|
||||||
|
int lwip_blocked;
|
||||||
|
int sock_pos;
|
||||||
|
int sock_total;
|
||||||
|
char sockbuf[SOCKBUF_LEN];
|
||||||
|
|
||||||
|
/* for all listeners */
|
||||||
|
int lport;
|
||||||
|
char *bind_addr;
|
||||||
|
evconnlistener_cb listen_cb;
|
||||||
|
|
||||||
|
/* for port forwarding */
|
||||||
|
ip_addr_t rhost;
|
||||||
|
int rport;
|
||||||
|
|
||||||
|
/* for lwip_data_cb() */
|
||||||
|
struct netif *netif;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct socks_auth {
|
||||||
|
u8_t ver;
|
||||||
|
u8_t n_methods;
|
||||||
|
u8_t methods;
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
|
||||||
|
struct socks_req {
|
||||||
|
u8_t ver;
|
||||||
|
u8_t cmd;
|
||||||
|
u8_t rsv;
|
||||||
|
u8_t atyp;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
u32_t dst_addr;
|
||||||
|
u16_t dst_port;
|
||||||
|
u8_t end;
|
||||||
|
} ipv4;
|
||||||
|
struct {
|
||||||
|
u8_t fqdn_len;
|
||||||
|
u8_t fqdn_name[255]; /* variable length */
|
||||||
|
u16_t port;
|
||||||
|
} fqdn;
|
||||||
|
} u;
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
|
||||||
|
struct socks_reply {
|
||||||
|
u8_t ver;
|
||||||
|
u8_t rep;
|
||||||
|
u8_t rsv;
|
||||||
|
u8_t atyp;
|
||||||
|
u32_t bnd_addr;
|
||||||
|
u16_t bnd_port;
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
|
||||||
|
static struct event_base *event_base;
|
||||||
|
|
||||||
|
static struct ocp_sock ocp_sock_pool[MAX_CONN];
|
||||||
|
static struct ocp_sock *ocp_sock_free_list;
|
||||||
|
static struct ocp_sock *ocp_sock_bind_list;
|
||||||
|
static int ocp_sock_used;
|
||||||
|
static int ocp_sock_max;
|
||||||
|
|
||||||
|
/* nonstatic debug cmd option, exported in lwipopts.h */
|
||||||
|
unsigned char debug_flags = 0;
|
||||||
|
|
||||||
|
static int allow_remote;
|
||||||
|
static int tcpdump_enabled;
|
||||||
|
static int got_sighup;
|
||||||
|
static int got_sigusr1;
|
||||||
|
static char *dns_domain;
|
||||||
|
|
||||||
|
static void start_connection(struct ocp_sock *s);
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* Utility functions / libevent wrappers
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
static void die(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
fflush(stdout);
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void warn(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
fflush(stdout);
|
||||||
|
fprintf(stderr, "warning: ");
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *xstrdup(const char *s)
|
||||||
|
{
|
||||||
|
char *ret = strdup(s);
|
||||||
|
if (!ret)
|
||||||
|
die("out of memory\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ocp_atoi(const char *s)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
long val = strtol(s, &p, 0);
|
||||||
|
if (!*s || *p)
|
||||||
|
die("invalid integer: '%s'\n", s);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ocp_sock *ocp_sock_new(int fd, event_callback_fn cb, int flags)
|
||||||
|
{
|
||||||
|
struct ocp_sock *s;
|
||||||
|
|
||||||
|
s = ocp_sock_free_list;
|
||||||
|
if (!s) {
|
||||||
|
if (flags & FL_DIE_ON_ERROR)
|
||||||
|
die("%s: ran out of ocp_socks\n", __func__);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ocp_sock_free_list = s->next;
|
||||||
|
memset(s, 0, sizeof(*s));
|
||||||
|
|
||||||
|
ocp_sock_used++;
|
||||||
|
if (ocp_sock_used > ocp_sock_max)
|
||||||
|
ocp_sock_max = ocp_sock_used;
|
||||||
|
|
||||||
|
s->next = ocp_sock_bind_list;
|
||||||
|
ocp_sock_bind_list = s;
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
return s;
|
||||||
|
|
||||||
|
s->fd = fd;
|
||||||
|
s->ev = event_new(event_base, fd, EV_READ, cb, s);
|
||||||
|
if (flags & FL_ACTIVATE)
|
||||||
|
event_add(s->ev, NULL);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ocp_sock_del(struct ocp_sock *s)
|
||||||
|
{
|
||||||
|
if (s->state == STATE_DNS) {
|
||||||
|
s->state = STATE_DEAD;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
close(s->fd);
|
||||||
|
if (s->tpcb) {
|
||||||
|
tcp_arg(s->tpcb, NULL);
|
||||||
|
tcp_close(s->tpcb);
|
||||||
|
}
|
||||||
|
event_free(s->ev);
|
||||||
|
memset(s, 0xdd, sizeof(*s));
|
||||||
|
s->next = ocp_sock_free_list;
|
||||||
|
ocp_sock_free_list = s;
|
||||||
|
ocp_sock_used--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* lwIP TCP<->socket TCP traffic
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
/* Called when the local TCP socket has data available (or hung up) */
|
||||||
|
static void local_data_cb(evutil_socket_t fd, short what, void *ctx)
|
||||||
|
{
|
||||||
|
struct ocp_sock *s = ctx;
|
||||||
|
ssize_t len;
|
||||||
|
int try_len;
|
||||||
|
err_t err;
|
||||||
|
|
||||||
|
try_len = tcp_sndbuf(s->tpcb);
|
||||||
|
if (try_len > SOCKBUF_LEN)
|
||||||
|
try_len = SOCKBUF_LEN;
|
||||||
|
if (!try_len || tcp_sndqueuelen(s->tpcb) > (TCP_SND_QUEUELEN/2)) {
|
||||||
|
s->lwip_blocked = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = read(s->fd, s->sockbuf, try_len);
|
||||||
|
if (len <= 0) {
|
||||||
|
ocp_sock_del(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
err = tcp_write(s->tpcb, s->sockbuf, len, TCP_WRITE_FLAG_COPY);
|
||||||
|
if (err == ERR_MEM)
|
||||||
|
die("%s: out of memory\n", __func__);
|
||||||
|
else if (err != ERR_OK)
|
||||||
|
warn("tcp_write returned %d\n", (int)err);
|
||||||
|
|
||||||
|
tcp_output(s->tpcb);
|
||||||
|
event_add(s->ev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called when lwIP has sent data to the VPN */
|
||||||
|
static err_t sent_cb(void *ctx, struct tcp_pcb *tpcb, u16_t len)
|
||||||
|
{
|
||||||
|
struct ocp_sock *s = ctx;
|
||||||
|
|
||||||
|
if (!s)
|
||||||
|
return ERR_OK;
|
||||||
|
|
||||||
|
if (s->lwip_blocked) {
|
||||||
|
s->lwip_blocked = 0;
|
||||||
|
event_add(s->ev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called when lwIP has new TCP data from the VPN */
|
||||||
|
static err_t recv_cb(void *ctx, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
|
||||||
|
{
|
||||||
|
struct ocp_sock *s = ctx;
|
||||||
|
struct pbuf *first = p;
|
||||||
|
int offset;
|
||||||
|
ssize_t wlen;
|
||||||
|
|
||||||
|
if (!s)
|
||||||
|
return ERR_ABRT;
|
||||||
|
|
||||||
|
if (!p) {
|
||||||
|
ocp_sock_del(s);
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tcp_tmr() will call this function every 250ms with the same pbuf,
|
||||||
|
* if we refused data during the previous attempt. s->done_len
|
||||||
|
* will reflect the number of bytes we were able to send to the socket
|
||||||
|
* so far (if any).
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (offset = s->done_len; p && offset >= p->len; offset -= p->len)
|
||||||
|
p = p->next;
|
||||||
|
|
||||||
|
for (; p; p = p->next) {
|
||||||
|
int try_len = p->len - offset;
|
||||||
|
|
||||||
|
wlen = write(s->fd, (char *)p->payload + offset, try_len);
|
||||||
|
offset = 0;
|
||||||
|
|
||||||
|
if (wlen < 0) {
|
||||||
|
ocp_sock_del(s);
|
||||||
|
return ERR_ABRT;
|
||||||
|
}
|
||||||
|
s->done_len += wlen;
|
||||||
|
tcp_recved(tpcb, wlen);
|
||||||
|
if (wlen < try_len)
|
||||||
|
return ERR_WOULDBLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we got here, then the whole pbuf is done */
|
||||||
|
s->done_len = 0;
|
||||||
|
pbuf_free(first);
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* SOCKS protocol
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* Connection setup
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
/* Called on lwIP TCP errors; used to detect connection failure */
|
||||||
|
static void tcp_err_cb(void *arg, err_t err)
|
||||||
|
{
|
||||||
|
struct ocp_sock *s = arg;
|
||||||
|
warn("%s: called with %d\n", __func__, (int) err);
|
||||||
|
|
||||||
|
if (s) {
|
||||||
|
s->tpcb = NULL;
|
||||||
|
ocp_sock_del(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called when lwIP tcp_connect() is successful */
|
||||||
|
static err_t connect_cb(void *arg, struct tcp_pcb *tpcb, err_t err)
|
||||||
|
{
|
||||||
|
if (err != ERR_OK)
|
||||||
|
warn("%s: called with %d\n", __func__, (int) err);
|
||||||
|
|
||||||
|
struct ocp_sock *s = arg;
|
||||||
|
|
||||||
|
s->state = STATE_DATA;
|
||||||
|
event_add(s->ev, NULL);
|
||||||
|
tcp_recv(tpcb, recv_cb);
|
||||||
|
tcp_sent(tpcb, sent_cb);
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void start_connection(struct ocp_sock *s)
|
||||||
|
{
|
||||||
|
struct tcp_pcb *tpcb;
|
||||||
|
err_t err;
|
||||||
|
|
||||||
|
s->state = STATE_CONNECTING;
|
||||||
|
|
||||||
|
tpcb = tcp_new();
|
||||||
|
if (!tpcb)
|
||||||
|
die("%s: out of memory\n", __func__);
|
||||||
|
tcp_nagle_disable(tpcb);
|
||||||
|
tcp_arg(tpcb, s);
|
||||||
|
tcp_recv(tpcb, NULL);
|
||||||
|
tcp_err(tpcb, tcp_err_cb);
|
||||||
|
s->tpcb = tpcb;
|
||||||
|
|
||||||
|
|
||||||
|
err = tcp_connect(tpcb, &s->rhost, s->rport, connect_cb);
|
||||||
|
if (err != ERR_OK) {
|
||||||
|
warn("%s: tcp_connect(%s:%d) returned %d\n", __func__, ipaddr_ntoa(&s->rhost), s->rport, (int) err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called upon connection to a local TCP socket */
|
||||||
|
static void new_conn_cb(struct evconnlistener *listener, evutil_socket_t fd,
|
||||||
|
struct sockaddr *address, int socklen, void *ctx)
|
||||||
|
{
|
||||||
|
struct ocp_sock *lsock = ctx, *s;
|
||||||
|
|
||||||
|
s = ocp_sock_new(fd, local_data_cb, 0);
|
||||||
|
if (!s) {
|
||||||
|
warn("too many connections\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->conn_type = lsock->conn_type;
|
||||||
|
s->rhost = lsock->rhost;
|
||||||
|
s->rport = lsock->rport;
|
||||||
|
|
||||||
|
start_connection(s);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* lwIP<->VPN traffic
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
static void vpn_conn_down(void)
|
||||||
|
{
|
||||||
|
printf("VPN connection has terminated\n");
|
||||||
|
event_base_loopbreak(event_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called when the VPN sends us a raw IP packet destined for lwIP */
|
||||||
|
static void lwip_data_cb(evutil_socket_t fd, short what, void *ctx)
|
||||||
|
{
|
||||||
|
struct ocp_sock *s = ctx;
|
||||||
|
ssize_t len;
|
||||||
|
struct pbuf *p;
|
||||||
|
|
||||||
|
len = read(s->fd, s->sockbuf, SOCKBUF_LEN);
|
||||||
|
if (len <= 0) {
|
||||||
|
/* This might never happen, because s->fd is a DGRAM socket */
|
||||||
|
vpn_conn_down();
|
||||||
|
}
|
||||||
|
if ((p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL)) != NULL) {
|
||||||
|
char *bufptr;
|
||||||
|
struct pbuf *q;
|
||||||
|
|
||||||
|
bufptr = s->sockbuf;
|
||||||
|
q = p;
|
||||||
|
while (len > 0) {
|
||||||
|
int copy = (len > q->len) ? q->len : len;
|
||||||
|
|
||||||
|
memcpy(q->payload, bufptr, copy);
|
||||||
|
len -= copy;
|
||||||
|
bufptr += copy;
|
||||||
|
q = q->next;
|
||||||
|
}
|
||||||
|
LINK_STATS_INC(link.recv);
|
||||||
|
s->netif->input(p, s->netif);
|
||||||
|
} else
|
||||||
|
warn("%s: could not allocate pbuf\n", __func__);
|
||||||
|
event_add(s->ev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called when lwIP has data to send up to the VPN */
|
||||||
|
static err_t lwip_data_out(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr)
|
||||||
|
{
|
||||||
|
struct ocp_sock *s = netif->state;
|
||||||
|
int i = 0, total = 0;
|
||||||
|
ssize_t ret;
|
||||||
|
struct iovec iov[MAX_IOVEC];
|
||||||
|
|
||||||
|
|
||||||
|
for (; p; p = p->next) {
|
||||||
|
if (i >= MAX_IOVEC) {
|
||||||
|
warn("%s: too many chunks, dropping packet\n", __func__);
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
iov[i].iov_base = p->payload;
|
||||||
|
iov[i++].iov_len = p->len;
|
||||||
|
total += p->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = writev(s->fd, iov, i);
|
||||||
|
if (ret < 0) {
|
||||||
|
if (errno == ECONNREFUSED || errno == ENOTCONN)
|
||||||
|
vpn_conn_down();
|
||||||
|
else
|
||||||
|
LINK_STATS_INC(link.drop);
|
||||||
|
} else if (ret != total)
|
||||||
|
LINK_STATS_INC(link.lenerr);
|
||||||
|
else
|
||||||
|
LINK_STATS_INC(link.xmit);
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* Periodic tasks
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
static void handle_sig(int sig)
|
||||||
|
{
|
||||||
|
if (sig == SIGHUP)
|
||||||
|
got_sighup = 1;
|
||||||
|
else if (sig == SIGUSR1)
|
||||||
|
got_sigusr1 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void new_periodic_event(event_callback_fn cb, void *arg, int timeout_ms)
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
struct event *ev;
|
||||||
|
|
||||||
|
tv.tv_sec = timeout_ms / 1000;
|
||||||
|
tv.tv_usec = 1000 * (timeout_ms % 1000);
|
||||||
|
ev = event_new(event_base, -1, EV_PERSIST, cb, arg);
|
||||||
|
if (!ev)
|
||||||
|
die("can't create new periodic event\n");
|
||||||
|
evtimer_add(ev, &tv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cb_housekeeping(evutil_socket_t fd, short what, void *ctx)
|
||||||
|
{
|
||||||
|
int *vpnfd = ctx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OpenConnect will ignore 0-byte datagrams if it's alive, but
|
||||||
|
* we'll get ECONNREFUSED if the peer has died.
|
||||||
|
*/
|
||||||
|
if (write(*vpnfd, vpnfd, 0) < 0 &&
|
||||||
|
(errno == ECONNREFUSED || errno == ENOTCONN))
|
||||||
|
vpn_conn_down();
|
||||||
|
else if (got_sighup)
|
||||||
|
vpn_conn_down();
|
||||||
|
|
||||||
|
if (got_sigusr1) {
|
||||||
|
LINK_STATS_DISPLAY();
|
||||||
|
MEM_STATS_DISPLAY();
|
||||||
|
printf("open connections: %d / %d, max %d\n",
|
||||||
|
ocp_sock_used, MAX_CONN, ocp_sock_max);
|
||||||
|
got_sigusr1 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* Program initialization
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
static err_t init_oc_netif(struct netif *netif)
|
||||||
|
{
|
||||||
|
netif->name[0] = 'u';
|
||||||
|
netif->name[1] = 'n';
|
||||||
|
netif->output = lwip_data_out;
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bind_all_listeners(void)
|
||||||
|
{
|
||||||
|
struct ocp_sock *s;
|
||||||
|
struct sockaddr_in sock;
|
||||||
|
|
||||||
|
for (s = ocp_sock_bind_list; s; s = s->next) {
|
||||||
|
if (!s->listen_cb)
|
||||||
|
continue;
|
||||||
|
if (s->lport < 1 || s->lport > 65535)
|
||||||
|
die("invalid port number: %d\n", s->lport);
|
||||||
|
|
||||||
|
memset(&sock, 0, sizeof(sock));
|
||||||
|
sock.sin_port = htons(s->lport);
|
||||||
|
sock.sin_family = AF_INET;
|
||||||
|
|
||||||
|
if (s->bind_addr) {
|
||||||
|
/*
|
||||||
|
* TODO: support IPv6 and multiple listening sockets
|
||||||
|
* per hostname
|
||||||
|
*/
|
||||||
|
if (!inet_aton(s->bind_addr, &sock.sin_addr))
|
||||||
|
die("can't parse IP: '%s'\n", s->bind_addr);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
sock.sin_addr.s_addr = htonl(allow_remote ?
|
||||||
|
INADDR_ANY : INADDR_LOOPBACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
s->listener = evconnlistener_new_bind(event_base, s->listen_cb,
|
||||||
|
s, LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1,
|
||||||
|
(struct sockaddr *)&sock, sizeof(sock));
|
||||||
|
if (!s->listener)
|
||||||
|
die("can't set up listener on port %d/tcp\n", s->lport);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ocp_sock *new_listener(int port, evconnlistener_cb cb)
|
||||||
|
{
|
||||||
|
struct ocp_sock *s;
|
||||||
|
|
||||||
|
s = ocp_sock_new(-1, NULL, FL_DIE_ON_ERROR);
|
||||||
|
s->lport = port;
|
||||||
|
s->listen_cb = cb;
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fwd_add(const char *opt)
|
||||||
|
{
|
||||||
|
char *str = xstrdup(opt), *tmp = str, *p;
|
||||||
|
int lport;
|
||||||
|
struct ocp_sock *s;
|
||||||
|
|
||||||
|
p = strsep(&str, ":");
|
||||||
|
if (!str)
|
||||||
|
goto bad;
|
||||||
|
lport = ocp_atoi(p);
|
||||||
|
|
||||||
|
p = strsep(&str, ":");
|
||||||
|
if (!str)
|
||||||
|
goto bad;
|
||||||
|
|
||||||
|
s = new_listener(lport, new_conn_cb);
|
||||||
|
struct addrinfo *addrinfo;
|
||||||
|
|
||||||
|
int ret = getaddrinfo(p, NULL, NULL, &addrinfo);
|
||||||
|
if (ret != 0) {
|
||||||
|
die("getaddrinfo: %s\n", gai_strerror(ret));
|
||||||
|
}
|
||||||
|
ip_addr_t addr;
|
||||||
|
if (addrinfo->ai_addr->sa_family == AF_INET6) {
|
||||||
|
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) addrinfo->ai_addr;
|
||||||
|
//addr.u_addr.ip6.zone = addr6->sin6_scope_id;
|
||||||
|
addr.u_addr.ip6.addr[0] =
|
||||||
|
addr6->sin6_addr.s6_addr[0] << 24 |
|
||||||
|
addr6->sin6_addr.s6_addr[1] << 16 |
|
||||||
|
addr6->sin6_addr.s6_addr[2] << 8 |
|
||||||
|
addr6->sin6_addr.s6_addr[3] << 0;
|
||||||
|
addr.u_addr.ip6.addr[1] =
|
||||||
|
addr6->sin6_addr.s6_addr[4] << 24 |
|
||||||
|
addr6->sin6_addr.s6_addr[5] << 16 |
|
||||||
|
addr6->sin6_addr.s6_addr[6] << 8 |
|
||||||
|
addr6->sin6_addr.s6_addr[7] << 0;
|
||||||
|
addr.u_addr.ip6.addr[2] =
|
||||||
|
addr6->sin6_addr.s6_addr[8] << 24 |
|
||||||
|
addr6->sin6_addr.s6_addr[9] << 16 |
|
||||||
|
addr6->sin6_addr.s6_addr[10] << 8 |
|
||||||
|
addr6->sin6_addr.s6_addr[11] << 0;
|
||||||
|
addr.u_addr.ip6.addr[3] =
|
||||||
|
addr6->sin6_addr.s6_addr[12] << 24 |
|
||||||
|
addr6->sin6_addr.s6_addr[13] << 16 |
|
||||||
|
addr6->sin6_addr.s6_addr[14] << 8 |
|
||||||
|
addr6->sin6_addr.s6_addr[15] << 0;
|
||||||
|
} else {
|
||||||
|
struct sockaddr_in *addr4 = (struct sockaddr_in *) addrinfo->ai_addr;
|
||||||
|
addr.u_addr.ip4.addr = addr4->sin_addr.s_addr;
|
||||||
|
}
|
||||||
|
s->rhost = addr;
|
||||||
|
s->rport = ocp_atoi(str);
|
||||||
|
s->conn_type = CONN_TYPE_REDIR;
|
||||||
|
|
||||||
|
if (s->rport <= 0)
|
||||||
|
die("Remote port must be a positive integer\n");
|
||||||
|
|
||||||
|
free(tmp);
|
||||||
|
|
||||||
|
return;
|
||||||
|
bad:
|
||||||
|
die("Invalid port forward specifier: '%s'\n", opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct option longopts[] = {
|
||||||
|
{ "ip", 1, NULL, 'I' },
|
||||||
|
{ "mtu", 1, NULL, 'M' },
|
||||||
|
{ "dns", 1, NULL, 'd' },
|
||||||
|
{ "domain", 1, NULL, 'o' },
|
||||||
|
{ "localfw", 1, NULL, 'L' },
|
||||||
|
{ "dynfw", 1, NULL, 'D' },
|
||||||
|
{ "allow-remote", 0, NULL, 'g' },
|
||||||
|
{ "verbose", 0, NULL, 'v' },
|
||||||
|
{ "tcpdump", 0, NULL, 'T' },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int opt, i, vpnfd;
|
||||||
|
char *str;
|
||||||
|
char *ip_str, *mtu_str, *dns_str;
|
||||||
|
ip_addr_t ip, netmask, gw, dns;
|
||||||
|
struct ocp_sock *s;
|
||||||
|
struct netif netif;
|
||||||
|
|
||||||
|
ip_str = mtu_str = dns_str = NULL;
|
||||||
|
|
||||||
|
ocp_sock_free_list = &ocp_sock_pool[0];
|
||||||
|
for (i = 1; i < MAX_CONN; i++)
|
||||||
|
ocp_sock_pool[i - 1].next = &ocp_sock_pool[i];
|
||||||
|
|
||||||
|
event_base = event_base_new();
|
||||||
|
if (!event_base)
|
||||||
|
die("can't initialize libevent\n");
|
||||||
|
|
||||||
|
str = getenv("VPNFD");
|
||||||
|
if (!str)
|
||||||
|
die("VPNFD is not set, aborting\n");
|
||||||
|
vpnfd = ocp_atoi(str);
|
||||||
|
|
||||||
|
/* try to set the IP configuration from the environment, first */
|
||||||
|
ip_str = getenv("INTERNAL_IP4_ADDRESS");
|
||||||
|
mtu_str = getenv("INTERNAL_IP4_MTU");
|
||||||
|
|
||||||
|
dns_domain = getenv("CISCO_DEF_DOMAIN");
|
||||||
|
str = getenv("INTERNAL_IP4_DNS");
|
||||||
|
if (str) {
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
/* this could contain many addresses; just use the first one */
|
||||||
|
dns_str = xstrdup(str);
|
||||||
|
p = strchr(dns_str, ' ');
|
||||||
|
if (p)
|
||||||
|
*p = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* override with command line options */
|
||||||
|
while ((opt = getopt_long(argc, argv,
|
||||||
|
"I:M:d:o:D:k:gL:vT", longopts, NULL)) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'I':
|
||||||
|
ip_str = optarg;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
mtu_str = optarg;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
dns_str = optarg;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
dns_domain = optarg;
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
allow_remote = 1;
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
fwd_add(optarg);
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
debug_flags = LWIP_DBG_ON | LWIP_DBG_TRACE |
|
||||||
|
LWIP_DBG_STATE | LWIP_DBG_FRESH |
|
||||||
|
LWIP_DBG_HALT;
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
tcpdump_enabled = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
die("unknown option: %c\n", opt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ip_str || !mtu_str)
|
||||||
|
die("missing -I or -M\n");
|
||||||
|
|
||||||
|
if (!ipaddr_aton(ip_str, &ip))
|
||||||
|
die("Invalid IP address: '%s'\n", ip_str);
|
||||||
|
|
||||||
|
/* Debugging help. */
|
||||||
|
signal(SIGHUP, handle_sig);
|
||||||
|
signal(SIGUSR1, handle_sig);
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
setlinebuf(stdout);
|
||||||
|
setlinebuf(stderr);
|
||||||
|
|
||||||
|
/* Set up lwIP interface */
|
||||||
|
s = ocp_sock_new(vpnfd, lwip_data_cb, FL_ACTIVATE | FL_DIE_ON_ERROR);
|
||||||
|
memset(&netif, 0, sizeof(netif));
|
||||||
|
s->netif = &netif;
|
||||||
|
|
||||||
|
lwip_init();
|
||||||
|
ip_addr_set_zero(&netmask);
|
||||||
|
ip_addr_set_zero(&gw);
|
||||||
|
netif_add(&netif, &ip.u_addr.ip4, &netmask.u_addr.ip4, &gw.u_addr.ip4, s, init_oc_netif, ip_input);
|
||||||
|
netif.mtu = ocp_atoi(mtu_str);
|
||||||
|
|
||||||
|
netif_set_default(&netif);
|
||||||
|
netif_set_up(&netif);
|
||||||
|
netif_set_link_up(&netif);
|
||||||
|
|
||||||
|
/* bind after all options have been parsed (especially -g) */
|
||||||
|
bind_all_listeners();
|
||||||
|
|
||||||
|
|
||||||
|
new_periodic_event(cb_housekeeping, &vpnfd, 1000);
|
||||||
|
|
||||||
|
event_base_dispatch(event_base);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user