1 module libsweatyballs.engine.core; 2 3 import libsweatyballs.router.core : Router; 4 import libsweatyballs.router.table; 5 import libsweatyballs.zwitch.core : Switch; 6 import libsweatyballs.zwitch.neighbor; 7 import libsweatyballs.link.core : Link; 8 import core.sync.mutex : Mutex; 9 import libsweatyballs.engine.configuration : Config; 10 import std.conv : to; 11 import gogga; 12 import core.thread : Thread, dur; 13 import libsweatyballs.router.table : Route; 14 import std.socket : Address, parseAddress; 15 16 /* TODO: Import for config thing */ 17 18 /** 19 * Engine 20 * 21 * Description: TODO 22 */ 23 public final class Engine : Thread 24 { 25 /** 26 * Network components 27 */ 28 private Router router; 29 private Switch zwitch; 30 31 /** 32 * Links the router can advertise over 33 */ 34 private Link[] links; 35 private Mutex linksMutex; 36 37 /** 38 * 1. This must read config given to it 39 * 2. Setups links 40 * 3. Create new Router with these links 41 * 4. Spawn a Switch that handles packet in/out 42 * 5. Pass the Switch the router 43 * 6. Start the switch 44 * 7. We must then mainloop and collect statistics and handle shutdown etc 45 */ 46 this(Config config) 47 { 48 /* TODO: Add comment */ 49 super(&worker); 50 51 /* TODO: Read config */ 52 parseConfig(config); 53 54 /* Initialize locks */ 55 initMutexes(); 56 } 57 58 /** 59 * Initializes all the mutexes 60 */ 61 private void initMutexes() 62 { 63 linksMutex = new Mutex(); 64 } 65 66 public Link[] getLinks() 67 { 68 Link[] copy; 69 70 linksMutex.lock(); 71 foreach(Link link; links) 72 { 73 copy ~= link; 74 } 75 linksMutex.unlock(); 76 77 return copy; 78 } 79 80 private void parseConfig(Config config) 81 { 82 /* TODO: Set configuration parameter */ 83 84 /* Setup links */ 85 links = createLinks(config.links); 86 setupLinks(links); 87 88 /** 89 * Setup a new Router 90 */ 91 router = new Router(this, config.routerIdentity); 92 93 94 95 96 /* Setup a new Switch */ 97 zwitch = new Switch(this); 98 99 /* Add self neighbor to any link (try the first, TODO: Atleast one link is needed) */ 100 Address address = parseAddress("::", links[0].getR2RPort()); 101 Neighbor selfNeighbor = new Neighbor(router.getIdentity().getKeys().publicKey, address, links[0]); 102 103 104 Route route = new Route(router.getIdentity().getKeys().publicKey, selfNeighbor); 105 route.setAgeibility(false); 106 107 router.getTable().addRoute(route); 108 109 } 110 111 public Router getRouter() 112 { 113 return router; 114 } 115 116 public Switch getSwitch() 117 { 118 return zwitch; 119 } 120 121 private void worker() 122 { 123 while(true) 124 { 125 /** 126 * FIXME: Remove this, this is just testing code 127 */ 128 Route[] routes = router.getTable().getRoutes(); 129 foreach(Route route; routes) 130 { 131 zwitch.sendPacket(route.getAddress(), cast(byte[])"Hello world"); 132 } 133 134 Thread.sleep(dur!("seconds")(1)); 135 } 136 } 137 138 private Link[] createLinks(string[] interfaces) 139 { 140 Link[] createdLinks; 141 142 foreach(string interfaceName; interfaces) 143 { 144 createdLinks ~= new Link(interfaceName, this); 145 } 146 147 return createdLinks; 148 } 149 150 private void setupLinks(Link[] links) 151 { 152 gprintln("Begin link initailization"); 153 foreach(Link link; links) 154 { 155 gprintln("Initializing link "~to!(string)(link)~" ..."); 156 link.launch(); 157 } 158 gprintln("Links have been initialized"); 159 } 160 161 public void launch() 162 { 163 /* Start the engine */ 164 start(); 165 166 /* Start router */ 167 router.launch(); 168 169 /* Start switch */ 170 zwitch.launch(); 171 172 /* Start collector */ 173 /* TODO: Add me */ 174 175 gprintln("Engine has started all threads and is now going to finish and return to constructor thread control"); 176 } 177 }