void SocketServer::CreateSocket() throw (JsonRpcException) {
    int yes = 1;
    socket_ = socket(host_info_->ai_family, host_info_->ai_socktype, host_info_->ai_protocol);
    CHECK_SOCKET(socket_);
    CHECK_STATUS(setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)));
    CHECK_STATUS(bind(socket_, host_info_->ai_addr, host_info_->ai_addrlen));
    CHECK_STATUS(listen(socket_, poolSize_));
    return;
error:
    CloseSocket();
    throw JsonRpcException(Errors::ERROR_SERVER_CONNECTOR);
  }
Exemple #2
0
static void udp_close(int fd, void *data)
{
    struct udp_data *pri = data;
    CHECK_SOCKET(fd);
    close(pri->socket);
}
Exemple #3
0
int udp_user_read(int fd, void *buf, int len, struct udp_data *pri)
{
    char buffer[BUF_SIZE], *udpStart = buffer + sizeof(struct iphdr);
    CHECK_SOCKET(fd);

#ifdef INCLUDE_MAC
#error INCLUDE_MAC support does not work
#endif
    const int invalidPacketLen = -1;
    struct sockaddr_in srcAddr;
    int srcAddrLen = sizeof(struct sockaddr_in);
    int rcv_packet_len = invalidPacketLen;
    __u32 srcIP;

    if ((rcv_packet_len = recvfrom(fd, udpStart, BUF_SIZE, 0,
                                   (struct sockaddr *) & srcAddr, &srcAddrLen)) <= 0) {
        //DEBUG(1, "recvfrom");
        return 0;
    }
    srcIP = srcAddr.sin_addr.s_addr;

    if(rcv_packet_len > 0) {
        DEBUG(2,"Packet recv'd(%d); need to perform unwrap operation\n",
              rcv_packet_len);
        /* XXX Copy unwrap code from kernel-level skbuff reorg stuff
         * */
        struct ipudp *iuh = (struct ipudp *)udpStart;
        char *dataStart = (char*)(iuh + 1);
        struct iphdr *iph = ((struct iphdr*)dataStart) - 1;
        struct tcphdr *th = (struct tcphdr *)dataStart;

        int cookedLen = rcv_packet_len - sizeof(struct ipudp) +
                        sizeof(struct iphdr);

        if(cookedLen < sizeof(struct tcphdr)) {
            printk("Cooked length is shorter than minimum tcp "
                   "header len\n");
            return 0;
        }

        __u16 origCheck = th->check;
        // This code does NOT respect the ipudp src and dest addresses
        // Remove UDP header; push on IP header
        if(iuh->saddr != srcIP) {
#ifndef SUPPORT_NAT
            addrPrintComp("IPUDP header src did not match addr",
                          "!=",iuh->saddr, srcIP);
            return 0;
#else
            // th->check adjustment needed
            th->check =
                ip_nat_cheat_check(~iuh->saddr, srcIP,
                                   th->check);
#endif
        }

        if(iuh->daddr != pri->local_addr) {
#ifndef SUPPORT_NAT
            addrPrintComp("IPUDP header dest did not match addr",
                          "!=",iuh->daddr, pri->local_addr);
            return 0;
#else
            // th->check adjustment needed
            th->check =
                ip_nat_cheat_check(~iuh->daddr, pri->local_addr,
                                   th->check);
#endif
        }

        int ihl = sizeof(*iph);

        iph->version = 4;
        iph->ihl = ihl / 4;
        iph->tos = 0;
        iph->tot_len = htons(cookedLen);
        static int ip_id = 0;
        iph->id = ip_id++;
        iph->frag_off = 0;
        iph->ttl = 255;
        iph->protocol = IPPROTO_TCP;
        iph->check = 0;
#ifdef SUPPORT_NAT
        iph->saddr = srcIP;
        iph->daddr = pri->local_addr;
#else
        iph->saddr = iuh->saddr;
        iph->daddr = iuh->daddr;
#endif
        iph->check = ip_compute_csum((unsigned char *)iph, ihl);

        // XXX should copy protocol from an ipudp field
        DEBUG(2,"Returning cooked length %d, "
              "origCheck = %d, newCheck = %d\n",
              cookedLen, origCheck, th->check);
        DEBUG_GUARD(2, printk("IPH: "); hexdump((char*)iph, ihl) );

        memcpy(buf, (char*)iph, cookedLen);
        return(cookedLen);
    }
Exemple #4
0
int main(int argc, char * argv[]) {
	SOCKET sock, clientSock;
	struct sockaddr_in addr;
	struct sockaddr clientAddr;
	char buffer[BUFFER_SIZE];
	int clientAddrSize = 0, readBytes = 0;
	WoopsaServer server;
	WoopsaBufferSize responseLength;

	memset(buffer, 0, sizeof(buffer));
	WoopsaServerInit(&server, "/woopsa/", woopsaEntries, ServeHTML);

	printf("Woopsa C library v0.1 demo server.\n");

	if (sockInit() != 0) {
		printf("Error initializing sockets\n");
		EXIT_ERROR();
	}

	sock = socket(AF_INET, SOCK_STREAM, 0);
	if (!CHECK_SOCKET(sock)) {
		printf("Error creating socket\n");
		EXIT_ERROR();
	}

	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = INADDR_ANY;
	addr.sin_port = htons(WOOPSA_PORT);

	if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
		printf("Error binding socket\n");
		EXIT_ERROR();
	}

	listen(sock, 5);
	printf("Server listening on port %d\n", WOOPSA_PORT);

	while (1) {
		clientAddrSize = sizeof(struct sockaddr_in);
		clientSock = accept(sock, &clientAddr, &clientAddrSize);
		if (!CHECK_SOCKET(clientSock)) {
			printf("Received an invalid client socket.\n");
			EXIT_ERROR();
		}

		while (1) {
			readBytes = recv(clientSock, buffer + readBytes, sizeof(buffer), 0);

			if (readBytes == SOCKET_ERROR) {
				printf("Error %d", WSAGetLastError());
				break;
			}

			if (readBytes == 0) {
				printf("Finished\n");
				break;
			}

			if (WoopsaCheckRequestComplete(&server, buffer, sizeof(buffer)) != WOOPSA_REQUEST_COMLETE) {
				// If the request is not complete, it means more data needs 
				// to be -added- to the buffer
				continue;
			}

			if (WoopsaHandleRequest(&server, buffer, sizeof(buffer), buffer, sizeof(buffer), &responseLength) >= WOOPSA_SUCCESS) {
				send(clientSock, buffer, responseLength, 0);
			}
			readBytes = 0;
			memset(buffer, 0, sizeof(buffer));
		}
	}

	if (sockClose(sock) != 0) {
		printf("Error closing socket\n");
		EXIT_ERROR();
	}

	if (sockQuit() != 0) {
		printf("Error quitting sockets\n");
		EXIT_ERROR();
	}

	getchar();

	return 0;
}