2011-01-18 4 views
1

현재 C++ 프로그램에서 SOCKS 4/5 기능을 구현하려고합니다 (예 : 원하는 경우 임의의 프로토콜 및 호스트에 대한 요청을 주어진 SOCKS 프록시를 통해 리디렉션 할 수 있음). Winsock 2를 사용하여 Windows 용으로 순전히 개발하고 있습니다.SOCKS 프록시 요청에 어떤 문제가 있습니까?

"이 기능은 어떻게 작동합니까?" SOCKS 4에 대한 RFC를 읽었습니다. (SOCKS 4를 구현하기로 결정한 이유는 요청한 바이트 수가 적기 때문입니다.) send() C 문자열을 작성하는 데 어려움을 겪고 있습니다. 현재

, 내가 가진 다음과 같습니다 Socks4Msg라고 정의 구조체 :

struct Socks4Msg { 
const static uint8_t version = 0x04; //SOCKS version 4 (obviously) 
const static uint8_t command = 0x01; //1 is TCP CONNECT command 
const static uint8_t nullbyte = 0x00; //null byte sent at message end 

uint16_t port; //16 bit/2 byte port (network order) 
uint32_t ip; //32 bit/4 byte IP address (network order) 
Socks4Msg(uint16_t p, uint32_t i) : port(p), ip(i) { } 
}; 

실제 소켓을 만들고 작업이 여기에 수행하는 기능 (p와 h는 포트를 개최 어디 호스트가 에서까지 테스트하려면 proxy-p는 이미 구현 한 HttpProxy와의 호환성을 유지하기위한 문자열입니다. port와 addr는 클래스의 일부이며 각각 int와 string입니다. 그것들은 프록시 서버의 세부 사항입니다.

int Socks4Proxy::test(std::string p, std::string h) const { 
uint16_t network_port = htons(str_to_numt<uint16_t>(p)); 
uint32_t network_ip = hostname_to_ip(h); 
Socks4Msg msg_struct(network_port,network_ip); 

SOCKET s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 
int last_error; 
if(s == INVALID_SOCKET) { 
       last_error = WSAGetLastError(); 
       std::cerr << "Failed to initialise socket! Error code: " << last_error << std::endl; 
       return 2; 
} 

sockaddr_in st_addr; 
st_addr.sin_family = AF_INET; 
st_addr.sin_port = htons(port); 
ipaddr_t ip = inet_addr(addr.c_str()); 
st_addr.sin_addr.S_un.S_addr = ip; 

if(connect(s,(sockaddr*)&st_addr,sizeof(st_addr))!=0) { 
                 last_error = WSAGetLastError(); 
                 std::cerr << "Socket failed to connect. Error code: " << last_error << std::endl; 
                 return 2; 
} 

uint8_t message[13]; 
uint8_t* message_ptr; 
memset(message, 0, 13); 
message_ptr = message; 
*message_ptr = msg_struct.version; 
message_ptr++; 
*message_ptr = msg_struct.command; 
message_ptr++; 
*message_ptr = msg_struct.port; 
message_ptr += 2; 
*message_ptr = msg_struct.ip; 
message_ptr += 4; 
*message_ptr = 'b'; message_ptr++; *message_ptr = 'o'; message_ptr++; *message_ptr = 'b'; message_ptr++; 
*message_ptr = msg_struct.nullbyte; 
message_ptr++; 
*message_ptr = 0x00; 
char smessage[13]; 
memcpy(smessage, message, 13); 

int return_val; 
while(return_val = send(s, smessage, strlen(smessage), 0)) { 
         if(return_val == SOCKET_ERROR) { 
            last_error = WSAGetLastError(); 
            std::cerr << "Writing data failed. Error code: " << last_error << std::endl; 
            return 2; 
         } 
         //implement return_val < strlen(message) here 
         else break; 
} 
//remainder of function 

나는 시험과 msg_struct의 구성원이 C 문자열 조작이 시작되기 전에 올바른 데이터를 (그리고 올바른 바이트 순서로)이 포함되어 있음을 확인했습니다.

나는 Wireshack 항상의 바이트 길이를 인용 이유 (2) 예 방어 적이기 (message_ptr, & msg_struct.port) 할당 대신에 방어 적이기()를 사용하지만, 난 그냥 이해할 수없는 일을 시도했습니다 전송 된 데이터는 2 (즉, 버전 및 명령)이지만 다른 것은 없습니다. (C 문자열에 대한 지식과 그 시점의 코드는 약간 거친 것이지만 왜 작동하지 않는지 설명 할 수는 없습니다)

어떤 조언을 주시면 감사하겠습니다!

답변

1

우선 message_ptruint8_t*이고 *message_ptr = msg_struct.ip;은 잘못되었습니다. message_ptruint_32t*으로 캐스팅 한 다음 데이터를 할당하십시오 (예 : * ((uint32_t*)message_ptr) = msg_struct.ip;). 그렇지 않으면 msg_struct.ip이 uint8_t로 변환 된 다음 할당됩니다. 다른 필드에도 같은 문제가 있습니다.

확인이와 다시 woring 경우 :

을 BTW 알려주세요. Wireshark 네트워크 트래픽 분석기는 이러한 종류의 문제를 검색하는 데 많은 도움이 될 것이라고 생각합니다.

UPDATE

은 아마 더 나은 아이디어를 보내려하고이 구조에서 포인터에 message_ptr 캐스트 메시지를 표현하는 구조를 만드는 것입니다. 그러나 패딩을 추가하지 않도록 컴파일러에게 알려주는 것을 잊지 마십시오.

UPDATE 2

네트워크와 호스트 바이트 순서.

hton, ntoh, htonl 또는 ntohl 함수를 사용하여 바이트 순서를 변경해야한다는 것을 잊지 마십시오.

+0

조언 해 주셔서 감사합니다. 좋아요, 포트 및 IP에 대해 각각 \ * ((uint16_t *) message_ptr) 및 \ * ((uint32_t *) message_ptr) 캐스트를 추가했습니다. 그래도 변화는 없습니다. Wireshark는 메시지 본문이 0x04 0x01 인 것으로보고합니다.이 메시지 본문은 완벽하게 괜찮습니다. 잘못 잘라낸 것입니다. 조심스럽게. : P – Ellie

+0

strlen (smessage) 값을 확인하십시오. 그것은 매우 작을 수 있습니다. 왜냐하면 '\ 0은 텍스트에 포함될 수 있고 프로토콜 메시지는 텍스트가 아닙니다;) 내가 볼 수있는 한, 적어도 * 1 message_ptr = msg_struct.nullbyte 때문에 예상보다 1 바이트 작을 것입니다 ; ' – Elalfer

+0

구조체에 모든 것을 넣으려는 생각에 전혀 나쁜 생각이 아닙니다. 아마 몇 시간 전에 생각하고 내 머리카락을 살려 줘야 했겠지만, 적어도 아직 약간 남아 있습니다. :) 환호, 나는 그것을 할 것이고 무엇이 일어나는 것을 볼 것이다. – Ellie

관련 문제