Tunnel IRC through HTTP proxies

by Reinhard Max

There is not much error checking yet, but it already works for me.

It is only useful within networks that don't allow direct access to IRC, but have a proxy that allows HTTP/1.1 CONNECTs to the outside. CONNECT might be restricted to certain ports such as 443 (HTTPS). In that case you can only connect to IRC servers that listen on a port that is allowed by your local proxy.

Please fill in the name and port number of your proxy server and set up your IRC client to connect to port 6667 of the machine this proxy is running on.

PT 2003-07-21: See also SSL Tunnel for a version that supports an authenticating web proxy server.


These settings are only examples. There is no need to 'fix' this page by adding your local settings

====== THIS MEANS YOU ! ====

set useproxy    1
set proxyserver proxy.example.com
set proxyport   3128
set ircserver   rucus.zanet.net
set ircport     443
set localport   6667

proc server {sock host port} {
    puts "connection from $host $port on $sock"
    if {$::useproxy} {
        set irc [socket $::proxyserver $::proxyport]
        puts $irc "CONNECT $::ircserver:$::ircport HTTP/1.1"
        puts $irc "Host: $::ircserver"
        puts $irc {} 
        flush $irc
        while {[gets $irc line] > -1 && $line ne {}} {
            puts $line
        }
        if {[eof $irc]} {
                close $irc
                close $sock
                return
        }
    } else {
        set irc [socket $::ircserver $::ircport]
    }
    fconfigure $sock -blocking no -buffering none -translation binary
    fconfigure $irc -blocking no -buffering none -translation binary

    fileevent $sock readable [list proxy $sock $irc ]
    fileevent $irc  readable [list proxy $irc  $sock]
}

proc proxy {sock1 sock2} {
    puts -nonewline $sock2 [read $sock1]
    if {[eof $sock1]} {
        puts "closing $sock1 $sock2"
        close $sock1
        close $sock2
    }
    return
}

proc main {} {
    set server [socket -server server -myaddr 127.0.0.1 $::localport]
    vwait ::forever
}
main