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); }
static void udp_close(int fd, void *data) { struct udp_data *pri = data; CHECK_SOCKET(fd); close(pri->socket); }
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); }
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; }