/* Sends a message to register SERVER with a TPCMaster over a socket located at * SOCKFD which has previously been connected. Does not close the socket when * done. Returns -1 if an error was encountered. * * Checkpoint 2 only. */ int kvserver_register_master(kvserver_t *server, int sockfd) { // OUR CODE HERE kvmessage_t *reqmsg = (kvmessage_t *) malloc(sizeof(kvmessage_t)); if (reqmsg == NULL) { return -1; } reqmsg->type = REGISTER; reqmsg->key = (char *) malloc((strlen(server->hostname) + 1) * sizeof(char)); if (reqmsg->key == NULL) { kvmessage_free(reqmsg); return -1; } strcpy(reqmsg->key, server->hostname); reqmsg->value = (char *) malloc(sizeof(char) * PORT_NUM_LENGTH); // max number is 2^16 - 1 if (reqmsg->value == NULL) { kvmessage_free(reqmsg); return -1; } sprintf(reqmsg->value, "%d", server->port); kvmessage_send(reqmsg, sockfd); kvmessage_t *response = kvmessage_parse(sockfd); int ret; if (!response || !response->message || strcmp(response->message, MSG_SUCCESS) != 0) { ret = -1; } else { ret = 0; server->state = TPC_READY; } kvmessage_free(response); return ret; }
void tpcmaster_dummy_handle(tpcmaster_t *master, int sockfd, callback_t callback) { kvmessage_t *req, resp; req = kvmessage_parse(sockfd); memset(&resp, 0, sizeof(kvmessage_t)); switch (current_test) { case GET_SIMPLE: resp.type = GETRESP; resp.key = "KEY"; resp.value = "VAL"; break; case PUT_SIMPLE: case DEL_SIMPLE: case PUT_CACHE: case DEL_CACHE: if (req->type == PUTREQ || req->type == DELREQ) resp.type = VOTE_COMMIT; else resp.type = ACK; break; default: return; } kvmessage_send(&resp, sockfd); free(req); }
/* Generic entrypoint for this SERVER. Takes in a socket on SOCKFD, which * should already be connected to an incoming request. Processes the request * and sends back a response message. This should call out to the appropriate * internal handler. */ void kvserver_handle(kvserver_t *server, int sockfd, void *extra) { kvmessage_t *reqmsg, *respmsg; respmsg = calloc(1, sizeof(kvmessage_t)); reqmsg = kvmessage_parse(sockfd); void (*server_handler)(kvserver_t *server, kvmessage_t *reqmsg, kvmessage_t *respmsg); server_handler = server->use_tpc ? kvserver_handle_tpc : kvserver_handle_no_tpc; if (reqmsg == NULL) { respmsg->type = RESP; respmsg->message = ERRMSG_INVALID_REQUEST; } else { server_handler(server, reqmsg, respmsg); } kvmessage_send(respmsg, sockfd); if (reqmsg != NULL) kvmessage_free(reqmsg); }