Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Karasiq committed Sep 14, 2015
1 parent 3a6dacd commit b45f870
Show file tree
Hide file tree
Showing 14 changed files with 87 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ proxyChain {
script = "proxychain.coffee" // Proxy script file
host = "0.0.0.0" // Listen IP
port = 1080 // Listen port (0 to disable)
frozen-connection-close = 2m // Close frozen connections after this duration

tls-port = 443 // TLS listen port (0 to disable)
tls-port = 0 // TLS listen port (0 to disable)
tls-key = "proxychain-server"
tls-client-auth = true

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.karasiq.proxychain.app
package com.karasiq.proxychain

import java.net.InetSocketAddress

import com.karasiq.fileutils.PathUtils._
import com.karasiq.proxy.ProxyChain
import com.typesafe.config.{Config, ConfigFactory}

private[app] object AppConfig {
object AppConfig {
def apply(cfg: Config): AppConfig = new AppConfig {
override def firewall(): Firewall = Firewall(cfg)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.karasiq.proxychain.app
package com.karasiq.proxychain

import java.net.{InetAddress, InetSocketAddress, UnknownHostException}

Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/com/karasiq/proxychain/app/Boot.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import akka.io.Tcp.Bind
import akka.io.{IO, Tcp}
import akka.kernel.Bootable
import com.karasiq.fileutils.PathUtils._
import com.karasiq.proxychain.app.script.ScriptEngine
import com.karasiq.proxychain.AppConfig
import com.karasiq.proxychain.script.ScriptEngine
import com.typesafe.config.Config

final class Boot extends Bootable {
Expand Down
44 changes: 44 additions & 0 deletions src/main/scala/com/karasiq/proxychain/app/ConnectionWatcher.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.karasiq.proxychain.app

import java.util.concurrent.TimeUnit

import akka.actor._
import akka.io.Tcp
import com.karasiq.proxychain.AppConfig

import scala.concurrent.duration._

private[app] object ConnectionWatcher {
case object Refresh

def closeFrozenConnectionsAfter(): Option[FiniteDuration] = {
val config = AppConfig.externalConfig().getConfig("proxyChain")
val ms = config.getDuration("frozen-connection-close", TimeUnit.MILLISECONDS)
if (ms > 0) Some(FiniteDuration(ms, TimeUnit.MILLISECONDS)) else None
}
}

private[app] final class ConnectionWatcher(connection: ActorRef) extends Actor {
import context.dispatcher

context.watch(connection)
private val closeAfter = ConnectionWatcher.closeFrozenConnectionsAfter()
private var task = createTask()

def createTask(): Cancellable = {
closeAfter.map { ca
context.system.scheduler.scheduleOnce(ca) {
connection ! Tcp.Close
}
}.orNull
}

override def receive: Receive = {
case Terminated(`connection`)
task.cancel()
context.stop(self)

case ConnectionWatcher.Refresh if task != null && (task.cancel() || task.isCancelled)
task = createTask()
}
}
25 changes: 19 additions & 6 deletions src/main/scala/com/karasiq/proxychain/app/Handler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.karasiq.parsers.http.{HttpConnect, HttpMethod, HttpRequest, HttpRespo
import com.karasiq.parsers.socks.SocksClient._
import com.karasiq.parsers.socks.SocksServer._
import com.karasiq.proxy.ProxyException
import com.karasiq.proxychain.{AppConfig, Firewall}
import org.apache.commons.io.IOUtils

import scala.collection.JavaConversions._
Expand All @@ -26,9 +27,9 @@ import scala.language.postfixOps
import scala.util.{Failure, Success, Try, control}

/**
* SOCKS5 connection handler
* Proxy connection handler
*/
private[app] final class Handler(cfg: AppConfig) extends Actor with ActorLogging {
class Handler(cfg: AppConfig) extends Actor with ActorLogging {
import context.dispatcher

private val firewall: Firewall = cfg.firewall()
Expand Down Expand Up @@ -86,21 +87,33 @@ private[app] final class Handler(cfg: AppConfig) extends Actor with ActorLogging
context.stop(self)
}

private def becomeConnected(conn: ActorRef, socket: SocketChannel): Unit = {
private def becomeConnected(connection: ActorRef, socket: SocketChannel): Unit = {
val writer = context.actorOf(Props(SocketChannelWrapper.writer(socket)))
val watcher = context.actorOf(Props(classOf[ConnectionWatcher], connection))

val stream: Receive = {
case Received(data)
writer ! Write(data)
watcher ! ConnectionWatcher.Refresh
}

context.become(stream.orElse(onClose))
SocketChannelWrapper.register(socket, context.actorOf(Props(new Actor {
@throws[Exception](classOf[Exception])
override def preStart(): Unit = {
context.watch(connection)
}

override def receive: Actor.Receive = {
case Received(data)
conn ! Write(data)
connection ! Write(data)
watcher ! ConnectionWatcher.Refresh

case PeerClosed
conn ! ConfirmedClose
connection ! Close
context.stop(self)

case Terminated(`connection`)
context.stop(self)
}
})))
Expand Down Expand Up @@ -157,7 +170,7 @@ private[app] final class Handler(cfg: AppConfig) extends Actor with ActorLogging

private def dummyPage(): ByteString = {
val resource = getClass.getClassLoader.getResourceAsStream("proxychain-dummy.html")
control.Exception.allCatch.andFinally(resource.close()) {
control.Exception.allCatch.andFinally(IOUtils.closeQuietly(resource)) {
ByteString(IOUtils.toString(resource, "UTF-8"), "UTF-8")
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/main/scala/com/karasiq/proxychain/app/Server.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import java.util.concurrent.Executors

import akka.actor._
import akka.event.Logging
import com.karasiq.proxychain.AppConfig
import com.karasiq.tls.{TLS, TLSCertificateVerifier, TLSKeyStore, TLSServerWrapper}

import scala.concurrent.{ExecutionContext, Future, Promise}
import scala.util.control

private[app] final class Server(cfg: AppConfig) extends Actor with ActorLogging {
class Server(cfg: AppConfig) extends Actor with ActorLogging {
import akka.io.Tcp._

def receive = {
Expand All @@ -29,7 +30,7 @@ private[app] final class Server(cfg: AppConfig) extends Actor with ActorLogging
}

// TLS tamper
private[app] final class TLSServer(address: InetSocketAddress, cfg: AppConfig) extends Actor with ActorLogging {
class TLSServer(address: InetSocketAddress, cfg: AppConfig) extends Actor with ActorLogging {
import akka.io.Tcp._
val serverSocket = ServerSocketChannel.open()
private case class Accepted(socket: SocketChannel)
Expand Down Expand Up @@ -89,7 +90,7 @@ private[app] final class TLSServer(address: InetSocketAddress, cfg: AppConfig) e
}

override protected def onHandshakeFinished(): Unit = {
log.debug("TLS handhake finished")
log.debug("TLS handshake finished")
tlsSocket.future.onSuccess { case socket: SocketChannel
val actor = context.actorOf(Props(classOf[TLSHandlerTamper], socket))
actor ! Register(handler)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import com.karasiq.networkutils.SocketChannelWrapper

import scala.util.control

class TLSHandlerTamper(tlsSocket: SocketChannel) extends Actor with ActorLogging with Stash {
final class TLSHandlerTamper(tlsSocket: SocketChannel) extends Actor with ActorLogging with Stash {
private var handler: Option[ActorRef] = None
private val writer: ActorRef = context.actorOf(Props(SocketChannelWrapper.writer(tlsSocket)), "tlsTamperWriter")

@throws[Exception](classOf[Exception])
override def preStart(): Unit = {
Expand Down Expand Up @@ -69,9 +70,8 @@ class TLSHandlerTamper(tlsSocket: SocketChannel) extends Actor with ActorLogging
unstashAll()
context.become(onClose.orElse(readResumed).orElse(streaming))

case w @ Write(data, ack)
tlsSocket.write(data.toByteBuffer)
if (ack != Tcp.NoAck) sender() ! ack
case w: Write
writer ! w

case event: Tcp.Event
handler.foreach(_ ! event)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.karasiq.proxychain.app.script
package com.karasiq.proxychain.script

import com.karasiq.proxy.ProxyChain

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.karasiq.proxychain.app.script
package com.karasiq.proxychain.script

import com.karasiq.networkutils.proxy.Proxy
import com.karasiq.proxy.ProxyChain
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.karasiq.proxychain.app.script
package com.karasiq.proxychain.script

import com.karasiq.networkutils.proxy.Proxy
import jdk.nashorn.api.scripting.JSObject
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.karasiq.proxychain.app.script
package com.karasiq.proxychain.script

import javax.script.Invocable

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.karasiq.proxychain.app.script
package com.karasiq.proxychain.script

import java.io.{IOException, InputStream}
import java.net.URL
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.karasiq.proxychain.app.script
package com.karasiq.proxychain.script

import java.io.InputStreamReader
import java.net.InetSocketAddress
Expand All @@ -9,21 +9,20 @@ import javax.script._
import akka.event.LoggingAdapter
import com.karasiq.fileutils.PathUtils._
import com.karasiq.proxy.ProxyChain
import com.karasiq.proxychain.app.{AppConfig, Firewall}
import com.karasiq.proxychain.{AppConfig, Firewall}
import org.apache.commons.io.IOUtils

import scala.language.dynamics
import scala.util.control.Exception

private[app] final class ScriptEngine(log: LoggingAdapter) {
class ScriptEngine(log: LoggingAdapter) {
// Script executor
private val scriptEngine = {
val scriptEngineManager = new ScriptEngineManager()
scriptEngineManager.getEngineByName("coffeescript")
}

@inline
private def createBindings(): Bindings = {
protected def createBindings(): Bindings = {
val bindings = scriptEngine.createBindings()
bindings.put("Conversions", Conversions) // JS conversions util
bindings.put("ChainBuilder", ChainBuilder) // Chain build util
Expand Down

0 comments on commit b45f870

Please sign in to comment.