int send_file(char *path, long IPaddr, uuid_t *uuids, uint64_t num_uuids, int PN) { FILE *fp = fopen(path,"r"); char block[DEFAULT_BLOCK_SIZE]; int i=0; fseek(fp,0,SEEK_SET); while(!feof(fp)) { char *msg = 0, *err_msg_string = 0; uint64_t msg_len; int num; uuid_t uuid; char *resp_msg = 0; ErrorCode error; struct Node* resp; if(i>=num_uuids) { printf("Not enough uuids\n"); fclose(fp); return 0; } else { memset(block,0,sizeof(block)); num = fread(block, 1, DEFAULT_BLOCK_SIZE, fp); create_msg_post_block_request(uuids[i], num, block, &msg, &msg_len); error = mysend(msg, IPaddr, PN, msg_len); if(error == FAILURE || error == RETRY) { printf("error in send"); free(msg); fclose(fp); return 0; } else { resp = myrecv(CLIENT_PORT); resp_msg = resp->message; if(get_header_type(resp_msg) == BACS_ERROR) { parse_msg_error(resp_msg, &err_msg_string); printf("%s\n",err_msg_string); fclose(fp); return 0; } else parse_msg_post_block_response(resp_msg, &uuid); } free(err_msg_string); free(resp->message); free(resp); free(msg); } i++; } printf("\nFile uploaded successfully\n"); fclose(fp); return 1; }
void make_dir(char* dir, bool l, char* path, unsigned long IPaddr, int PN) { if(l==0) { char dirpath[1024]; int result; strcpy(dirpath,path); strcat(dirpath,"/"); strcat(dirpath,dir); /* printf("dirpath:%s\n",dirpath);*/ result = mkdir(dirpath, 0777); if(result==0) printf("Local directory '%s' created at path: %s\n", dir, path); else perror("mkdir() error"); } else { char* msg = 0, * resp_msg = 0, *err_msg_string = 0; uint64_t msg_len; ErrorCode error; struct Node* resp; char dirpath[1024]; strcpy(dirpath,path); if(strcmp(path,"/")!=0) strcat(dirpath,"/"); strcat(dirpath,dir); create_msg_post_folder_request(dirpath, &msg, &msg_len); error = mysend(msg, IPaddr, PN, msg_len); free(msg); if(error == FAILURE || error == RETRY) { printf("error in send\n"); return; } resp = myrecv(CLIENT_PORT); resp_msg = resp->message; if(get_header_type(resp_msg) == BACS_ERROR) { parse_msg_error(resp_msg, &err_msg_string); printf("%s\n",err_msg_string); free(err_msg_string); free(resp->message); free(resp); return; } parse_msg_post_folder_response(resp_msg); printf("Remote directory '%s' created at path: %s\n", dir, path); free(err_msg_string); free(resp->message); free(resp); } }
static int sendf(int fd, const char *fmt, ...) { char buf[1024]; int ret; va_list ap; va_start(ap, fmt); int n = vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); ret = mysend(fd, buf, n); return ret; }
/* Send one file. */ static void get_file(int s, char *url) { /* Set www_dir to point to your web directory. */ char *www_dir = NULL; char bufo[512]; int n, w; const char *mime = NULL; const char *p = url + 1; if (*p == 0) p = "index.html"; char *p2 = strrchr(p, '.'); if (p2) { p2++; if (!strcmp(p2, "html")) mime = "text/html"; else if (!strcmp(p2, "htm")) mime = "text/html"; else if (!strcmp(p2, "css")) mime = "text/css"; else if (!strcmp(p2, "txt")) mime = "text/plain"; else if (!strcmp(p2, "png")) mime = "image/png"; else if (!strcmp(p2, "jpg")) mime = "image/jpg"; else if (!strcmp(p2, "class")) mime = "application/x-java-applet"; else if (!strcmp(p2, "jar")) mime = "application/java-archive"; else if (!strcmp(p2, "pdf")) mime = "application/pdf"; else if (!strcmp(p2, "swf")) mime = "application/x-shockwave-flash"; else if (!strcmp(p2, "ico")) mime = "image/vnd.microsoft.icon"; else if (!strcmp(p2, "js")) mime = "text/javascript"; } www_dir = getenv("www_dir"); snprintf(bufo, sizeof(bufo), "%s/%s", www_dir, p); FILE *f = fopen(bufo, "rb"); if (!f) { sendf(s, "HTTP/1.0 404 NOK\r\n\r\n"); return; } sendf(s, "HTTP/1.0 200 OK\r\n"); if (mime) sendf(s, "Content-Type: %s\r\n\r\n", mime); else sendf(s, "\r\n"); while ((n = fread(bufo, 1, sizeof(bufo), f)) > 0) if ((w = mysend(s, bufo, n)) < 0) break; fclose(f); }
void download_folder(char* file_name, char* local_path, char* remote_path, unsigned long IPaddr, int PN) { char local_temp[1024], remote_temp[1024]; char* msg = 0, * resp_msg = 0, *err_msg_string = 0; uint64_t msg_len; uint32_t num_metas; int i; basic_meta_t *basic_metas = 0; ErrorCode error; struct Node* resp; strcpy(local_temp, local_path); strcpy(remote_temp, remote_path); make_dir(file_name, 0, local_path, IPaddr, PN); change_dir(file_name, local_temp, 0, IPaddr, PN); change_dir(file_name, remote_temp, 1, IPaddr, PN); create_msg_get_folder_meta_request(remote_temp, &msg, &msg_len); error = mysend(msg, IPaddr, PN, msg_len); free(msg); if(error == FAILURE || error == RETRY) { printf("error in send\n"); return; } resp = myrecv(CLIENT_PORT); resp_msg = resp->message; if(get_header_type(resp_msg) == BACS_ERROR) { parse_msg_error(resp_msg, &err_msg_string); printf("%s",err_msg_string); free(resp->message); free(resp); free(err_msg_string); return; } parse_msg_get_folder_meta_response(resp_msg, &basic_metas, &num_metas); free(resp->message); free(resp); free(err_msg_string); for(i=0; i < num_metas; i++) { if(strcmp(basic_metas[i].name,".")!=0 && strcmp(basic_metas[i].name,"..")!=0) download_file(basic_metas[i].name, local_temp, remote_temp, IPaddr, PN); //free(basic_metas[i].name); } free(basic_metas); /*download file complete*/ printf("Directory downloaded to path: %s\n",local_path); }
void sendtofics(int fd, char *buff, int *rd) { static int c=0; for(;c<*rd;c++) if(buff[c]=='\n') { char ffub[BSIZE+20]; int k; memcpy(ffub,buff,c); k=crypt(ffub,c); mysend(fd,ffub,k); for(c++,k=0;c<*rd;c++,k++) buff[k]=buff[c]; *rd=k; c=-1; } }
dove::Nub::SOCKETSTATUS Nub::sendMsg(char * data,int len,char* & outdata,int& outlen) { outdata = data; outlen = len; if(len ==0) return STATUS_SENDALL; int sendLen = mysend(fd_,data,len,0); if(sendLen == -1) { if(errno == EAGAIN) return STATUS_SENDPART; return STATUS_SENDERROR; } data += sendLen; len -= sendLen; return sendMsg(data,len,outdata,outlen); }
void getfromfics(int fd, char *buff, int *rd) { int n, m, got_g = 0; while(*rd > 0) { for(n=0; n<*rd && buff[n]!='\r'; n++) { if (buff[n] == '\0' && n >= 3 && !strncmp(buff + n - 3, "[G]",3)) { char reply[20]="\x2""9"; for(n++; n < *rd; n++) { buff[n-4] = buff[n]; } *rd -= 4; n = crypt(reply,2); mysend(fd, reply, n); got_g = 1; break; } } if (got_g) { got_g = 0; continue; } if(n<*rd) n++; if (write(1, buff, n) != n) { printf("error writing to stdout (%d)\n", WSAGetLastError()); exit(1); } for (m = n; m < *rd; m++) { buff[m - n] = buff[m]; } *rd -= n; } }
/* Thread per sessione di connessione */ static void *Session (void *p) { int clifd; /* Socket Client-Proxy */ int servfd; /* Socket Proxy-Server */ int ris; /* Utili */ struct Request req; /* Conterrà le informazioni per forward e prefetch */ struct Response resp; /* Conterrà info per invio file cache, struttura richiesta da prepareResponse ecc */ char cache_filename[MAXLENPATH]; char error_response[16]; char buffer[MAXLENRESP]; int buffer_len; struct sockaddr_in Local, Serv; /* Per connessione con il server */ /* Client socket Timeout */ struct timeval timercli; timercli.tv_sec = INACTIVITY_TIMEOUT_SECONDS; timercli.tv_usec = 0; /* Estrazione informazioni parametro thread */ clifd = ((struct param*)p)->fd; free(p); p = NULL; /* Controllo sul numero dei thread */ pthread_mutex_lock(&mutex_num); if(numthread < MAXNUMTHREADWORKING) numthread++; pthread_mutex_unlock(&mutex_num); if(numthread >= MAXNUMTHREADWORKING) { close(clifd); exitThread(); return(NULL); } #ifdef DEBUG printf("Thread: %ld. Client FD passato: %d\n", pthread_self(), clifd); fflush(stdout); #endif /* Imposto il timeout per questo socket client */ setsockopt(clifd, SOL_SOCKET, SO_RCVTIMEO, &timercli, sizeof(struct timeval)); setsockopt(clifd, SOL_SOCKET, SO_SNDTIMEO, &timercli, sizeof(struct timeval)); /* Inizializzo struttura per richiesta */ initRequest(&req); /* Prelevo la richiesta ed estraggo le informazioni. Se a buon fine l'avrò tutta in req->buf, mentre il resto sarà estratto e messo negli altri campi di req. */ ris = getRequest(clifd,&req); switch(ris) { case -3: /* Client ha chiuso la connessione */ #ifdef DEBUG printf("Thread: %ld. Client ha chiuso connessione. \nBuffer: %s\n", pthread_self(), req.buf); fflush(stdout); #endif close(clifd); exitThread(); return(NULL); break; case -2: /* Errore in lettura, chiudo thread e connessione */ #ifdef DEBUG printf("Thread: %ld. Errore in lettura client request. \nBuffer: %s\n", pthread_self(), req.buf); fflush(stdout); #endif close(clifd); exitThread(); return(NULL); break; case -1: /* Lettura richiesta terminata, formato richiesta sbagliato */ strcpy(error_response, "403\n\n"); mysend(clifd, error_response, strlen(error_response)); #ifdef DEBUG printf("Thread: %ld. Lettura req terminata, formato richiesta sbagliato. \nBuffer: %s\n", pthread_self(), req.buf); fflush(stdout); #endif close(clifd); exitThread(); return(NULL); break; case 1: /* Lettura richiesta OK -> proseguo */ #ifdef DEBUG printf("Thread: %ld. Lettura req OK. \nBuffer: %s\n", pthread_self(), req.buf); fflush(stdout); #endif break; default: /* Errore sconosciuto */ strcpy(error_response, "402\n\n"); mysend(clifd, error_response, strlen(error_response)); #ifdef DEBUG printf("Thread: %ld. Errore sconosciuto. \nBuffer: %s\n", pthread_self(), req.buf); fflush(stdout); #endif close(clifd); exitThread(); return(NULL); break; } /* Switch */ /* Ora ho nella struttura Request tutte le informazioni che mi servono */ /* Tentativi connessione server */ int servconn_chance = SERVER_CHANCE; /* Ogni qualvolta ritento una connessione con il server per errori, ricontrollo di avere il file in cache, qualche altro thread potrebbe averlo salvato nel frattempo. */ while (1) { #ifdef DEBUG printf("Controllo su thread: %ld. While session().\n", pthread_self()); fflush(stdout); #endif /* Se ha fatto una richiesta GET e ho il file in cache */ if ((req.reqType == GET) && (get_cache_name(&(req.inaddr), req.port, req.path, cache_filename))) { /* Cerco di preparare la risposta da mandare (Anche con RANGE), l'eventuale contenuto del file è nel buffer di resp */ ris = prepareGetResponse(&req, &resp, cache_filename); #ifdef DEBUG printf("Thread: %ld. La req è GET e ho il file in cache. \nFile: %s\n", pthread_self(), resp.buf); fflush(stdout); #endif switch(ris) { case 1: ris = mysend(clifd, resp.buf, resp.lenresp); /* caso OK ------> MANDO AL CLIENT IL FILE CHE ERA IN CACHE e chiudo */ if (ris == -1) { printf ("Error on cached file response send.\n"); fflush(stdout); } if (ris == -2) { printf ("Time out on cached file response send.\n"); fflush(stdout); } if (ris == 0) { printf ("Client closed connection before sending cached file.\n"); fflush(stdout); } else { printf ("Cached file sent to client.\n"); fflush(stdout); } close(clifd); exitThread(); return(NULL); break; case -3: /* file not found (expired nel frattempo) ---> faccio la richiesta */ #ifdef DEBUG printf("Thread: %ld. Avevo il file ma è expired. \n", pthread_self()); fflush(stdout); #endif break; case -4: /* interval not found -----> lo notifico */ strcpy(error_response, "405\n\n"); mysend(clifd, error_response, strlen(error_response)); #ifdef DEBUG printf("Thread: %ld. Avevo il file ma il RANGE è sbagliato. \n", pthread_self()); fflush(stdout); #endif close(clifd); exitThread(); return(NULL); break; case -5: /* unknown error */ default: strcpy(error_response, "402\n\n"); mysend(clifd, error_response, strlen(error_response)); #ifdef DEBUG printf("Thread: %ld. Avevo il file ma dopo la prepareResponse errore sconosciuto.\n", pthread_self()); fflush(stdout); #endif close(clifd); exitThread(); return(NULL); break; } } /* Fine GET e ho il file in cache */ /* Non ho file in cache oppure richiesta INF -> Forward richiesta al server e poi discrimino in base a GET (prefetch) e INF (solo forward risposta) */ servfd = socket(AF_INET, SOCK_STREAM, 0); if (servfd < 0) { printf("Thread: %ld. Chiamata a socket() per serverfd fallita. Errore: %d \"%s\"\n", pthread_self(), errno,strerror(errno)); fflush(stdout); close(clifd); exitThread(); return(NULL); } /* Server socket Timeout */ struct timeval timerserv; timerserv.tv_sec = INACTIVITY_TIMEOUT_SECONDS; timerserv.tv_usec = 0; if ((SetsockoptReuseAddr(servfd) == 0) || (setsockopt(servfd, SOL_SOCKET, SO_RCVTIMEO, &timerserv, sizeof(struct timeval)) != 0) || (setsockopt(servfd, SOL_SOCKET, SO_SNDTIMEO, &timerserv, sizeof(struct timeval)) != 0)) { printf("Thread: %ld. Error on a setsockopt for server socket\n", pthread_self()); fflush(stdout); close(servfd); close(clifd); exitThread(); return(NULL); } /* Binding */ memset(&Local, 0, sizeof(Local)); Local.sin_family = AF_INET; Local.sin_addr.s_addr = INADDR_ANY; Local.sin_port = htons(0); ris = bind(servfd, (struct sockaddr *)&Local, sizeof(Local)); if (ris < 0) { printf("Thread: %ld. Chiamata a bind() per serverfd fallita. Errore: %d \"%s\"\n", pthread_self(), errno,strerror(errno)); fflush(stdout); close(servfd); exitThread(); return(NULL); } /* Compilo campi server */ memset(&Serv, 0, sizeof(Serv)); Serv.sin_family = AF_INET; Serv.sin_addr.s_addr = req.inaddr.s_addr; Serv.sin_port = htons(req.port); #ifdef DEBUG printf ("Thread: %ld, %d° tentativo connessione con server. FD: %d\n", pthread_self(), (SERVER_CHANCE-servconn_chance+1), servfd); fflush(stdout); #endif int repeat; repeat = 0; while (1) { #ifdef DEBUG printf("Controllo su thread: %ld. While connect session.\n", pthread_self()); fflush(stdout); #endif ris = connect (servfd, (struct sockaddr *)&Serv, sizeof(Serv)); if (ris < 0) { if ((errno == EINTR) || (errno == EINPROGRESS)) ; /* Ritento */ if (errno == EISCONN) { printf("Thread: %ld, Chiamata a connect() per serverfd fallita. FD: %d. Errore: %d \"%s\"\n", pthread_self(), servfd, errno,strerror(errno)); fflush(stdout); repeat = 0; break; } else { printf("Thread: %ld, Chiamata a connect() per serverfd fallita. FD: %d. Errore: %d \"%s\"\n", pthread_self(), servfd, errno,strerror(errno)); fflush(stdout); if (servconn_chance > 0) servconn_chance--; /* Ritento */ else { printf("Thread: %ld, Chiamata a connect() per serverfd fallita. FD: %d. Errore: %d \"%s\"\n", pthread_self(), servfd, errno,strerror(errno)); fflush(stdout); close(servfd); exitThread(); return(NULL); } /* Ritento nuovo socket */ repeat = 1; break; } /* Errore non recuperabile */ } /* Error on connect */ else { /* OK */ repeat = 0; break; } } /* Connect while */ /* Se è il caso torno indietro */ if (repeat) continue; /* Forwardo la richiesta, qualunque essa sia (inf/get) */ #ifdef DEBUG printf("Thread: %ld. Forward richiesta del client al server.\n Req: %s\n", pthread_self(), req.buf); fflush(stdout); #endif ris = mysend(servfd, req.buf, strlen(req.buf)); if (ris < 0) { #ifdef DEBUG printf("Thread: %ld. Errore su forward req.\n", pthread_self()); fflush(stdout); #endif if (servconn_chance > 0) { servconn_chance--; close(servfd); continue; /* Chiudo questa connessione e ritento */ } else { close(clifd); close(servfd); exitThread(); return(NULL); } } /* Aspetto la risposta del server */ ris = myread(servfd, buffer, MAXLENRESP); if (ris <= 0) { #ifdef DEBUG printf("Thread: %ld. Errore in risposta server a forward req del client.\nErrore: %d \"%s\"\n", pthread_self(), errno,strerror(errno)); fflush(stdout); #endif if (servconn_chance > 0) { servconn_chance--; close(servfd); continue; /* Chiudo questa connessione e ritento */ } else { close(clifd); close(servfd); exitThread(); return(NULL); } } #ifdef DEBUG printf("Thread: %ld. OK arrivo risposta dal server per forward al client.\n Resp: %s\n", pthread_self(), buffer); fflush(stdout); #endif /* Concludo chiusura con server */ close(servfd); /* Terminatore */ buffer[ris] = '\0'; buffer_len = ris; /* Controllo errori 40X nel qual caso forwardo e chiudo */ if ((!(strncmp(buffer,"402\n\n",5))) || (!(strncmp(buffer,"403\n\n",5))) || (!(strncmp(buffer,"404\n\n",5))) || (!(strncmp(buffer,"405\n\n",5)))) { #ifdef DEBUG printf("Thread: %ld. Server ha inviato un errore 40X, faccio forward al Client", pthread_self()); fflush(stdout); #endif ris = mysend(clifd, buffer, buffer_len); close(clifd); exitThread(); return(NULL); } /* Se la richiesta era INF faccio un parsing per INF e invio a client */ if (req.reqType == INF) { /* Corretto */ if (parseINF(buffer, buffer_len) == 0){ ris = mysend(clifd, buffer, buffer_len); if (ris < 0) /* Errore irreparabile col client */ #ifdef DEBUG printf("Thread: %ld. Errore in risposta a Client (dopo arrivo dal server).\n Errore: %d \"%s\"\n", pthread_self(), errno,strerror(errno)); fflush(stdout); #endif close(clifd); exitThread(); return(NULL); } /* Errato */ else continue; /* Ritento */ } /* Se la richiesta era GET per RANGE faccio il parsing per RANGE e poi invio il file */ if (req.is_range) { /* Corretto */ if (parseRANGE(buffer, buffer_len) == 0) ; /* Vado comunque a fare il parsing per fare prefetch sugli URL che trovo */ /* Errato */ else continue; /* Ritento */ } int expire; char cachename[MAXLENPATH]; struct timeval tod; /* Se invece la richiesta era GET per file completo prima faccio parsing per GET completo. Se corretto salvo il file (così è a disposizione di altri thread) e poi invio a client */ if (!(req.is_range)) { #ifdef DEBUG printf("Thread: %ld. Prelevo nome per caching.\n", pthread_self()); fflush(stdout); #endif /* Prelevo nome univoco */ my_tempname(cachename); #ifdef DEBUG printf("Thread: %ld. Salvo file caching.\n", pthread_self()); fflush(stdout); #endif /* SE CORRETTO E COMPLETO salvo file appena scaricato in cache e prelevo expire */ expire = buffer_data_to_file (cachename, buffer, buffer_len); /* Non completo / Corrotto */ if (expire < 0) { #ifdef DEBUG printf("Thread: %ld. Il file arrivato è corrotto.\nEcco il file:\n", pthread_self()); fflush(stdout); #endif write(1, buffer, MAXLENRESP); fflush(stdout); continue; /* Ritento da capo connessione con server e richiesta */ } else { /* Prendo tempo attuale da sommare al tempo di expire del file appena ricevuto */ gettimeofday(&tod, NULL); /* Gestione cache, aggiunta file */ add_file_cache(&(req.inaddr), req.port, req.path, (tod.tv_sec + expire), cachename); } } /* Ora ho nel buffer ciò che devo inviare a Client e in ogni caso faccio lo stesso tipo di invio */ ris = mysend(clifd, buffer, buffer_len); if (ris < 0) { /* Errore irreparabile col client */ #ifdef DEBUG printf("Thread: %ld. Errore in risposta a Client (dopo arrivo dal server).\n Errore: %d \"%s\"\n", pthread_self(), errno,strerror(errno)); fflush(stdout); #endif close(clifd); exitThread(); return(NULL); } #ifdef DEBUG printf("Thread: %ld. OK risposta dopo arrivo file del Server verso Client.\n Resp: %s\n", pthread_self(), buffer); fflush(stdout); #endif /* In ogni caso ho finito col client */ close(clifd); /* Inizializzo qui, ma viene modificato nel parsing per scorrere il buffer con la risposta */ int lenparsed = 0; struct Request *p_prefetch_req; char tmpname[MAXLENPATH]; #ifdef DEBUG printf("Thread: %ld. Fase prefetching.\n", pthread_self()); fflush(stdout); #endif while(1) { #ifdef DEBUG printf("Controllo su thread: %ld. While parse session().\n", pthread_self()); fflush(stdout); #endif /* Struttura Request per fare richiesta al server, già passabile come parametro a thread */ p_prefetch_req = (struct Request *) malloc (sizeof(struct Request)); if (p_prefetch_req == NULL){ #ifdef DEBUG printf("Thread: %ld. Errore in allocazione p_prefetch_req.\n", pthread_self()); fflush(stdout); #endif exitThread(); return(NULL); } /* Chiamo il parsing saltando almeno il minimo numero di byte che possono esserci prima dei dati. NB: USO CAMPO "buf[]" della struttura Request per l'URL!! NB2: Chiedo sia REF che IDX;REF per 1° e 2° livello */ #ifdef DEBUG printf("Thread: %ld. Fase parsing del buffer.\n", pthread_self()); fflush(stdout); #endif ris = parse((buffer+MIN_BYTE_BEFORE_DATA), &lenparsed, (buffer_len-MIN_BYTE_BEFORE_DATA), p_prefetch_req, FIRST_SECOND_LEVEL_PREFETCHING); /* Parsing finito, per errori o fine buffer */ if(ris <= 0) { exitThread(); return(NULL); } else if(ris == 1) { #ifdef DEBUG printf("Thread: %ld. OK parsing, URL estratto: %s.\n", pthread_self(), p_prefetch_req->buf); fflush(stdout); #endif /* Thread che fanno prefetch su REF - IDX+REF */ pthread_attr_t attr; pthread_attr_init(&attr); pthread_t threadID; pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); /* Se ho già il file passo al prossimo URL */ if(get_cache_name(&(p_prefetch_req->inaddr), p_prefetch_req->port, p_prefetch_req->path, tmpname)) { free(p_prefetch_req); p_prefetch_req = NULL; continue; } /* Altrimenti setto il campo reqType della struttura Request che uso come parametro al thread, impostandolo per il prefetching di primo e secondo livello.. */ p_prefetch_req->reqType = FIRST_SECOND_LEVEL_PREFETCHING; /* .. e faccio partire il thread relativo alla sessione di prefetching per URL specificato in p_prefetch_req->buf[] */ ris = pthread_create(&threadID, &attr, get_and_cache, (void *)p_prefetch_req); if(ris != 0) { printf("Thread: %ld. Chiamata a pthread_create() fallita.\n Errore: %d \"%s\"\n", pthread_self(), errno,strerror(errno)); fflush(stdout); continue; } } } /* while del parsing */ } /* While socket/binding */ } /* Session ****************/
void download_file(char* file_name, char* local_path, char* remote_path, unsigned long IPaddr, int PN) { FILE *fp; char local_file[1024]; char remote_file[1024]; char *msg = 0; uint64_t msg_len; basic_block_t *blocks = 0; uint64_t num_blocks; int i; ErrorCode error; struct Node* resp; char * resp_msg = 0, *err_msg_string = 0; strcpy(local_file,local_path); strcat(local_file,"/"); strcat(local_file,file_name); strcpy(remote_file,remote_path); if(strcmp(remote_path,"/")!=0) strcat(remote_file,"/"); strcat(remote_file,file_name); printf("Downloading file '%s'..\n", file_name); create_msg_get_file_request(remote_file, &msg, &msg_len); error = mysend(msg, IPaddr, PN, msg_len); free(msg); if(error == FAILURE || error == RETRY) { printf("error in send\n"); return; } resp = myrecv(CLIENT_PORT); resp_msg = resp->message; if(get_header_type(resp_msg) == BACS_ERROR) { parse_msg_error(resp_msg, &err_msg_string); printf("%s\n",err_msg_string); free(resp->message); free(resp); free(err_msg_string); return; } parse_msg_get_file_response(resp_msg, &blocks, &num_blocks); /*printf("UUIDS received: ");*/ for(i=0; i<num_blocks; i++) { char *str = uuid_str(blocks[i].uuid); /*printf(" - %s\n", str);*/ free(str); } fp = fopen(local_file, "w"); free(resp->message); free(resp); free(err_msg_string); for(i=0; i<num_blocks; i++) { char *msg = 0, *resp_msg = 0, *err_msg_string = 0; uuid_t uuid; uint32_t size; char *content = 0; ErrorCode error; struct Node* resp; create_msg_get_block_request(blocks[i].uuid, &msg, &msg_len); /*printf("in client\n"); print_msg(msg);*/ error = mysend(msg, IPaddr, PN, msg_len); free(msg); if(error == FAILURE || error == RETRY) { printf("error in send\n"); free(blocks); close(fp); return; } resp = myrecv(CLIENT_PORT); resp_msg = resp->message; if(get_header_type(resp_msg) == BACS_ERROR) { parse_msg_error(resp_msg, &err_msg_string); printf("%s\n",err_msg_string); /*char *str = uuid_str(blocks[i].uuid); printf(" - %s\n", str); free(str);*/ free(resp->message); free(resp); free(err_msg_string); free(blocks); close(fp); return; } parse_msg_get_block_response(resp_msg, &uuid, &size, &content); fwrite (content, sizeof(char), size, fp); free(content); free(resp->message); free(resp); free(err_msg_string); } printf("File downloaded to path: %s\n",local_path); fclose(fp); free(blocks); }
bool upload_file(char* file_name, char* local_path, char* remote_path, unsigned long IPaddr, int PN) { char filepath[1024]; struct stat st; uint64_t size; char *msg = 0, *resp_msg = 0, *err_msg_string = 0; uint64_t msg_len; uuid_t *uuids = 0; uint64_t num_uuids; ErrorCode error; struct Node* resp; printf("...Uploading file '%s'...\n", file_name); strcpy(filepath,local_path); strcat(filepath,"/"); strcat(filepath,file_name); if(stat(filepath, &st)==0) { size = st.st_size; /* printf("*********************************size= %d\n", size);*/ if(size == 0) { printf("File empty. Cannot be uploaded\n"); return 0; } } else { perror("size error: "); return 0; } memset(filepath, 0, 1024); strcpy(filepath,remote_path); if(strcmp(remote_path,"/")!=0) strcat(filepath,"/"); strcat(filepath,file_name); create_msg_post_file_request(filepath, size, &msg, &msg_len); /*mysend(msg, ...) */ error = mysend(msg, IPaddr, PN, msg_len); free(msg); if(error == FAILURE || error == RETRY) { printf("error in send\n"); return 0; } resp = myrecv(CLIENT_PORT); resp_msg = resp->message; if(get_header_type(resp_msg) == BACS_ERROR) { parse_msg_error(resp_msg, &err_msg_string); printf("%s\n",err_msg_string); free(err_msg_string); free(resp->message); free(resp); return 0; } parse_msg_post_file_response(resp_msg, &uuids, &num_uuids); int i; for(i=0; i<num_uuids; i++) { char *str = uuid_str(uuids[i]); /*printf(" - %s\n", str);*/ free(str); } free(err_msg_string); free(resp->message); free(resp); if(num_uuids==0) { printf("***************error num_uuids\n"); free(uuids); return 0; } bool success; memset(filepath, 0, 1024); strcpy(filepath,local_path); strcat(filepath,"/"); strcat(filepath,file_name); success = send_file(filepath, IPaddr, uuids, num_uuids, PN); if(success == 0) { free(uuids); return 0; } free(uuids); return 1; }
bool change_dir(char* dir, char* path, bool l, unsigned long IPaddr, int PN) { if(l==0) { char dirpath[1024]; int result; memset(dirpath, 0, 1024); if(strcmp(path,"/")==0 && strcmp(dir,"..")==0) strcpy(dirpath,path); else if(strcmp(dir,"..")!=0 && strcmp(path,"/")!=0) { strcpy(dirpath,path); strcat(dirpath,"/"); strcat(dirpath,dir); } else if(strcmp(dir,"..")!=0 && strcmp(path,"/")==0) { strcpy(dirpath,path); strcat(dirpath,dir); } else if(strcmp(path,"/")!=0) { char** tokens; tokens = str_split(path, '/'); if (tokens) { int i; for (i = 0; *(tokens + i); i++); if(i!=1) { int j; for (j = 0; j<i-1; j++) { strcat(dirpath,"/"); strcat(dirpath,*(tokens + j)); free(*(tokens + j)); } } else strcpy(dirpath,"/"); free(tokens); } } else strcpy(dirpath,"/"); result = chdir(dirpath); if(result==0) { memset(path, 0, 1024); strcpy(path, dirpath); printf("New local path: '%s'\n", path); } else { perror("cd() error"); return 1; } } else { char dirpath[1024]; char* msg = 0; uint64_t msg_len; uint32_t num_metas; int i; basic_meta_t *basic_metas = 0; ErrorCode error; char* resp_msg =0, *err_msg_string = 0; struct Node* resp; memset(dirpath, 0, 1024); if(strcmp(path,"/")==0 && strcmp(dir,"..")==0) strcpy(dirpath, path); else if(strcmp(dir,"..")!=0 && strcmp(path,"/")!=0) { strcpy(dirpath,path); strcat(dirpath,"/"); strcat(dirpath,dir); } else if(strcmp(dir,"..")!=0 && strcmp(path,"/")==0) { strcpy(dirpath,path); strcat(dirpath,dir); } else if(strcmp(path,"/")!=0) { char** tokens; tokens = str_split(path, '/'); if (tokens) { int i; for (i = 0; *(tokens + i); i++); if(i!=1) { int j; for (j = 0; j<i-1; j++) { strcat(dirpath,"/"); strcat(dirpath,*(tokens + j)); free(*(tokens + j)); } } else strcpy(dirpath,"/"); free(tokens); } } else strcpy(dirpath,"/"); /* printf("dirpath:%s\n",dirpath); */ create_msg_get_folder_meta_request(dirpath, &msg, &msg_len); error = mysend(msg, IPaddr, PN, msg_len); free(msg); if(error == FAILURE || error == RETRY) { printf("error in send\n"); return 1; } resp = myrecv(CLIENT_PORT); resp_msg = resp->message; if(get_header_type(resp_msg) == BACS_ERROR) { parse_msg_error(resp_msg, &err_msg_string); printf("%s\n",err_msg_string); free(err_msg_string); free(resp->message); free(resp); return 1; } parse_msg_get_folder_meta_response(resp_msg, &basic_metas, &num_metas); free(err_msg_string); free(resp->message); free(resp); /* printf("remote directory contains: \n");*/ for(i=0; i < num_metas; i++) { /*printf("%s\n",basic_metas[i].name);*/ free(basic_metas[i].name); } memset(path, 0, 1024); strcpy(path, dirpath); free(basic_metas); printf("New remote path: '%s'\n", path); } return 0; }
void list_dir(char* path, bool l, unsigned long IPaddr, int PN) { if(l==0) { DIR *dp; struct dirent *ep; dp = opendir (path); if (dp != NULL) { while ((ep = readdir (dp))) { if(strcmp(ep->d_name,".")!=0 && strcmp(ep->d_name,"..")!=0) { if(ep->d_type == DT_REG) { int size = -1; char filepath[1024]; struct stat st; strcpy(filepath,path); strcat(filepath,"/"); strcat(filepath,ep->d_name); if(stat(filepath, &st)==0) size = st.st_size; else perror("Unable to calculate file size: "); printf("%s File Size: %d\n",ep->d_name, size); } if(ep->d_type == DT_DIR) printf("%s Folder\n",ep->d_name); } } closedir (dp); } else perror ("ls() error"); } else { char* msg = 0, * resp_msg = 0, *err_msg_string = 0; uint64_t msg_len; uint32_t num_metas; int i; basic_meta_t *basic_metas = 0; ErrorCode error; struct Node* resp; create_msg_get_folder_meta_request(path, &msg, &msg_len); error = mysend(msg, IPaddr, PN, msg_len); free(msg); if(error == FAILURE || error == RETRY) { printf("error in send\n"); return; } resp = myrecv(CLIENT_PORT); resp_msg = resp->message; if(get_header_type(resp_msg) == BACS_ERROR) { parse_msg_error(resp_msg, &err_msg_string); printf("%s\n",err_msg_string); free(err_msg_string); free(resp->message); free(resp); return; } parse_msg_get_folder_meta_response(resp_msg, &basic_metas, &num_metas); free(err_msg_string); free(resp->message); free(resp); if(num_metas>0) { /*printf("remote directory contains: \n");*/ for(i=0; i < num_metas; i++) { if(basic_metas[i].type==BACS_FILE_TYPE) printf("%s FILE Size: %d\n",basic_metas[i].name,basic_metas[i].size); else printf("%s FOLDER\n",basic_metas[i].name); free(basic_metas[i].name); } } else printf("Empty folder.\n"); free(basic_metas); } }
int main(int argv, char** argc) { char IPaddr[1024]; char ch; //char data[1024]; int data_testint; int choice; strcpy(IPaddr, "127.0.0.1"); ErrorCode mycode; char* data = "This is a test.> I have a doubt in Q1 a) of the Midterm where it is stated that Do not modify the way in which shares are stored or the information that is stored with them . If the same share is written to different servers and yet each server only holds a single share, would this be in violation of how the shares are stored? There are two attacks possible when data is stored using secretsharing techniques. One attack is by a faulty client that generatesinconsistent shares during writes, i.e., different subsets of k sharesout of the q shares will decode to different values. The other attack is when a faulty server returns incorrect or arbitrary sharesduring reads. Such attacks can be detected using verifiable secretsharing schemes [6]. In such schemes, some common data (callewitnesses) for all the shares is computed by a client during writes and sent to all the servers. Before storing the shares and the wit-nesses,the servers check the shares received against the witnessesand arrive at a consensus on the consistency of the shares. Duringreads, a client will first determine the witnesses and check the va-lidity of each share with the witnesses before proceeding to decode the sensitive data. Verifiable secret sharing schemes significantlyincrease the computation overheads during the secret sharing (en-coding) and secret recovery (decoding) processes. A widely useethod for verifiable secret sharing is Feldman’s scheme [8]. Ta-ble 2 gives the computation times during secret sharing and secretrecovery of an 8 KB block of data when Feldman’s scheme is usedwith Shamir’s scheme.For comparison purposes, the throughputs of the AES Rijndaelsymmetric-key encryption algorithm are given in Table 3.From Tables 1–3, it is clear that the computation times of Samir’sscheme and Feldman’s scheme are far higher than those of symmetric-key encryption and, in fact, this performance is well below whatis acceptable for modern data storage systems. The secret recov-ery computation time for verifiable secret sharing are at least 3000times slower than the Rijndael decryption times. The above anal-ses also indicate, in part, why perfect secret sharing techniqueshave not been adopted for generic data to date. We reduce the computation overheads by using the following two mechanisms:Mechanism 1: Use a (q, q) perfect secret sharing scheme: Whenk = q, i.e., all the shares are needed to recover the secret, then“inconsistent” secret sharing is not possible. That is, there is noquestion of different subsets of k shares out of q shares decoding toifferent values because there is only one such subset, since k = q.Hence, verifiable secret sharing schemes can be avoided. Further,a (q, q) perfect secret sharing scheme can be realized using sim-ple bit-wise XOR operations. If each data bit is thought of as aseparate secret, then each share is a single bit and XOR of the qshares (or q bits) gives the encoded secret bit. In practice, XORsecret sharing can be implemented with word-wide operations forefficiency. Table 4 lists the computation times during secret shar-ing and secret recovery for a selection of (q, q) values for XORsecret sharingNote that XOR secret sharing is also a perfect seThis is a test.> I have a doubt in Q1 a) of the Midterm where it is stated that Do not modify the way in which shares are stored or the information that is stored with them . If the same share is written to different servers and yet each server only holds a single share, would this be in violation of how the shares are stored? There are two attacks possible when data is stored using secretsharing techniques. One attack is by a faulty client that generatesinconsistent shares during writes, i.e., different subsets of k sharesout of the q shares will decode to different values. The other attack is when a faulty server returns incorrect or arbitrary sharesduring reads. Such attacks can be detected using verifiable secretsharing schemes [6]. In such schemes, some common data (callewitnesses) for all the shares is computed by a client during writes and sent to all the servers. Before storing the shares and the wit-nesses,the servers check the shares received against the witnessesand arrive at a consensus on the consistency of the shares. Duringreads, a client will first determine the witnesses and check the va-lidity of each share with the witnesses before proceeding to decode the sensitive data. Verifiable secret sharing schemes significantlyincrease the computation overheads during the secret sharing (en-coding) and secret recovery (decoding) processes. A widely useethod for verifiable secret sharing is Feldman’s scheme [8]. Ta-ble 2 gives the computation times during secret sharing and secretrecovery of an 8 KB block of data when Feldman’s scheme is usedwith Shamir’s scheme.For comparison purposes, the throughputs of the AES Rijndaelsymmetric-key encryption algorithm are given in Table 3.From Tables 1–3, it is clear that the computation times of Samir’sscheme and Feldman’s scheme are far higher than those of symmetric-key encryption and, in fact, this performance is well below whatis acceptable for modern data storage systems. The secret recov-ery computation time for verifiable secret sharing are at least 3000times slower than the Rijndael decryption times. The above anal-ses also indicate, in part, why perfect secret sharing techniqueshave not been adopted for generic data to date. We reduce the computation overheads by using the following two mechanisms:Mechanism 1: Use a (q, q) perfect secret sharing scheme: Whenk = q, i.e., all the shares are needed to recover the secret, then“inconsistent” secret sharing is not possible. That is, there is noquestion of different subsets of k shares out of q shares decoding toifferent values because there is only one such subset, since k = q.Hence, verifiable secret sharing schemes can be avoided. Further,a (q, q) perfect secret sharing scheme can be realized using sim-ple bit-wise XOR operations. If each data bit is thought of as aseparate secret, then each share is a single bit and XOR of the qshares (or q bits) gives the encoded secret bit. In practice, XORsecret sharing can be implemented with word-wide operations forefficiency. Table 4 lists the computation times during secret shar-ing and secret recovery for a selection of (q, q) values for XORsecret sharingNote that XOR secret sharing is also a perfect se"; printf("sizeof data: %lu\n", strlen(data)); mycode = mysend(data, IPaddr , 9930 , strlen(data)); //printf("Enter your choice\n1: Send Test String\n2: Send Heart beat\n\nChoice: ");//2: Transmit Int\n"); /*loop: printf("Enter your choice\n1: Send Test String\n2: Send Heart beat\n\nChoice: ");//2: Transmit Int\n"); scanf("%d",&choice); switch(choice) { case 1: { //strcpy(data, strcat( IPaddr, " My Test String "));//Append Sender IP to the message strcpy(data, "My test string"); printf("data : %s\n",data); mycode = mysend(data, IPaddr); break; } case 2: { //data_testint = htonl(123); //strcpy(data, strcat( IPaddr, " Heartbeat ")); strcpy(data,"Hearbeat"); mycode = mysend(data, IPaddr); break; } default: { printf("Enter 1, 2 or 3\n"); goto loop; } } //mycode = myclient(data, IPaddr); if(mycode == RETRY) { printf("Sender Returned: %d\n", mycode); printf("Need to resend data\nResending...\n\n"); printf("Sender Returned: %d\n",mysend(data, IPaddr)); } if(mycode == FAILURE) { printf("Sender Returned: %d\tSending Failed\n", mycode); } if(mycode == SUCCESS) { printf("Sender Returned: %d\tSending SUccessful\n", mycode); } */ //printFunction(); //free(data); return 0; }