1/* 2 * Copyright (c) 2007-12 ETH Zurich. 3 * All rights reserved. 4 * 5 * This file is distributed under the terms in the attached LICENSE file. 6 * If you do not find this file, copies can be found by writing to: 7 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. 8 */ 9 10#include <barrelfish/barrelfish.h> 11#include <stdio.h> 12#include <assert.h> 13#include <lwip/netif.h> 14#include <lwip/udp.h> 15#include <lwip/ip_addr.h> 16#include <netif/bfeth.h> 17#include <trace/trace.h> 18#include <arpa/inet.h> 19#include "tcp_server_bm.h" 20 21//called whenever a new datagram for that pcb arrived 22static void udp_recv_handler_bm(void *arg, struct udp_pcb *pcb, 23 struct pbuf *p, struct ip_addr *addr, u16_t port) 24{ 25 // Send the data to benchmarking code for furthur analysis 26 handle_data_arrived(p->payload, p->len); 27 28 //send the echo 29 struct ip_addr destaddr = *addr; 30 udp_sendto(pcb, p, &destaddr, port); 31 pbuf_free(p); 32} 33 34int udp_server_bm_init(uint16_t bind_port) 35{ 36 err_t r; 37 38 //create a new UDP PCB 39 struct udp_pcb *pcb = udp_new(); //UDP connection data 40 if (pcb == NULL) { 41 return ERR_MEM; 42 } 43 44 //bind it to every IP of every interface and define a specific port to 45 //bind to 46 r = udp_bind(pcb, IP_ADDR_ANY, bind_port); 47 if(r != ERR_OK) { 48 udp_remove(pcb); 49 return(r); 50 } 51 52 //install a callback for received datagrams 53 udp_recv(pcb, udp_recv_handler_bm, 0); 54 printf("installed receive callback for server.\n"); 55 printf("udp_server_bm_init (): bound.\n"); 56 return (0); 57} // end function: udp_server_bm_init 58 59// ********************************************************************* 60 61// *************************************************************** 62// udp client code 63// *************************************************************** 64 65// A client pcb 66static struct udp_pcb *client_pcb = NULL; 67 68// single pbuf that will be used by client to send over and over again. 69static struct pbuf *udp_pbuf_cl = NULL; 70 71static void *payload_ptr = NULL; 72static size_t udp_msg_size = 0; 73 74//called whenever a new datagram for that pcb arrived 75static void udp_recv_handler_bm_client(void *arg, struct udp_pcb *pcb, 76 struct pbuf *p, struct ip_addr *addr, u16_t port) 77{ 78 // Send the data to benchmarking code for furthur analysis 79 handle_data_arrived(p->payload, p->len); 80 pbuf_free(p); 81} 82 83// initialize udp connection for the client 84int udp_client_bm_init(char *ip_addr_str, uint16_t server_port) 85{ 86 err_t r; 87 88 // Preparing IP address for use 89 assert(ip_addr_str != NULL); 90 struct in_addr addr; 91 if (inet_aton(ip_addr_str, &addr) == 0) { 92 printf("Invalid IP addr: %s\n", ip_addr_str); 93 USER_PANIC("Invalid IP address %s", ip_addr_str); 94 return -1; 95 } 96 struct ip_addr server_addr; 97 server_addr.addr = addr.s_addr; 98 99 // Prepare udp_pcb 100 client_pcb = udp_new(); 101 if (client_pcb == NULL) { 102 USER_PANIC("udp_new failed"); 103 return -1; 104 } 105 106 // Connecting to given IP address, port no. 107 //don't use htons() on port no. (don't know why...) 108 r = udp_connect(client_pcb, &server_addr, server_port); 109 if(r != ERR_OK) { 110 USER_PANIC("udp_connect failed"); 111 return(r); 112 } 113 114 udp_recv(client_pcb, udp_recv_handler_bm_client, 0); 115 116 // Connection established! 117 printf("udp benchmark client started\n"); 118 handle_connection_opened(); 119 return (0); 120} // end function: udp_client_bm_init 121 122 123void *prepare_udp_buffer(size_t payload_size) 124{ 125 126// udp_pbuf_cl = pbuf_alloc(PBUF_TRANSPORT, payload_size, PBUF_POOL); 127 udp_pbuf_cl = pbuf_alloc(PBUF_TRANSPORT, payload_size, PBUF_RAM); 128 if (udp_pbuf_cl == NULL){ 129 USER_PANIC("pbuf_alloc failed in prepare_udb_buffer"); 130 return NULL; 131 } 132 assert(udp_pbuf_cl != NULL); 133 assert(udp_pbuf_cl->payload != NULL); 134 assert(udp_pbuf_cl->len == payload_size); 135 payload_ptr = udp_pbuf_cl->payload; 136 udp_msg_size = payload_size; 137 return udp_pbuf_cl->payload; 138} 139 140// send single message over udp connection 141int send_udp_message_client(void) 142{ 143 err_t err; 144 145 // resetting the values as they will be changed by 146 // pbuf_header function 147 udp_pbuf_cl->len = udp_msg_size; 148 udp_pbuf_cl->tot_len = udp_msg_size; 149 udp_pbuf_cl->payload = payload_ptr; 150 151 err = udp_send(client_pcb, udp_pbuf_cl); 152 if (err_is_fail(err)) { 153 USER_PANIC_ERR(err, "udp_send failed"); 154 return -1; 155 } 156 return 0; 157} // end function: send_message_client 158