go – modified julienschmidt/httprouter with group routing

I’m a bit tired today to solve this. I’m using a modified version of julienschmidt/httprouter with support for group routes based on this Gist from this Issue

My code can be found here: https://github.com/prologic/twtxt/pull/66 along with the failing unit tests I’m struggling with.

Posted here for posterity:

$ go test .
--- FAIL: TestGroup (0.00s)
    router_test.go:145: Grouped path /foo not registered
    router_test.go:145: Grouped path /foo/group not registered
    router_test.go:145: Grouped path /foo/baz/group not registered
    router_test.go:145: Grouped path /bar/group not registered
--- FAIL: TestMiddleware (0.00s)
    router_test.go:176: Middleware registered by Use() under "/" not touched
    router_test.go:179: Middleware registered by Group() under "/foo" not touched
FAIL
FAIL    github.com/prologic/twtxt   0.214s
FAIL

Would someone better at Go then me please help me review this code and help me fix either the bug that exists or the unit tests?

Thank you!

Routing to Google Map services issue

I’m developing an Android application on a tablet that must use both Ethernet (trough USB adapter) and internal LTE carrier (or WiFi) to access Google Map services.
When I connect the USB/Ethernet adapter the application becomes unable to authenticate on Google Map services and therefore map is not populated at all, when USB is unplugged the application works correctly and Google Map component correctly shows its content up to the maximum level of detail.

May this depend on a routing issue? How can I fix this?

BTW the Ethernet port on this device is used only to access other devices located on a private LAN whose network is known.

PS The device is a Samsung Tab S2 running Android 7.0.

— UPDATE —

I’m not certain of the missing authentication since USB port is busy and I cannot see app logcat dump in realtime but the behaviour is the same I can observe if Google Map authentication fails for some other reason (WiFi turned off while debugging, invalid Google Map API key etc).

angular 2+ – Multiple RouterOutlets and Routing from Subcomponent

I have two outlets (primary and second). The routes are defined like this:

const routes: Routes = (
  { path: '', redirectTo: '/home(second:list)', pathMatch: 'full' },
  { path: 'home', component: HomeComponent },
  { path: 'list', component: MyItemListComponent, outlet: 'second' },
  { path: 'navigation', component: NavigationComponent, outlet: 'second' },
);

In a nutshell, home is always the primary router-outlet content and the second router-outlet switches between list and navigation. Therefore I have the following two valid routes:

localhost:4200/home(second:list)
localhost:4200/home(second:navigation)

When I do the routing like this, it only works on the level of the AppComponent:

<a (routerLink)="({ outlets: { primary: 'home', second: 'list' }})">Home-List</a>
<br>
<a (routerLink)="({ outlets: { primary: 'home', second: 'navigation' }})">Home-Navigation</a>

For routing from a subcomponent I need the following:

<a (routerLink)="('/', { outlets: { primary: 'home', second: 'list' }})">Home-List</a>
<br>
<a (routerLink)="('/', { outlets: { primary: 'home', second: 'navigation' }})">Home-Navigation</a>

Is this the correct approach (assuming that the primary outlet is not always ‘home’)?

api – How should I handle a scalability problem during routing my requests from server?

I have faced a problem with the initial design of my system where sensitive information was being sent to the front-end and front-end was responsible for calling 3rd party APIs. As you have probably guessed it was extremely vulnerable to attacks. To remedy this I added a back-end system to proxy those requests and call the 3rd party APIs on behalf of front-end. The issue with this approach is it is not scalable at all. I am currently looking at additional 15 servers to handle the current load and it is increasing day by day.

Any advice on how can I remove this back-end requirement? is there any way to make the front-end still call the APIs but secure the data?

How would blockchain help with logistics routing software?

I have been doing some research on the potential capabilities of blockchain tech and I have seen some companies tease that there could be a way to automate logistics. Specifically for trucking and shipping companies. I understand the basic way that blockchain works, but I don’t understand how a distributed ledger would automate the routing process.

Any and all answers are appreciated!

url routing – Is this URL router production ready c++ code?

So I’ve written a URL router which also allows for wildcards aka path parameters.

A URL like /users/{uuid} can be added and then, when a user sends a request to the server with the following target /users/955b2a88-ae80-11ea-b3de-0242ac130004, the uuid will then equal 955b2a88-ae80-11ea-b3de-0242ac130004.

Example:

PathMatcher<int> matcher(-1);
matcher.add_path("/users/{uuid}", 1);

Parameters parameters;
assert(matcher.match("/users/9c4ceec8-f929-434e-8ff1-837dd54b7b56", parameters) == 1);
assert(parameters.find("uuid", "") == "9c4ceec8-f929-434e-8ff1-837dd54b7b56");

I have learnt c++ through stackoverflow, therefore I dont really have an idea how production ready code should look like.

Id like to know what should be written differently and would could be improved.

If youd like to run the code, it is hosted on github with an example main.cpp.

    typedef std::string string_t;
    
    class Parameters {
        std::vector<std::pair<string_t, string_t>> parameters_;
    
    public:
    
        void add(string_t& name, string_t& value) {
            parameters_.emplace_back(name, value);
        }
    
        string_t find(string_t name, string_t default_="") {
            for(auto & parameter : parameters_) {
                if(parameter.first == name) return parameter.second;
            }
            return default_;
        }
    
        void clear() {
            parameters_.clear();
        }
    };

    template<typename Result>
    class PathMatcher {
    
        struct Path {
            char character;
            std::vector<Path *> children;
            std::optional<Result> result;
    
            Path(char character, std::optional<Result> result) : character(character), result(result) {}
    
            ~Path() {
                for(size_t i = 0; i < children.size(); i++) {
                    delete children(i);
                }
            }
        };
    
        Path *
        find_child(char character, std::vector<Path *> &parent, bool findWildcard = false, Path **wildcard = nullptr) {
            Path *child = nullptr;
            for (size_t i = 0; i < parent.size(); i++) {
                if (parent(i)->character == character) {
                    child = parent(i);
                    // If wildcards are not wanted, there is no need to continue
                    if (!findWildcard) break;
                } else if (findWildcard && parent(i)->character == wildcard_open_) {
                    (*wildcard) = parent(i);
                    // If child has already been found, there is no need to continue
                    if (child != nullptr) break;
                }
            }
            return child;
        }
    
        Path *create_path(std::vector<Path *> &parent, char character, std::optional<Result> value) {
            Path *route = new Path(character, value);
            parent.push_back(route);
            return route;
        }
    
        void insert_path(string_t &path, Result &result, Path *step = nullptr, int path_pos = 0) {
            /*
             * Recursively creates path. A path contains a vector with child paths.
             * These linked paths create a chain which can be walked down.
             * If we input /users/a and /users/b the following chain would be created.
             * / -> u -> s -> e -> r -> s -> / -> a
             *                                 -> b
             *
             * Now if you want to match against an input, this chain can be walked down until a path no longer contains the matching character.
             * If the input would equal /users/c, the chain would be walked until the last '/' and then failing because it only contains the children a & b, not c.
             *
             * The last two paths (a & b) will contains a value. This value states that the path has reached its end.
             */
            assert(path.size() > 1);
            if (path_pos == path.size() - 1) {
                // last insertion accompanied by ending value
                Path *child = find_child(path(path_pos), step->children);
    
                if (child != nullptr) {
                    assert(!child->result); // Cant already have a value
                    child->result = result;
                } else {
                    create_path(step->children, path(path_pos), result);
                }
            } else {
    
                Path *child;
                if (path_pos == 0) {
                    child = find_child(path(path_pos), paths_);
                } else {
                    child = find_child(path(path_pos), step->children);
                }
    
                if (child == nullptr && path_pos == 0) {
                    child = create_path(paths_, path(path_pos), std::nullopt);
                } else if (child == nullptr) {
                    child = create_path(step->children, path(path_pos), std::nullopt);
                }
    
                return insert_path(path, result, child, path_pos + 1);
            }
        }
    
        void get_wildcard_name(Path **wildcard, string_t &wildcard_name) {
            /*
             * /users/{uuid} and users/{uuid}/friends is allowed
             * /users/{uuid} and users/{id}/friends is not allowed, because wildcards at the same positions must match
             *
             * This method walks down the chain until the wildcard_close_ character has been found. Everything between start and end is appended to the value.
             */
            assert((*wildcard)->children.size() == 1);
            if ((*wildcard)->children(0)->character != wildcard_close_) {
                wildcard_name.append(1, (*wildcard)->children(0)->character);
                *wildcard = (*wildcard)->children(0);
                get_wildcard_name(wildcard, wildcard_name);
            } else {
                *wildcard = (*wildcard)->children(0);
            }
        }
    
        string_t get_wildcard_value(string_t &path, size_t &pos) {
            // Walks down the input until the trailing_wildcard_ is found or the end is reached, everything between equals the wildcard value
            int begin = pos;
            for (; pos < path.size() - 1; pos++) {
                if (path(pos + 1) == trailing_wildcard_) {
                    return path.substr(begin, pos - begin + 1);
                }
            }
            return path.substr(begin);
        }
    
        std::vector<Path *> paths_;
        Result default_;
        char wildcard_open_;
        char wildcard_close_;
        char trailing_wildcard_;
    
    public:
    
        PathMatcher(Result default_, char wildcard_open='{', char wildcard_close='}', char trailing_wildcard='/')
            : default_(default_), wildcard_open_(wildcard_open), wildcard_close_(wildcard_close), trailing_wildcard_(
                                                                                                                trailing_wildcard) {}
    
    
        virtual ~PathMatcher() {
            for(size_t i = 0; i < paths_.size(); i++) {
                delete paths_(i);
            }
        }
    
        void add_path(string_t path, Result value) {
            insert_path(path, value);
        }
    
        Result match(string_t path, Parameters &variables) {
            /*
             * Starts at paths_ and continues trying to find children matching the next characters in input path.
             * If there is no child which matches the next character, but there was a wildcard_open_ as a child,
             * the code jumps back to it and sets a Parameters value for the wildcard with its value and then continues normally.
             */
            Path *step = find_child(path(0), paths_);
            if (step == nullptr) return default_;
    
            Path *lastWildcard = nullptr;
            size_t lastWildcardPos;
            size_t i = 1;
            for (; i < path.size() - 1 && step != nullptr; i++) {
    
                Path *nextWildcard = nullptr;
                step = find_child(path(i), step->children, true, &nextWildcard);
    
                if (nextWildcard != nullptr && nextWildcard != lastWildcard) {
                    lastWildcardPos = i;
                    lastWildcard = nextWildcard;
                }
                if (path(i) == trailing_wildcard_) {
                    lastWildcard = nullptr;
                }
    
                if (step == nullptr && lastWildcard != nullptr) {
                    i = lastWildcardPos;
    
                    string_t wildcard_name;
                    get_wildcard_name(&lastWildcard, wildcard_name);
                    string_t wildcard_value = get_wildcard_value(path, i);
                    variables.add(wildcard_name, wildcard_value);
    
                    if (i == path.size() - 1) {
                        // Wildcard value reaches end
                        if (!lastWildcard->result) return default_;
                        return lastWildcard->result.value();
                    } else {
                        step = lastWildcard;
                    }
                }
            }
    
            if (step == nullptr) return default_;
    
            Path *wildcard = nullptr;
            Path *result = find_child(path(path.size() - 1), step->children, true, &wildcard);
    
            if(result != nullptr && result->result) return result->result.value();
            else if(wildcard != nullptr) {
                // find wildcard ending and check if it contains a value
                string_t wildcardName;
                get_wildcard_name(&wildcard, wildcardName);
    
                if(!wildcard->result) return default_;
    
                string_t value = path.substr(path.size() - 1);
                variables.add(wildcardName, value);
                return wildcard->result.value();
            }
    
            return default_;
        }
    };

networking – Routing issue for windows with multiple NICs

I have a routing issue on a windows box. The windows box has three NIC’s with ip’s:

  1. 10.87.6.27 (no gateway set)
  2. 10.87.11.27 (no gateway set)
  3. 10.87.60.51 (gateway = 10.87.60.254)

When I contact a host in 10.87.11.0/24 (for example 10.87.11.212) the windows machine sends the traffic to 10.87.60.254, which routes it to 10.87.11.212. Because the windows box has a NIC directly in 10.87.11.0/24 (i.e. 10.87.11.27), i want it to send the traffic directly to that host instead of going over 10.87.60.254.

I changed the metric on the routing table. From inspecting the routing table I would expect the windows box to send the traffic directly to 10.87.11.212. What am I overlooking here?

The “route print” command gives the following output:
Output route print

The “tracert” command gives the following: Output trace route

routing – Linux default gateway wrong?

I deployed a VMware vCloud appliance and before deployment I’m asked to enter the IP addresses this appliance should use and the default gateway. This appliance has 2 IP addresses and nics by default and they should be in the same subnet.

So the info I entered was:
10.248.2.10/24 for eth0
10.248.2.20/24 for eth1
Default gateway is 10.248.2.254

Now I run into a strange issue. When I ping both IP addresses from a computer in the same subnet, all is fine. When I ping from a computer in a different subnet, I only get a reply from the 10.248.2.20 address (eth1). When I login to the appliance I can ping the computer in the same subnet as well as the computer in the different subnet.

The network guys have assured me there is no firewall blocking this traffic.

Not sure where it is going wrong. I was thinking maybe the routing table is incorrect? Shouldn’t there be only one “default” destination? But then again, I would expect traffic coming in on eth0 or eth1, to also leave over the same interface it arrived, or is that not a correct assumption?

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         10.248.2.254    0.0.0.0         UG    0      0        0 eth1
default         10.248.2.254    0.0.0.0         UG    0      0        0 eth0
10.248.2.0      *               255.255.255.0   U     0      0        0 eth1
10.248.2.0      *               255.255.255.0   U     0      0        0 eth0

Any clues where to look for?

Hostinger null routing shared hosting IP due to DDOS


Hi folks,

Is it common practice these days to null route shared hosting IPs incase of DDOS attacks? I thought thats what firewalls were for?

Just got this from hostinger support as a response to a support ticket I created saying my website has been down for over an hour…

Hello there, I hope you are having a wonderful day blush

Sorry for the inconveniences! It seems that there’s a DDoS attack currently targeting the IP that is assigned to your IP address. As a precaution, our administrators have null routed the IP address which causes the website to be temporarily unavailable. The monitoring team is currently keeping watch of this situation, and they will make sure to get the websites back online as soon as the attack is stopped.

If you have any more questions about this or other topic, let me know, I would be more than happy to answer them!

Thanks!

PS: I have been out of the tech side of things for a while now, thus the seemingly newbie question.

How does Tor preserve anonymity if it uses normal Internet Routing?

I’m studying Tor and Onion Routing and I don’t understand how it preserves anonymity if the Internet routing is still done using public ip addresses.

Let’s suppose we have the following Tor circuit: Tor Browser -> A -> B -> C -> Server.
If someone follows the traffic from relay to relay then the anonymity is broken.
Even though it uses 3 layers of encryption the routing is done by public ip addresses which are in clear text in the ip header.

Or when the server responds back it sends the packets to the public ip address of C. Some authority could follow to route from the server to C to B to A to the client and knows that the client is communicating with the server.

Can anyone say if I’m right? Or the entire security of Tor is based on the fact that no one can ever control all 3 relays (or statistically is very improbable)?