#line 1 "src/panda/unievent/socks/SocksParser.rl"
#include "SocksFilter.h"
namespace panda { namespace unievent { namespace socks {
#line 93 "src/panda/unievent/socks/SocksParser.rl"
#line 13 "src/panda/unievent/socks/SocksParser.cc"
static const int socks5_client_parser_start = 1;
static const int socks5_client_parser_first_final = 13;
static const int socks5_client_parser_error = 0;
static const int socks5_client_parser_en_negotiate_reply = 9;
static const int socks5_client_parser_en_auth_reply = 11;
static const int socks5_client_parser_en_connect_reply = 1;
#line 96 "src/panda/unievent/socks/SocksParser.rl"
void SocksFilter::handle_read (string& buf, const ErrorCode& err) {
panda_log_debug("handle_read, err: " << err << " state:" << state << ", " << buf.length() << " bytes");
if (state == State::terminal) return NextFilter::handle_read(buf, err);
if (err) return do_error(err);
panda_log_verbose_debug(log::escaped{buf});
// pointer to current buffer
const char* buffer_ptr = buf.data();
// start parsing from the beginning pointer
const char* p = buffer_ptr;
// to the end pointer
const char* pe = buffer_ptr + buf.size();
const char* eof = pe;
// select reply parser by our state
switch (state) {
case State::handshake_reply:
cs = socks5_client_parser_en_negotiate_reply;
break;
case State::auth_reply:
cs = socks5_client_parser_en_auth_reply;
break;
case State::connect_reply:
cs = socks5_client_parser_en_connect_reply;
break;
case State::parsing:
// need more input
break;
case State::error:
panda_log_notice("error state, wont parse");
return;
default:
panda_log_notice("bad state, len: " << int(p - buffer_ptr));
do_error(errc::protocol_error);
return;
}
state = State::parsing;
#line 66 "src/panda/unievent/socks/SocksParser.cc"
{
short _widec;
if ( p == pe )
goto _test_eof;
switch ( cs )
{
case 1:
if ( (*p) == 5 )
goto st2;
goto tr0;
tr0:
#line 70 "src/panda/unievent/socks/SocksParser.rl"
{
do_error(errc::protocol_error);
}
goto st0;
#line 83 "src/panda/unievent/socks/SocksParser.cc"
st0:
cs = 0;
goto _out;
st2:
if ( ++p == pe )
goto _test_eof2;
case 2:
if ( (*p) == 0 )
goto tr2;
goto tr0;
tr2:
#line 65 "src/panda/unievent/socks/SocksParser.rl"
{
rep = (uint8_t)*p;
panda_log_verbose_debug("rep: " << rep);
}
goto st3;
st3:
if ( ++p == pe )
goto _test_eof3;
case 3:
#line 105 "src/panda/unievent/socks/SocksParser.cc"
if ( (*p) == 0 )
goto st4;
goto tr0;
st4:
if ( ++p == pe )
goto _test_eof4;
case 4:
goto tr4;
tr4:
#line 60 "src/panda/unievent/socks/SocksParser.rl"
{
atyp = (uint8_t)*p;
panda_log_verbose_debug("atyp: " << atyp);
}
goto st5;
st5:
if ( ++p == pe )
goto _test_eof5;
case 5:
#line 125 "src/panda/unievent/socks/SocksParser.cc"
_widec = (*p);
if ( (*p) < 5 ) {
if ( (*p) > 3 ) {
if ( 4 <= (*p) && (*p) <= 4 ) {
_widec = (short)(1152 + ((*p) - -128));
if (
#line 89 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x01 ) _widec += 256;
if (
#line 90 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x04 ) _widec += 512;
}
} else {
_widec = (short)(1152 + ((*p) - -128));
if (
#line 89 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x01 ) _widec += 256;
if (
#line 90 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x04 ) _widec += 512;
}
} else if ( (*p) > 15 ) {
if ( (*p) > 16 ) {
if ( 17 <= (*p) )
{ _widec = (short)(1152 + ((*p) - -128));
if (
#line 89 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x01 ) _widec += 256;
if (
#line 90 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x04 ) _widec += 512;
}
} else if ( (*p) >= 16 ) {
_widec = (short)(1152 + ((*p) - -128));
if (
#line 89 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x01 ) _widec += 256;
if (
#line 90 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x04 ) _widec += 512;
}
} else {
_widec = (short)(1152 + ((*p) - -128));
if (
#line 89 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x01 ) _widec += 256;
if (
#line 90 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x04 ) _widec += 512;
}
switch( _widec ) {
case 1540: goto tr6;
case 1808: goto tr8;
case 2052: goto tr10;
case 2064: goto tr11;
}
if ( _widec < 1664 ) {
if ( 1408 <= _widec && _widec <= 1663 )
goto tr5;
} else if ( _widec > 1919 ) {
if ( 1920 <= _widec && _widec <= 2175 )
goto tr9;
} else
goto tr7;
goto tr0;
tr5:
#line 52 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("ip4");
}
goto st6;
tr7:
#line 56 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("ip6");
}
goto st6;
tr9:
#line 52 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("ip4");
}
#line 56 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("ip6");
}
goto st6;
st6:
if ( ++p == pe )
goto _test_eof6;
case 6:
#line 217 "src/panda/unievent/socks/SocksParser.cc"
if ( (*p) == 2 )
goto tr13;
goto tr12;
tr12:
#line 22 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("connect");
if(rep) {
do_error(errc::protocol_error);
{p++; cs = 13; goto _out;}
}
do_connected();
}
goto st13;
st13:
if ( ++p == pe )
goto _test_eof13;
case 13:
#line 236 "src/panda/unievent/socks/SocksParser.cc"
goto st0;
tr13:
#line 22 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("connect");
if(rep) {
do_error(errc::protocol_error);
{p++; cs = 14; goto _out;}
}
do_connected();
}
goto st14;
tr14:
#line 52 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("ip4");
}
#line 22 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("connect");
if(rep) {
do_error(errc::protocol_error);
{p++; cs = 14; goto _out;}
}
do_connected();
}
goto st14;
tr16:
#line 56 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("ip6");
}
#line 22 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("connect");
if(rep) {
do_error(errc::protocol_error);
{p++; cs = 14; goto _out;}
}
do_connected();
}
goto st14;
st14:
if ( ++p == pe )
goto _test_eof14;
case 14:
#line 283 "src/panda/unievent/socks/SocksParser.cc"
if ( (*p) == 2 )
goto tr13;
goto tr12;
tr6:
#line 52 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("ip4");
}
goto st7;
tr10:
#line 52 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("ip4");
}
#line 56 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("ip6");
}
goto st7;
st7:
if ( ++p == pe )
goto _test_eof7;
case 7:
#line 307 "src/panda/unievent/socks/SocksParser.cc"
_widec = (*p);
if ( (*p) < 4 ) {
if ( (*p) <= 3 ) {
_widec = (short)(128 + ((*p) - -128));
if (
#line 89 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x01 ) _widec += 256;
}
} else if ( (*p) > 4 ) {
if ( 5 <= (*p) )
{ _widec = (short)(128 + ((*p) - -128));
if (
#line 89 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x01 ) _widec += 256;
}
} else {
_widec = (short)(128 + ((*p) - -128));
if (
#line 89 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x01 ) _widec += 256;
}
switch( _widec ) {
case 258: goto tr13;
case 516: goto tr15;
}
if ( _widec > 383 ) {
if ( 384 <= _widec && _widec <= 639 )
goto tr14;
} else if ( _widec >= 128 )
goto tr12;
goto tr0;
tr15:
#line 52 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("ip4");
}
#line 22 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("connect");
if(rep) {
do_error(errc::protocol_error);
{p++; cs = 15; goto _out;}
}
do_connected();
}
goto st15;
st15:
if ( ++p == pe )
goto _test_eof15;
case 15:
#line 358 "src/panda/unievent/socks/SocksParser.cc"
_widec = (*p);
if ( (*p) < 4 ) {
if ( (*p) <= 3 ) {
_widec = (short)(128 + ((*p) - -128));
if (
#line 89 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x01 ) _widec += 256;
}
} else if ( (*p) > 4 ) {
if ( 5 <= (*p) )
{ _widec = (short)(128 + ((*p) - -128));
if (
#line 89 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x01 ) _widec += 256;
}
} else {
_widec = (short)(128 + ((*p) - -128));
if (
#line 89 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x01 ) _widec += 256;
}
switch( _widec ) {
case 258: goto tr13;
case 516: goto tr15;
}
if ( _widec > 383 ) {
if ( 384 <= _widec && _widec <= 639 )
goto tr14;
} else if ( _widec >= 128 )
goto tr12;
goto st0;
tr8:
#line 56 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("ip6");
}
goto st8;
tr11:
#line 52 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("ip4");
}
#line 56 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("ip6");
}
goto st8;
st8:
if ( ++p == pe )
goto _test_eof8;
case 8:
#line 410 "src/panda/unievent/socks/SocksParser.cc"
_widec = (*p);
if ( (*p) < 16 ) {
if ( (*p) <= 15 ) {
_widec = (short)(640 + ((*p) - -128));
if (
#line 90 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x04 ) _widec += 256;
}
} else if ( (*p) > 16 ) {
if ( 17 <= (*p) )
{ _widec = (short)(640 + ((*p) - -128));
if (
#line 90 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x04 ) _widec += 256;
}
} else {
_widec = (short)(640 + ((*p) - -128));
if (
#line 90 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x04 ) _widec += 256;
}
switch( _widec ) {
case 770: goto tr13;
case 1040: goto tr17;
}
if ( _widec > 895 ) {
if ( 896 <= _widec && _widec <= 1151 )
goto tr16;
} else if ( _widec >= 640 )
goto tr12;
goto tr0;
tr17:
#line 56 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("ip6");
}
#line 22 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("connect");
if(rep) {
do_error(errc::protocol_error);
{p++; cs = 16; goto _out;}
}
do_connected();
}
goto st16;
st16:
if ( ++p == pe )
goto _test_eof16;
case 16:
#line 461 "src/panda/unievent/socks/SocksParser.cc"
_widec = (*p);
if ( (*p) < 16 ) {
if ( (*p) <= 15 ) {
_widec = (short)(640 + ((*p) - -128));
if (
#line 90 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x04 ) _widec += 256;
}
} else if ( (*p) > 16 ) {
if ( 17 <= (*p) )
{ _widec = (short)(640 + ((*p) - -128));
if (
#line 90 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x04 ) _widec += 256;
}
} else {
_widec = (short)(640 + ((*p) - -128));
if (
#line 90 "src/panda/unievent/socks/SocksParser.rl"
atyp==0x04 ) _widec += 256;
}
switch( _widec ) {
case 770: goto tr13;
case 1040: goto tr17;
}
if ( _widec > 895 ) {
if ( 896 <= _widec && _widec <= 1151 )
goto tr16;
} else if ( _widec >= 640 )
goto tr12;
goto st0;
case 9:
if ( (*p) == 5 )
goto st10;
goto tr0;
st10:
if ( ++p == pe )
goto _test_eof10;
case 10:
switch( (*p) ) {
case -1: goto tr19;
case 0: goto tr20;
case 2: goto tr21;
}
goto tr0;
tr19:
#line 46 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("noacceptable method");
do_error(errc::no_acceptable_auth_method);
{p++; cs = 17; goto _out;}
}
#line 8 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("negotiate");
if(noauth) {
do_connect();
} else {
do_auth();
}
}
goto st17;
tr20:
#line 36 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("noauth method");
noauth = true;
}
#line 8 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("negotiate");
if(noauth) {
do_connect();
} else {
do_auth();
}
}
goto st17;
tr21:
#line 41 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("userpass method");
noauth = false;
}
#line 8 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("negotiate");
if(noauth) {
do_connect();
} else {
do_auth();
}
}
goto st17;
st17:
if ( ++p == pe )
goto _test_eof17;
case 17:
#line 560 "src/panda/unievent/socks/SocksParser.cc"
goto tr0;
case 11:
if ( (*p) == 1 )
goto st12;
goto tr0;
st12:
if ( ++p == pe )
goto _test_eof12;
case 12:
goto tr23;
tr23:
#line 31 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("auth status");
auth_status = (uint8_t)*p;
}
#line 17 "src/panda/unievent/socks/SocksParser.rl"
{
panda_log_verbose_debug("auth");
do_connect();
}
goto st18;
st18:
if ( ++p == pe )
goto _test_eof18;
case 18:
#line 587 "src/panda/unievent/socks/SocksParser.cc"
goto st0;
}
_test_eof2: cs = 2; goto _test_eof;
_test_eof3: cs = 3; goto _test_eof;
_test_eof4: cs = 4; goto _test_eof;
_test_eof5: cs = 5; goto _test_eof;
_test_eof6: cs = 6; goto _test_eof;
_test_eof13: cs = 13; goto _test_eof;
_test_eof14: cs = 14; goto _test_eof;
_test_eof7: cs = 7; goto _test_eof;
_test_eof15: cs = 15; goto _test_eof;
_test_eof8: cs = 8; goto _test_eof;
_test_eof16: cs = 16; goto _test_eof;
_test_eof10: cs = 10; goto _test_eof;
_test_eof17: cs = 17; goto _test_eof;
_test_eof12: cs = 12; goto _test_eof;
_test_eof18: cs = 18; goto _test_eof;
_test_eof: {}
if ( p == eof )
{
switch ( cs ) {
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
#line 70 "src/panda/unievent/socks/SocksParser.rl"
{
do_error(errc::protocol_error);
}
break;
#line 627 "src/panda/unievent/socks/SocksParser.cc"
}
}
_out: {}
}
#line 138 "src/panda/unievent/socks/SocksParser.rl"
if (state == State::error) {
panda_log_notice("parser exiting in error state on pos: " << int(p - buffer_ptr));
} else if (state != State::parsing) {
panda_log_debug("parser finished");
}
}
}}}