// Implementation of the main loop of the pirserver, responsible for the // communication with the tor process. All the actual private lookup // work is done by an appropriate subclass of PIRServer. #include #include #include #include #include #include #include "pirserver.h" #define PIRSERVER_LOG_FILE "pirserverlog" #define PIRSERVER_HDR_SIZE 13 #define PIRSERVER_REQUEST_PARAMS 0x01 #define PIRSERVER_REQUEST_STORE 0x02 #define PIRSERVER_REQUEST_LOOKUP 0x03 #define PIRSERVER_RESPONSE_PARAMS 0xFF #define PIRSERVER_RESPONSE_LOOKUP_SUCCESS 0xFE #define PIRSERVER_RESPONSE_LOOKUP_FAILURE 0xFD static int read_all(char *buf, size_t len) { int tot_read = 0; while(len > 0) { int res = read(0, buf, len); if (res <= 0) return res; buf += res; len -= res; tot_read += res; } return tot_read; } static int write_all(const char *buf, size_t len) { int tot_written = 0; while(len > 0) { int res = write(1, buf, len); if (res <= 0) return res; buf += res; len -= res; tot_written += res; } return tot_written; } void PIRServer::mainloop() { FILE *fptr = fopen(PIRSERVER_LOG_FILE, "a"); clock_t start, end, cpu_time; char header[PIRSERVER_HDR_SIZE]; size_t bodylen = 0; char *body = NULL; string query, response; size_t response_len; while(1) { // Read the request from stdin int res = read_all(header, PIRSERVER_HDR_SIZE); if (res <= 0) return; // stdin has reached EOF (or error); we // will terminate bodylen = ntohl(*(uint32_t*)(header+PIRSERVER_HDR_SIZE-4)); if (bodylen > 0) { body = (char *)malloc(bodylen); res = read_all(body, bodylen); if (res <= 0) return; } // We have a complete request. Dispatch it. switch(header[8]) { case PIRSERVER_REQUEST_PARAMS: start = clock(); get_params(response); response_len = response.length(); header[8] = PIRSERVER_RESPONSE_PARAMS; *(uint32_t*)(header+PIRSERVER_HDR_SIZE-4) = htonl(response_len); res = write_all(header, PIRSERVER_HDR_SIZE); if (res <= 0) return; if (response_len > 0) { res = write_all(response.c_str(), response_len); if (res <= 0) return; } end = clock(); fprintf(fptr, "REQUEST_PARAMS,"); break; case PIRSERVER_REQUEST_STORE: if (bodylen >= 32) { start = clock(); string key(body, 32); string value(body+32, bodylen-32); store(key, value); end=clock(); fprintf(fptr, "STORE,"); } break; case PIRSERVER_REQUEST_LOOKUP: start = clock(); query.assign(body, bodylen); if (lookup(query, response)) { response_len = response.length(); header[8] = PIRSERVER_RESPONSE_LOOKUP_SUCCESS; } else { response_len = 0; header[8] = PIRSERVER_RESPONSE_LOOKUP_FAILURE; } *(uint32_t*)(header+PIRSERVER_HDR_SIZE-4) = htonl(response_len); res = write_all(header, PIRSERVER_HDR_SIZE); if (res <= 0) return; if (response_len > 0) { res = write_all(response.c_str(), response_len); if (res <= 0) return; } end = clock(); fprintf(fptr, "LOOKUP,"); break; } cpu_time = end - start; //Time logged in ms fprintf(fptr,"%f\n", ((float)cpu_time/CLOCKS_PER_SEC) * 1000 ); fflush(fptr); // Clean up for the next request. free(body); body = NULL; bodylen = 0; } }