[MUSIC] Okay, so we're talking a lot about routing and the reason we're doing that is because in networks, in IoT your kind of dealing with a lot of different problems. You're dealing with kind of storing data. You have a bunch of nodes you need to kind of store and replicate data across them need. You need to kind of multicast. You may need to construct trees, dissemination trees, to collect data from sensors and bring them back to the root, and so there's a lot of things you need to do. But a lot of these protocols rely on having some sort of point-to-point communication mechanism or point-to-multipoint communication mechanism, and that's what routing is. So once you understand routing and the different ways to do routing you have a big toolbox you can use to kind of build more advanced algorithms and you kind of call routing using an API. And we're going to kind of continue this journey and we're going to talk about geographic routing next. So geographic routing has been around for thousands of years, thousands of years ago people would kind of sail ships on the ocean and they needed to kind of describe where they were going. You're on a ship and you kind of need to go from one place to another place but there's not really landmarks in the ocean. So what people figured out is they said okay, the earth is a sphere and we're going to define a coordinate system on this sphere. We're going to have latitude and longitude lines were going to divide up the earth and then any point you want to go to is uniquely defined by a set of coordinates, and so this idea can be used for routing as well. So the designers of geographic routing realize that we can do the same thing for forwarding and using this as a metric for making progress in a geographic space. So that's the idea here. The idea behind geographic routing is we're going to use geographic position information to make progress to the destination. And the way this is going to work is the source is going to send a message not to a random address but to an address that is defined by the geographic location of the destination. So we're sending a message to a location as opposed to traditional address. And to make this work each node is going to have to know some information about its geographic location, the geographical location of its neighbors, and so it can kind of know where it is and which neighbor it should use to forward to make progress to the destination. So in order for this to work there's a bunch of challenges you actually have to deal with. I mean, it sounds simple, you're kind of at one point and you kind of want to reach another point you just go in that direction right? Well it's a little more complex than you might think. One issue is you can get stuck in dead ends. Think about you kind of go in one direction, go in one direction and then you're stuck, there's no node that make more progress in that direction. So you can get stuck in dead ends or voids. You could also potentially get stuck in loops. Imagine if you have two neighbors, which if this geographic information is a little bit out of date or stale, and they both think each other is closer to the destination you gotta deal with that you want packets getting stuck in loops. So to deal with this there are specific protocols that have been developed for geographic routing. And one that's kind of famous and used practices is called the Greedy Perimeter Stateless Routing, and we're going to be talking about that. So to kind of show this graphically, let's suppose we have a network bunch of nodes, let's do geographic routing on this network. So the first step in geographic routing is each node is going to figure out where it is. And so we're going to take the geography and we're going to divide it up in a metric space and I suppose we kind of divide up in the two-dimensional space. In practice you might use more dimensions, there's some trade-offs with that, if you're kind of dealing with the plainer network relying on a surface two-dimensions might be fine. If you're building something in an office building where you kind of have to move around in three-dimensions you might have three-dimensions. Turns out the more dimensions you have the less likely you are to be stuck in dead ends for various reasons, so there's some trade-offs here. But to keep this example simple, let's suppose we just have a two-dimensional space. All nodes exist at a point in this two-dimensional space and we defined the address of a node as being its coordinates in this space. So for example node C has the address 13 comma 61 and then we kind of repeat this process. So each node figures out what its address is, what is coordinates are. And there's different ways this could be done. Maybe each of these nodes is using GPS. So with GPS you can figure out your precise latitude and longitude, so this might be latitude and longitude. There's also a virtual ways to do this. There's virtual coordinate spaces where you can have kind of beacons that kind of radiates out through the network, they broadcast updates, and you kind of figure out how far away you are from a beacon. And so these could be virtual coordinates, you don't need GPS necessarily, so there's different ways to get these coordinates. But somehow each node gets a set of coordinates and that forms its address. Then the next step is each node broadcast hello information because each node has to know its neighbors addresses in order to know which ways it can go. So node E for example is going to broadcast a hello message it's going to say hello, my name is E and my coordinates are 58, 79. And when this happens each of its neighbors can start building a table, can start building a one hop neighbor table, that lists their neighbors and their neighbors coordinates. And this process continues, each node broadcast these hello messages, you're probably going to do this periodically because nodes might come and go, links might break, you want to keep this up to date. But eventually every node is going to discover all of its neighbors and the neighbors coordinates, and this information will be stored in these tables. So when this is done every node knows its neighbors, its neighbor's coordinates, and I'm going to wipe these tables off the screen to kind of make the animation more clear, but every node remembers these tables. And then what we do is if we have a source, and they want to send a packet to a destination then it becomes a matter of kind of looking at your neighbors and figuring out which one makes the most progress in this coordinate space. So for example, if node A want's to send a packet to 126, 37, which is in destination M over there, so A's sitting there and it's looking at its neighbors, it has a few options, there's A and C and E and it's trying to decide which next-hop it should use. So E makes some progress in the coordinate space. We can see that E kind of makes progress in the x-coordinate space, we go from 40 to 58 so that's good we're getting closer to 126. But it makes some negative progress in the y-coordinate space we go from 76 to 79, but we want the y-coordinate to get smaller. So then we can look at B, B is better for the y-coordinate space, we're getting down to 37, but in the x-coordinate space it makes a little bit of negative progress. So you can kind of see generally what you do is you kind of look at your neighbor see which one makes the most progress and to do that A looks at its neighbor table and it does a computation. So what should be the specific algorithm for doing this? I mean this all sounds kind of fuzzy, you kind of look at your neighbors, which one's best? And you gotta be careful because whenever you design a routing protocol you need a unique metric for making progress in the space. If different nodes are kind of making a little bit different decisions, one node's using one metric, one node's using another metric then you can get loops because they might think each other is a neighbor. So what you want to have is a strictly decreasing metric to make progress in this coordinate space. So we need a specific algorithm here. So in geographic routing what we do is we minimize the remaining distance to the destination. So to do that A is going to say, okay, well, I'm going to look at E, E is a certain distance from M. So what is E's distance from M? Well, if you've taken geometry before you may know how to do this already. What A can do is they can say well okay, E is a certain vertical distance from M and is a certain horizontal distance from M. In the x-coordinate space we have to go to position 126 and we're at position 58 at E. And in the y-coordinate space we're at position 79 and we want to go to position 37. So we can see that if we go to E from A then we only have 42 units left to go in the y-dimension and 68 units left to go in the x-dimension to reach the destination. So knowing that how much distance is there between E and M? What's the bottom line? How much more distance do we have to go from E to M, in terms of straight line distance? Well, there's an equation for that it's known as the Pythagorean theorem. And what that theorem states is if you have a triangle like this and you know kind of the vertical and horizontal distance, you can compute the hypotenuse as the x and y-coordinates squared, add them together and then take the square root. So use that formula, we can pretty easily figure out that E is 79.9 units away from M. So in other words A can kind of do this computation, this is a pretty easy computation for it to do it's just math. And so A can figure out okay, if I send the packet to E then I have 79.9 more units left to go. And then A can kind of repeat this process for itself and its neighbors. A can say well, okay, is that better than me? Well A can do the same computation for itself compute the x and y-coordinates, plug them into the Pythagorean theorem. And A can figure out okay, well, I'm 94.4 units away so if I send it to E I've actually made progress in the coordinate space, so that's a good thing. And then A can do the same thing for its other neighbors it can look at B if you plug in these numbers, and you can try this yourself, you'll figure out the B is 91.1 units away, and C is a 115.5 units away. So one question is which of these nodes would you choose as the next-hop for A? What's the best next-hop for A to choose? Well, there's a few options here, you could choose B, B makes progress, you could choose E, E also makes progress, so those are both good choices. C would be a bad choice because you're making negative progress in the space. If you send the packet to C, C's going to do the same computation it's going to say well A is probably the best next-hop for me, it'll send it back to A and you'll get loops. You always want to make progress. And a good heuristic is to maximize your progress in the space. So what traditional geographic routing does is it maximizes progress in this coordinate space. So A would send the packet to E because E makes the most progress. If we sent it to E we have the shortest remaining distance, so that's what A is going to do. It's going to look at it's neighbor table, do these computations, figure out that E is the closest to the destination and then it's going to send the packet to E. And then E's going to do the same thing, it's going to look at its neighbor table, do this computation for itself, each of its neighbors and it's going to figure out that I is the best next-hop. It's the node that makes the most progress to M we only have 57.8 more units left to go until we send it to I. So this approach, what you can see it's doing is it's kind of like sailing a ship on the ocean, you're kind of going in a certain direction. But the difference is when you do geographic routing you're limited in terms of where you can go. You can't just send the packet into an arbitrary place there has to be a node there, so you have a limited number of choices for your next-hop. So what geographic routing does is it looks at each of the neighbors of a node and then choose the one that makes the most progress in the space and then just kind of repeats this process. And you can see that if we keep doing this eventually we're going to make more and more progress. And eventually we're going to reach the destination because we're getting closer and closer. So finally we reach L and L says well I can send it to N or H or M, if I send it to M I've got 0 units of distance left, so it's pretty obviously the best choice. So that's geographic routing and it's based on this whole idea of greedy forwarding. If you have an algorithm and someone calls it a greedy, what they mean by that is it's an algorithm that makes a local decision. It makes a decision that just based on what it sees right now it's going to choose the best option that it sees, so here we're doing greedy forwarding in this geographic space. But there's a few different options for how we do greedy forwarding and the specific way you do it there's some there's some trade-offs. So here what we did is we chose the node that makes the most progress in this coordinate space, but there's a few other ways we could do this. There's this kind of philosophical question of how you measure progress to the destination? You know all along I've been saying you kind of want to choose the node that makes the most progress, minimize the remaining progress and that's a valid way to do it. So suppose I'm this source and I want to send the packet to the destination M, kind of deciding which of these neighbors to send the packet to next as the next-hop. Well, I have a few options to choose from here. One option is A can send to D, D is within its radio range. And this is an approach known as greedy routing this is what I talked about in the previous slide. So greedy routing is you choose the node with the minimum remaining distance to the destination, it's a valid way to do it. Another way to do it which also works and is sometimes used, is to minimize the straight line remaining distance to the destination. So what we do is we say, okay, we draw a line between the source and the destination and we look at all our neighbors and we choose the one that minimizes the remaining distance between the source and the destination. And this is called most forwarding progress within radius or MFR. And what you're doing here is you choose the node that makes the most progress along the straight line distance. So the trade-off here is if we're doing greedy routing we're kind of minimizing remaining distance, but with most forwarding progress we're maximizing the forwarding progress we make at each hop. Another alternative is to do something called nearest with forwarding progress. It is a little bit non-intuitive, but what we're doing is we're looking at all our neighbors and we're actually forwarding to the one that kind of is nearest to us, nearest to the current hop, but still make some progress to the destination. So with this approach were choosing the nearest node that makes progress along the straight line distance, the nearest node not the furthest node. So one reason you might want to do this is because if you choose nodes that are far away like D and especially E these nodes are likely to be on the edge of your radio range, so they're making a lot of progress. But these are also the nodes that are most likely to be flaky because you're sending a long-distance your signal strength is likely to be low. So if you send to a close node it's much more likely your packets are going to go through. So this could be good for certain environments where you really care about reliability and your packets getting through. Another alternative way to do this is to do something called compass routing. And what you do here is you choose the node with the minimum angle between the node that you're sending to in the destination. So here what you do is your kind of steering your packets along a route. There's the original source, the destination you're sending to, you're kind of sending to it but you're not letting the packet go all over the place, your kind of keeping it on a straight line between the source and destination, and this is good If you care about locality. You're sending packets, maybe you have a bunch of nodes sensor nodes are kind of forming a tree to a route that's collecting data from sensor nodes. You want the tree to kind of converge quickly because you want to have caches along the way. You want to build a tree with not many nodes in it because you want to minimize your power usage. This is good for that because it's kind of constrains the tree or kind of constrains your forwarding to be along a single line as much as possible. So the point here is geographic routing there's different variants of it that can work. And so what we can do is we can kind of define these different metrics, these different ways of forwarding in a greedy ways that have these different trade-offs. And so you can kind of choose between these trade-offs, these approaches based on your particular environment. Okay, so there's these different approaches and they're all correct in some sense. They all make progress in the space given a certain set of underlying assumptions. But what are those assumptions? Does geographic routing always work? And the answer is unfortunately no, so this gets into the complexity of geographic routing. On its surface it's extremely simple protocol which makes it a great choice. For certain networks it's a wonderful choice to use because you don't have any updates at all. Think about AODV and DSR, these protocols kind of have to do network-wide floods every time you want to send a packet, so geographic routing doesn't require any floods at all, it's like magic. Every node just figures out its coordinates and it kind of sends data, extremely scalable approach. But it has some downsides which make it less than desirable for certain circumstances, and one is kind of this issue with voids. So to see how that can happen, so you have this network and A is sending this packet to 121, 65. So A is going to probably send it to C, that's the node that makes the most progress in this coordinate space, we can kind of just see that. And then what C going to do? Who's C going to send it to next? Well, you're looking at this and you're thinking well I hope it sends it to D. But that's not what geographic routing would do right? Geographic routing is going to choose to the node that makes the most progress in this coordinate space, which is going to be E. And here we have a problem, which is E has no neighbors which make more progress in the coordinate space than itself, so the packet is stuck. So this is a problem with traditional vanilla geographic routing. However, a lot of smart people from academia and industry have kind of noticed this problem and put a lot of thought into protocols that can deal with this problem. So there are solutions to it, but it adds to the complexity of the protocol. So there's this problem of dead ends or voids. So to deal with this problem there's an approach called perimeter forwarding. And perimeter forwarding is kind of this clever idea. And I don't know if you've ever been in like a corn maze or ever like try to solve a maze on a piece of paper. And there's a trick for doing those and once you learn this trick, you can solve any maze. And the trick is if you're in a corn maze or whatever, if you're stuck, you don't know where you are, you put your hand up, pick a hand you touch the touch the wall and then just keep your hand on the wall and just walk and eventually you're going to get out. because if you kind of trace the outline or trace the perimeter of the maze and just kind of going to keep going around eventually you're going to hit an exit. If you kind of think about it that makes sense because you're going to traverse every edge in the maze. And people have realized that this actually works for dealing with voids in geographic routing. And the idea is what you're going to do is you're going to route until you hit a dead end. And then once you hit the dead end, you're going to kind of trace a perimeter to get around the void, get around that place where you're stuck. And so there's certain situations where this works, there's certain situations where it doesn't work, so it's a little bit more complex than that we'll talk about that. But the idea is that if you have perimeter routing, you kind of walk around the perimeter that works unless there's closed faces. If you kind of reach a point where you're kind of stuck routing around an area over and over and so there's something called face routing which deals with that. So to kind of make this more clear, let's say we forwarded this packet to node E and let's start using our maze trick where we kind of put our hand out and we're kind of going to follow the the right hand rule. We're going to kind of turn right and we're going to repeatedly follow the rightmost edge as we go around. So E's going to say, okay, the packet reached a dead end, but I'm going to forward it backward around the perimeter. So it's going to send it to C and C's going to follow the right hand rule and send it to D, he's going to send it to F, so we kind of go around this perimeter and this is good because we got out of that void. But the problem is if we keep doing this, if we have a closed face, we're going to keep going in this loop, we're stuck in this loop, so we can't just do perimeter forwarding. We can in certain situations, if we have a network where we don't have closed faces, and you might have that if you have a dissemination tree or something like that perimeter forwarding is good enough. But if you don't have a situation like that you need something called face routing where we look at these polygons and these are called faces, and then what we do is we kind of switch faces. We kind of do geographic routing based on faces if that kind of makes sense. So to kind of make that more clearer, if we're doing face routing, what we'll do is we'll route using geographic routing, we'll route till we hit a dead end, and then we'll set a bit in the packet which says okay, we're doing face routing now. We hit a dead end we gotta start doing routing based on faces to kind of get around the void. And so we're going to still use the right hand rule and kind of trace around the outline of something of a face. But then when we hit the edge of a face we kind of route around this face, we hit a node, and we say if we keep going around this face, we're going to go back, we're going to make less progress in the coordinate space than our current node. Then what we do is we say, okay, we need to switch faces, we need to switch to the next face. And so F will do that, F will realize if I forward it back to C I'm going to make worst progress in the space, really I should forward it to G. So F is going to switch faces now we're on the yellow face. And then we're going to kind of keep going to to G, to H, into M, and then we reach the destination, so that's good. So it's starting to look a little bit more complicated, right? It's a clever approach, but it's more complicated and it's even worse because even this doesn't always work, so this kind of shows the complexity of geographic routing. It's good for certain environments depending on your topology and set up, but depending on the setup you might need some additional complexity to deal with things. So face routing and perimeter forwarding have some issues. Face routing can fail if the graph is non-planar, is kind of the issue here, where if you have a network and your nodes are laid out you have kind of these nice faces then what I showed you on the previous slide actually works, it's guaranteed to work. But what if you have cross edges? What if your topology isn't kind of set up with these clean polygons? Then you don't really have faces and you can get loops. So to address that you can planarize the graph. You can say, okay, I have this network with all these cross edges, I'll just remove the cross edges and then your graph is planar and then face routing will work. And there's distribute the protocols to do this which kind of analyze the graph and remove the cross edges and planarize it. And one approach to doing this uses relative neighborhood graphs where this is a distributed protocol because there's no central node that kind of owns the topology. And the way it works is an edge is allowed to exist in a relative neighborhood graph only if there does not exist another connected node r that is closer to both sides of that edge than they are to each other. So it turns out if each node kind of locally does this check then it can remove these extra edges from the graph and then your graph is planar and then it works. So long story short, this is geographic routing. It's intuitively very simple, it's amazingly scalable because you don't need network-wide flooding, it's amazing. Super scalable, super great for batteries, but it's a little annoying because it it doesn't quite work unless you have this additional complexity in it. And so you kind of need to think about whether what your network is and whether your network is planar or whether it's a tree. So there's certain topologies were geographic routing's great for and if you don't have those topologies then it's not so great for that. So this is something you can think about when you're designing your system. If you have the guarantees that you need for geographic routing to work it'd be simple, it's great. If it's more complicated, you may prefer something like AODV and DSR.