无法查询其他端口并将响应发送回用户

时间:2018-06-07 20:20:39

标签: c sockets

首先,抱歉,如果我的头衔不是很好。无法想到一个好头衔。 所以,我尝试的是创建了一个应用程序,它侦听端口27080上的所有数据包。然后,它将数据包发送到另一个端口(有一个响应的服务器),然后将该响应发送回用户。现在,使用iptables,我将一个特定类型的数据包(查询数据包)从主端口重定向到此应用程序。现在,由于用户正在接收响应,因此主服务器应该在我的列表中在线。但是,只要我开始将数据包重定向到此应用程序,它就不会。

代码:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>

#include <string>
#include <string.h> // memset()
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>

#include <linux/ip.h> // For ipv4 header.
#include <linux/udp.h> // For udp header.

#define PORT 27080
#define BUFF_LEN 512

void die(char * error);
void QueryServer(char * ServerIP, char * ServerPort, char * Query, int QueryLen, char * Response, int ResponseSize, int *ResponseLen);

int main() {
    // Create a UDP socket.
    int iSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (iSocket == -1) {
        die((char *) "Unable to create socket");
    }

    struct sockaddr_in sock_structure;

    memset((char *) &sock_structure, 0, sizeof(sock_structure)); // Zero out the structure.

    sock_structure.sin_family = AF_INET;
    sock_structure.sin_port = htons(PORT);
    sock_structure.sin_addr.s_addr = INADDR_ANY;

    // Bind socket to port.
    if (bind(iSocket, (struct sockaddr *) &sock_structure, sizeof(sock_structure)) == -1) {
        die((char *) "Error binding to port");
    }

    // Keep listening for data.
    struct sockaddr_in recvsock_structure;
    socklen_t recvsock_len = sizeof(recvsock_structure);

    // Declare variables for send socket.
    int send_socket;
    struct sockaddr_in send_socket_structure;

    int recv_len = 0;
    char recv_data[BUFF_LEN];

    while (true) {
        recv_len = recvfrom(iSocket, recv_data, BUFF_LEN, 0, (struct sockaddr *) &recvsock_structure, &recvsock_len);
        if (recv_len == -1) {
            die((char *) "Error recieving data");
        }

        // Query server.
        char send_data[BUFF_LEN];
        int send_data_len;
        QueryServer((char *) "SERVERIP", (char *) "SERVERPORT", recv_data, recv_len, send_data, BUFF_LEN, &send_data_len);
        //printf("Sending response to %s:%d : %s\n", inet_ntoa(recvsock_structure.sin_addr), ntohs(recvsock_structure.sin_port), send_data);
        // Send the response.
        if (sendto(iSocket, send_data, send_data_len, 0, (struct sockaddr *) &recvsock_structure, recvsock_len) == -1) {
            die((char *) "Error sending response");
        }
/*
        if (recv_len > 4) {
            switch(recv_data[4]) {
                case 'T' : { // Info query, check cache.
                    // Query server.
                    char send_data[BUFF_LEN];
                    int send_data_len;
                    QueryServer((char *) "SERVERIP", (char *) "SERVERPORT", recv_data, recv_len, send_data, BUFF_LEN, &send_data_len);
                    printf("Recieved data : %s\n", send_data);
                    // Send the response.
                    if (sendto(iSocket, send_data, send_data_len, 0, (struct sockaddr *) &recvsock_structure, recvsock_len) == -1) {
                        die((char *)"Error sending response");
                    }

                    break;
                }
                // Further : not an info query.
                case 'U' : { // PlayerList.
                    break;
                }
                case 'V' : { // Rules
                    break;
                }
                case 'W' : { // GetChallenge
                    break;
                }
                default : { // Other.

                }
            }
        }*/

        //printf("Received packet from %s:%d\n", inet_ntoa(recvsock_structure.sin_addr), ntohs(recvsock_structure.sin_port));
        //printf("Data: %s\n" , recv_data);
    }

    close(iSocket);
}

void QueryServer(char * ServerIP, char * ServerPort, char * Query, int QueryLen, char * Response, int ResponseSize, int *ResponseLen) {
    // Create socket.
    int iSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (iSocket == -1) {
        die((char *) "Unable to create socket");
    }

    // Bind socket to any port.
    struct sockaddr_in sock_structure;
    sock_structure.sin_family = AF_INET;
    sock_structure.sin_addr.s_addr = htonl(INADDR_ANY);
    sock_structure.sin_port = htons(0);

    socklen_t sock_structure_len = sizeof(sock_structure);
    if (bind(iSocket, (struct sockaddr *) &sock_structure, sock_structure_len) == -1) {
        die((char *) "Error binding to port");
    }

    // Query server.
    struct hostent * host;
    host = gethostbyname(ServerIP); // Get server ip address.

    struct sockaddr_in send_sock_structure;
    send_sock_structure.sin_family = host->h_addrtype;
    memcpy((char *) &send_sock_structure.sin_addr.s_addr, host->h_addr_list[0], host->h_length);
    send_sock_structure.sin_port = htons(atoi(ServerPort));

    if (sendto(iSocket, Query, QueryLen, 0, (struct sockaddr *) &send_sock_structure, sizeof(send_sock_structure)) == -1) {
        die((char *) "Error sending data to remote server");
    }

    struct timeval timeout;
    timeout.tv_sec = 3;
    timeout.tv_usec = 0;

    setsockopt(iSocket, SOL_SOCKET, SO_RCVTIMEO, (struct timeval *) &timeout, sizeof(timeout));

    (*ResponseLen) = recvfrom(iSocket, Response, ResponseSize, 0, (struct sockaddr *) &sock_structure, &sock_structure_len);
    if (*ResponseLen == -1) {
        die((char *) "Error recieving data");
    }

    //printf("%s\n", Response);


    close(iSocket);
}

void die(char * error) {
    perror(error);
    exit(1);
}

有人可以指出我做错了吗?

0 个答案:

没有答案