1 //Kayo Fujiwara 1/8/2007
2 #include "gtnets_simulator.h"
3 #include "gtnets_topology.h"
9 static vector<void*> meta_flows;
10 static int* meta_nflow;
11 static int meta_flg = 0;
13 void static tcp_sent_callback(void* action, double completion_time);
16 // TODO: check the default values.
21 sim_ = new Simulator();
22 topo_ = new SGTopology();
24 // Set default values.
25 TCP::DefaultAdvWin(wsize);
26 TCP::DefaultSegSize(1000);
27 TCP::DefaultTxBuffer(128000);
28 TCP::DefaultRxBuffer(128000);
33 map<int, Linkp2p*>::iterator it;
34 for (it = gtnets_links_.begin(); it != gtnets_links_.end(); it++){
37 map<int, SGLink*>::iterator it2;
38 for (it2 = tmp_links_.begin(); it2 != tmp_links_.end(); it2++){
41 map<int, Node*>::iterator it3;
42 for (it3 = gtnets_nodes_.begin(); it3 != gtnets_nodes_.end(); it3++){
45 map<int, TCPServer*>::iterator it4;
46 for (it4 = gtnets_servers_.begin(); it4 != gtnets_servers_.end(); it4++){
49 map<int, TCPSend*>::iterator it5;
50 for (it5 = gtnets_clients_.begin(); it5 != gtnets_clients_.end(); it5++){
53 //TODO delete other objects!
57 int GTSim::add_link(int id, double bandwidth, double latency){
58 if (gtnets_links_.find(id) != gtnets_links_.end()){
59 fprintf(stderr, "can't add link %d. already exists.\n", id);
62 gtnets_links_[id] = new Linkp2p(bandwidth, latency);
66 int GTSim::add_route(int src, int dst, int* links, int nlink){
67 topo_->add_link(src, dst, links, nlink);
68 // topo_->create_tmplink(src, dst, links, nlink);
72 void GTSim::create_gtnets_topology(){
73 //TODO: add manual routing
74 //TODO: is this addressing fine?
75 static unsigned int address = IPAddr("192.168.0.1");
76 tmp_links_ = topo_->get_links();
77 map<int, SGLink*>::iterator it;
79 //By now, all links has two nodes.
80 //Connect left and right with the link.
81 for (it = tmp_links_.begin(); it != tmp_links_.end(); it++){
83 //both nodes must be not null. TODO check it!
84 int linkid = it->second->id();
85 int leftid = it->second->left_node()->id();
86 int rightid = it->second->right_node()->id();
88 cout << "linkid: " << linkid << endl;
89 cout << "leftid: " << leftid << endl;
90 cout << "rightid: " << rightid << endl;
93 map<int, Node*>::iterator nodeit = gtnets_nodes_.find(leftid);
94 // if the nodes don't exist, add one.
95 if (nodeit == gtnets_nodes_.end()){
96 gtnets_nodes_[leftid] = new Node();
97 gtnets_nodes_[leftid]->SetIPAddr(address++);
98 //add host-node relationships.
99 vector<int> tmphosts = it->second->left_node()->hosts();
101 for (int i = 0; i < tmphosts.size(); i++){
102 gtnets_hosts_[tmphosts[i]] = leftid;
103 cout << "host: " << tmphosts[i] << " node: " << leftid << endl;
107 nodeit = gtnets_nodes_.find(rightid);
108 if (nodeit == gtnets_nodes_.end()){//new entry
109 gtnets_nodes_[rightid] = new Node();
110 gtnets_nodes_[rightid]->SetIPAddr(address++);
112 //add host-node relationships.
113 vector<int> tmphosts = it->second->right_node()->hosts();
115 for (int i = 0; i < tmphosts.size(); i++){
116 gtnets_hosts_[tmphosts[i]] = rightid;
117 cout << "host: " << tmphosts[i] << " node: " << rightid << endl;
121 gtnets_nodes_[leftid]->
122 AddDuplexLink(gtnets_nodes_[rightid], *gtnets_links_[linkid]);
127 int GTSim::create_flow(int src, int dst, long datasize, void* metadata){
128 if (is_topology_ == 0){
129 create_gtnets_topology();
132 //TODO: what if more than two flows?
133 //TODO: check if src and dst exists.
134 //TODO: should use "flowID" to name servers and clients.
135 gtnets_servers_[nflow_] = (TCPServer*)gtnets_nodes_[gtnets_hosts_[dst]]->
136 AddApplication(TCPServer(TCPReno()));
137 gtnets_servers_[nflow_]->BindAndListen(80);
139 gtnets_clients_[nflow_] = (TCPSend*)gtnets_nodes_[gtnets_hosts_[src]]->
140 AddApplication(TCPSend(metadata, gtnets_nodes_[gtnets_hosts_[dst]]->GetIPAddr(),
141 80, Constant(datasize), TCPReno()));
142 gtnets_clients_[nflow_]->SetSendCallBack(tcp_sent_callback);
143 gtnets_clients_[nflow_]->Start(0);
149 Time_t GTSim::get_time_to_next_flow_completion(){
159 read(pfds[0], &t1, sizeof(Time_t));
160 waitpid(-1, &status, 0);
163 t = sim_->RunUntilNextCompletion();
164 write(pfds[1], (const void*)&t, sizeof(Time_t));
170 int GTSim::run_until_next_flow_completion(void ***metadata, int *number_of_flows){
172 meta_nflow = number_of_flows;
175 Time_t t1 = sim_->RunUntilNextCompletion();
177 *metadata = (meta_flows.empty() ? NULL : &meta_flows[0]);
181 int GTSim::run(double delta){
188 int GTSim::finalize(){
196 void static tcp_sent_callback(void* action, double completion_time){
197 // Schedule the flow complete event.
199 new SimulatorEvent(SimulatorEvent::FLOW_COMPLETE);
200 Simulator::instance->Schedule(e, 0, Simulator::instance);
203 meta_flows.push_back(action);