X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fgeekos%2Fsocket.c;h=0d6fd373ca574a2df0fca2a3107011b6f0f7d22e;hb=56f8088296ee4116a4811a2f4f843edd80a7748d;hp=b18eaeb392538f47a4f2da587739b7d112d2509d;hpb=410089191febd4884a3a5a513052b0ae12aa7ebf;p=palacios.git diff --git a/palacios/src/geekos/socket.c b/palacios/src/geekos/socket.c index b18eaeb..0d6fd37 100644 --- a/palacios/src/geekos/socket.c +++ b/palacios/src/geekos/socket.c @@ -1,63 +1,86 @@ +/* (c) 2008, Jack Lange */ +/* (c) 2008, Lei Xia +/* (c) 2008, The V3VEE Project */ + #include #include -#include #include #include #include -#include #include -#include - +#include +#include -// for some reason, there are compile warnings without these -extern void v3_init_queue(struct gen_queue * queue); -extern void v3_enqueue(struct gen_queue * queue, addr_t entry); -extern addr_t v3_dequeue(struct gen_queue * queue); #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) #define MAX_SOCKS 1024 +#define BUF_SIZE 1000 struct socket sockets[MAX_SOCKS]; -struct gen_queue in_packets; +void socket_appcall(void); +#ifndef UIP_APPCALL +#define UIP_APPCALL socket_appcall +#endif /* UIP_APPCALL */ + -struct sock_packet { - int size; - uchar_t *data; -}; -int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt) ; -void init_network() { +static int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt); +static void periodic_caller(int timer_id); + +void init_socket_layer() { int i = 0; - - v3_init_queue(&in_packets); + bool iflag; + for (i = 0; i < MAX_SOCKS; i++) { sockets[i].in_use = 0; - v3_init_queue(&(sockets[i].send_queue)); - v3_init_queue(&(sockets[i].recv_queue)); + sockets[i].send_buf = NULL; + sockets[i].recv_buf = NULL; + sockets[i].state = CLOSED; } - //initiate uIP + + + //initiate uIP uip_init(); uip_arp_init(); + + //setup device driver + Init_Ne2k(&Packet_Received); - // set up interrupt handler - // set up device driver + iflag = Begin_Int_Atomic(); + Start_Timer(2, periodic_caller); + End_Int_Atomic(iflag); - Init_Ne2k(&Packet_Received); +} + + +void set_ip_addr(uchar_t addr[4]) { + uip_ipaddr_t ipaddr; + uip_ipaddr(ipaddr, addr[0], addr[1], addr[2], addr[3]); /* Local IP address */ + uip_sethostaddr(ipaddr); } + static int allocate_socket_fd() { int i = 0; for (i = 0; i < MAX_SOCKS; i++) { if (sockets[i].in_use == 0) { sockets[i].in_use = 1; + sockets[i].send_buf = create_ring_buffer(BUF_SIZE); + if (sockets[i].send_buf == NULL) + return -1; + sockets[i].recv_buf = create_ring_buffer(BUF_SIZE); + if (sockets[i].recv_buf == NULL){ + free_ring_buffer(sockets[i].send_buf); + return -1; + } return i; } } @@ -66,7 +89,15 @@ static int allocate_socket_fd() { } static int release_socket_fd(int sockfd){ - sockets[sockfd].in_use = 0; + if (sockfd >= 0 && sockfd < MAX_SOCKS){ + sockets[sockfd].in_use = 0; + free_ring_buffer(sockets[sockfd].send_buf); + free_ring_buffer(sockets[sockfd].recv_buf); + sockets[sockfd].send_buf = NULL; + sockets[sockfd].recv_buf = NULL; + sockets[sockfd].state = CLOSED; + } + return 0; } @@ -77,11 +108,34 @@ struct socket * get_socket_from_fd(int fd) { +static void periodic_caller(int timer_id) { + int i; + //handle the periodic calls of uIP + + //PrintBoth("Timer CALLBACK handler\n"); + + for(i = 0; i < UIP_CONNS; ++i) { + uip_periodic(i); + if(uip_len > 0) { + //devicedriver_send(); + PrintBoth("Sending Packet\n"); + NE2K_Transmit(uip_len); + } + } + for(i = 0; i < UIP_UDP_CONNS; i++) { + uip_udp_periodic(i); + if(uip_len > 0) { + //devicedriver_send(); + NE2K_Transmit(uip_len); + } + } +} + int connect(const uchar_t ip_addr[4], ushort_t port) { int sockfd = -1; sockfd = allocate_socket_fd(); - uip_ipaddr_t ipaddr; + static uip_ipaddr_t ipaddr; if (sockfd == -1) { return -1; @@ -89,39 +143,56 @@ int connect(const uchar_t ip_addr[4], ushort_t port) { uip_ipaddr(&ipaddr, ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]); - sockets[sockfd].con = uip_connect((uip_ipaddr_t *)&ip_addr, htons(port)); + sockets[sockfd].con = uip_connect(&ipaddr, htons(port)); + if (sockets[sockfd].con == NULL){ - release_socket_fd(sockfd); - return -1; + release_socket_fd(sockfd); + return -1; } + + PrintBoth("Connection start\n"); + Wait(&(sockets[sockfd].recv_wait_queue)); + + + PrintBoth("Connected\n"); + + + + return sockfd; } +int recv(int sockfd, void * buf, uint_t len){ + uint_t recvlen; + + struct socket *sock = get_socket_from_fd(sockfd); + + + // here we need some lock mechnism, just disable interrupt may not work properly because recv() will be run as a kernel thread +buf_read: + recvlen = rb_read(sock->recv_buf, buf, len); + + if (recvlen == 0){ + Wait(&(sock->recv_wait_queue)); + goto buf_read; + } -void timer_int_Handler(struct Interrupt_State * state){ - int i; - //handle the periodic calls of uIP - for(i = 0; i < UIP_CONNS; ++i) { - uip_periodic(i); - if(uip_len > 0) { - //devicedriver_send(); - NE2K_Transmit(uip_len); - } - } - for(i = 0; i < UIP_UDP_CONNS; i++) { - uip_udp_periodic(i); - if(uip_len > 0) { - //devicedriver_send(); - NE2K_Transmit(uip_len); - } - } + return recvlen; } + + // a series of utilities to handle conncetion states -static void connected(int sockfd){ +static void connected(int sockfd) { + struct socket * sock = get_socket_from_fd(sockfd); + + PrintBoth("Connected Interrupt\n"); + + sock->state = ESTABLISHED; + Wake_Up(&(sock->recv_wait_queue)); } static void closed(int sockfd){ @@ -133,34 +204,71 @@ static void acked(int sockfd){ } static void newdata(int sockfd){ + uint_t len; + char *dataptr; + uint_t wrlen; + struct socket *sock; + + len = uip_datalen(); + dataptr = (char *)uip_appdata; + + if (len == 0) + return; + + sock = get_socket_from_fd(sockfd); + + wrlen = rb_write(sock->recv_buf, dataptr, len); + + if (wrlen < len){ //write error, what should I do? + return; + } + + Wake_Up(&(sock->recv_wait_queue)); + + return; } // not finished yet -static void -senddata(int sockfd){ - uchar_t *bufptr; - int len = 0; +static void send_to_driver(int sockfd) { + + PrintBoth("Sending data to driver\n"); + +} - bufptr = uip_appdata; + + +int send(int sockfd, void * buf, uint_t len) { + struct socket * sock = get_socket_from_fd(sockfd); + //int mss = uip_mss(); + //int pending_bytes = rb_data_len(sock->send_buf); + //int len = (mss < pending_bytes) ? mss: pending_bytes; + int bytes_read = 0; + uchar_t * send_buf = uip_appdata; - if(len < uip_mss()) { - // memcpy(bufptr, data, len); - } else { + bytes_read = rb_peek(sock->send_buf, send_buf, len); - } - //uip_send(uip_appdata,len); + if (bytes_read == 0) { + // no packet for send + return -1; + } + + uip_send(send_buf, len); + + return len; } //get the socket id by the local tcp port -static int get_socket_from_port(ushort_t lport) { +static int get_socket_from_port(ushort_t lport) { int i; - for (i = 0; ilport == lport) - return i; + + for (i = 0; i < MAX_SOCKS; i++){ + if (sockets[i].con->lport == lport) { + return i; + } } return -1; @@ -168,110 +276,89 @@ static int get_socket_from_port(ushort_t lport) { +void socket_appcall(void) { -void -socket_appcall(void) -{ int sockfd; - + sockfd = get_socket_from_port(uip_conn->lport); - if (sockfd == -1) return; - - if(uip_connected()) { - connected(sockfd); + PrintBoth("Appcall\n"); + + + if (sockfd == -1) { + return; + } + + if (uip_connected()) { + connected(sockfd); + } - if(uip_closed() ||uip_aborted() ||uip_timedout()) { + if (uip_closed() ||uip_aborted() ||uip_timedout()) { closed(sockfd); return; } - if(uip_acked()) { + if (uip_acked()) { acked(sockfd); } - if(uip_newdata()) { + if (uip_newdata()) { newdata(sockfd); } - if(uip_rexmit() || - uip_newdata() || - uip_acked() || - uip_connected() || - uip_poll()) { - senddata(sockfd); + if (uip_rexmit() || + uip_newdata() || + uip_acked() || + uip_connected() || + uip_poll()) { + send_to_driver(sockfd); } } -int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt) -{ - struct sock_packet next; - int i; - - next.size = info->size; - next.data = (uchar_t *)VMM_Malloc(next.size); - if (next.data == NULL) return 1; - - //uip_len = info->size; +static int Packet_Received(struct NE2K_Packet_Info * info, uchar_t * pkt) { + //int i; + uip_len = info->size; - for(i = 0; i < info->size; i++) { - *((next.data)+i) = *(pkt+i); - } - Free(pkt); + // for (i = 0; i < info->size; i++) { + // uip_buf[i] = *(pkt + i); + //} - Disable_Interrupts(); - v3_enqueue(&in_packets, (addr_t)(&next)); - Enable_Interrupts(); + PrintBoth("Packet REceived\n"); + + memcpy(uip_buf, pkt, uip_len); - //triger_receiver_interrupt(); - - return 0; -} + Free(pkt); -void int_handler_packet_receive(struct Interrupt_State * state){ - //device driver got a incoming packet and enqueue that packet to the receive queue - struct sock_packet *next_packet; - addr_t pkt; - int i; + if (BUF->type == htons(UIP_ETHTYPE_ARP)) { + PrintBoth("ARP PACKET\n"); + + uip_arp_arpin(); + + + if (uip_len > 0) { + PrintBoth("Transmitting\n"); + NE2K_Transmit(uip_len); + } - while(1){ - //currently disable interrupt because no lock for the queue - Disable_Interrupts(); - pkt = v3_dequeue(&in_packets); - Enable_Interrupts(); - - if (pkt == 0) break; - - //there are new packets in the receiver queue - next_packet = (struct sock_packet *)pkt; - uip_len = next_packet->size; - - for(i = 0; i < uip_len; i++) { - uip_buf[i] = *((next_packet->data)+i); - } - - Free(next_packet->data); - Free(next_packet); - - if(BUF->type == htons(UIP_ETHTYPE_ARP)) { - uip_arp_arpin(); - if (uip_len > 0){ - //ethernet_devicedriver_send(); - NE2K_Transmit(uip_len); - } - } else { - uip_arp_ipin(); - uip_input(); - if(uip_len > 0) { - uip_arp_out(); - //ethernet_devicedriver_send(); - NE2K_Transmit(uip_len); - } - } - } + + } else { + PrintBoth("Data PACKET\n"); + uip_arp_ipin(); + uip_input(); + + + if (uip_len > 0) { + PrintBoth("Transmitting\n"); + uip_arp_out(); + NE2K_Transmit(uip_len); + } + + } + + return 0; }