static int net_connect_req_handler(struct net_handle_cxt* cxt, struct net_req* req) { PLOGD("Entering CONNECT handler!"); struct strbuf* buf = &req->data->buf; PLOGD("HTTP/%d.%d", req->ver_major, req->ver_minor); req->host = req->path; PLOGD("Host: %s", buf->p + req->host); PLOGD("Port: %d", req->port); struct conn* client = cxt->client; PLOGD("From client: %s", ep_tostring(&client->ep)); struct conn* server = net_connect_to_server(cxt, buf->p + req->host, htons(req->port)); if (server == NULL) { // No server available net_bad_gateway(client); return -1; } struct net_handle_list* p = mem_alloc(sizeof(struct net_handle_list)); p->server = server; mem_incref(server); p->next = NULL; p->req = req; mem_incref(req); if (cxt->head == NULL) cxt->head = cxt->tail = p; else { cxt->tail->next = p; cxt->tail = p; } event_post(cxt->ev_notice_rsp, (void*)1); static char msg[] = "HTTP/1.1 200 OK\r\n\r\n"; int ret = conn_write(client, msg, strlen(msg)); if (ret) { net_bad_gateway(client); mem_decref(server, conn_done); return -1; } while (1) { ret = conn_copy(server, client, 64*1024); if (ret) break; } PLOGI("%s CONNECT %s %d", ep_tostring(client), buf->p + req->host, client->tx); mem_decref(server, conn_done); return ret; }
// Allocate and initialize a new proc as child 'cn' of parent 'p'. // Returns NULL if no physical memory available. proc * proc_alloc(proc *p, uint32_t cn) { pageinfo *pi = mem_alloc(); if (!pi) return NULL; mem_incref(pi); proc *cp = (proc*)mem_pi2ptr(pi); memset(cp, 0, sizeof(proc)); spinlock_init(&cp->lock); cp->parent = p; cp->state = PROC_STOP; // Integer register state cp->sv.tf.eflags = (FL_IOPL_MASK & FL_IOPL_3) | FL_IF; cp->sv.tf.cs = CPU_GDT_UCODE | 3; cp->sv.tf.ds = CPU_GDT_UDATA | 3; cp->sv.tf.es = CPU_GDT_UDATA | 3; cp->sv.tf.cs = CPU_GDT_UCODE | 3; cp->sv.tf.ss = CPU_GDT_UDATA | 3; if (p) p->child[cn] = cp; return cp; }
// Given a remote reference to a page on some other node, // see if we already have a corresponding local page // and return a pointer the beginning of that page if so. // Otherwise, returns NULL. pageinfo * mem_rrlookup(uint32_t rr) { // Change these to use whatever your memory spinlock is called. spinlock_acquire(&mem_freelock); uint8_t node = RRNODE(rr); assert(node > 0 && node <= NET_MAXNODES); uint32_t addr = RRADDR(rr); pageinfo *pi = mem_phys2pi(addr); assert(pi > &mem_pageinfo[1] && pi < &mem_pageinfo[mem_npage]); // Search for a page corresponding to this rr in the homelist for (pi = pi->homelist; pi != NULL; pi = pi->homenext) { assert(RRADDR(pi->home) == addr); if (pi->home == rr) { // found it! // Take a reference while we still have // the pageinfo array locked, so it can't go away. mem_incref(pi); break; } } spinlock_release(&mem_freelock); return pi; }
// Allocate and initialize a new proc as child 'cn' of parent 'p'. // Returns NULL if no physical memory available. proc * proc_alloc(proc *p, uint32_t cn) { pageinfo *pi = mem_alloc(); if (!pi) return NULL; mem_incref(pi); proc *cp = (proc*)mem_pi2ptr(pi); memset(cp, 0, sizeof(proc)); spinlock_init(&cp->lock); cp->parent = p; cp->state = PROC_STOP; cp->home = RRCONS(net_node, mem_phys(cp), 0); //Page directories - we might need this stuff, idk, merge conflict // cp->pdir = pmap_newpdir(); // cp->rpdir = pmap_newpdir(); // Integer register state cp->sv.tf.ds = CPU_GDT_UDATA | 3; cp->sv.tf.es = CPU_GDT_UDATA | 3; cp->sv.tf.cs = CPU_GDT_UCODE | 3; cp->sv.tf.ss = CPU_GDT_UDATA | 3; cp->pdir = pmap_newpdir(); if (!cp->pdir) return NULL; cp->rpdir = pmap_newpdir(); if (!cp->rpdir) { pmap_freepdir(mem_ptr2pi(cp->pdir)); return NULL; } if (p) p->child[cn] = cp; return cp; }
static int net_http_req_handler(struct net_handle_cxt* cxt, struct net_req* req) { struct conn* client = cxt->client; PLOGD("Entering HTTP handler!"); struct strbuf* buf = &req->data->buf; PLOGD("HTTP/%d.%d", req->ver_major, req->ver_minor); PLOGD("Method: %s", buf->p); PLOGD("Host: %s", buf->p + req->host); PLOGD("Port: %d", req->port); if (req->protocol > 0) PLOGD("Protocol: %s", buf->p + req->protocol); PLOGD("Path: %s", buf->p + req->path); PLOGD("From client: %s", ep_tostring(&client->ep)); // net_bad_gateway(client); // return -1; struct conn* server = NULL; int ret = 0; while (1) { server = net_connect_to_server(cxt, buf->p + req->host, htons(req->port)); if (server == NULL) { // No server available net_bad_gateway(client); return -1; } // TODO Check headers and http version if (net_data_get_ent(req->data, "Host") == NULL) net_data_set_ent_offset(req->data, "Host", req->host); ret = net_forward_req_header(req, server); if (ret == 0) break; mem_decref(server, conn_done); } // Add req to the cxt list struct net_handle_list* p = mem_alloc(sizeof(struct net_handle_list)); p->server = server; mem_incref(server); p->next = NULL; p->req = req; mem_incref(req); if (cxt->head == NULL) cxt->head = cxt->tail = p; else { cxt->tail->next = p; cxt->tail = p; } if (cxt->rsp_blocked) event_post(cxt->ev_notice_rsp, (void*)1); ret = net_transfer_body_HTTP_1_1(server, client, req->data); if (ret) net_bad_gateway(client); mem_decref(server, conn_done); return ret; }