how can i decipher dns messages? - sockets

i'm writing a program to receive dns messages and respond an appropriate answer(a simple dns server that only reply A records).
but when i receive messages it's not like the described format in 1035 RFC.
for example this is a dns query generated by nslookup:
'\xe1\x0c\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x06google\x03com\x00\x00\x01\x00\x01'
i know about dns headers and bits as defined in 1035 RFC but why it should be in hex?
should i consider them as hex numbers or their utf-8 equivalents?
should my responses have this format too?

It's coming out as hexadecimal because it is a raw binary request, but you are presumably trying to print it out as a string. That is apparently how non-printable characters are displayed by whatever you are using to print it out; it escapes them as hex sequences.
You don't interpret this as "hex" or UTF-8 at all; you need to interpret the binary format described by the RFC. If you mention what language you're using, I (or someone else) might be able to describe to you how to handle data in a binary format like this.
Untile then, let's take a look at RFC 1035 and see how to interpret your query by hand:
The header contains the following fields:
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Each line there is 16 bits, so that's 12 bytes. Lets fill our first 12 bytes into there:
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID = e10c | \xe1 \x0c
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| 0| Opcode=0 | 0| 0| 1| 0| Z=0 | RCODE=0 | \x01 \x00
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT = 1 | \x00 \x01
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT = 0 | \x00 \x00
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT = 0 | \x00 \x00
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT = 0 | \x00 \x00
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
So. We have a query with ID = e10c (just an arbitrary number so the client can match queries up with responses), QR = 0 indicates that it's a query, opcode = 0 indicates that it's a standard query, AA and TC are for responses, RD = 1 indicates that recursion is desired (we are making a recursive query to our local nameserver). Z is reserved for future use, RCODE is a response code for responses. QDCOUNT = 1 indicates that we have 1 question, all the rest are numbers of different types of records in a response.
Now we come to the questions. Each has the following format:
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ QNAME /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QTYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QCLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
QNAME is the name the query is about. The format is one octet indicating the length of a label, followed by the label, terminated by a label with 0 length.
So we have:
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| LEN = 6 | g | \x06 g
| o | o | o o
| g | l | g l
| e | LEN = 3 | e \x03
| c | o | c o
| m | LEN = 0 | m \x00
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QTYPE = 1 | \x00 \x01
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QCLASS = 1 | \x00 \x01
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
This indicates that the name we are looking up is google.com (sometimes written as google.com., with the empty label at the end made explicit). QTYPE = 1 is an A (IPv4 address) record. QCLASS = 1 is an IN (internet) query. So this is asking for the IPv4 address of google.com.

Related

KDB Select average of List data type for each row

Is there anyway in KDB to get the average of each row which has list data type ?
E.g. I have table with column ID and Size :
| ID | size |
|----|-----------|
| 1 | [1,3] |
| 2 | [3,3,3] |
| 3 | [4,2,4,2] |
In select , I want ID and avg of size :
| ID | avg |
|----|-----|
| 1 | 2 |
| 2 | 3 |
| 3 | 3 |
q)t:([]id:1 2 3;size:(1 3;3 3 3;4 2 4 2))
q)t
id size
----------
1 1 3
2 3 3 3
3 4 2 4 2
q)select id,avg each size from t
id size
-------
1 2
2 3
3 3

Finding distinct values across multiple columns

I want to create a function that finds the the number of pno's with the sid (staff id) that have worked on it.
So for example if I wanted to find the sid's corresponding to pno = 1
select sid_worked_on(1)
count
-------
2
I would have 2 as sid 0 and 1 have worked on it.
This is the joined table from 3 different tables.
pno | a_sid | b_sid | c_sid
-----+--------+--------+--------
1 | 0 | 0 | 0
4 | 4 | 4 | 6
5 | 4 | 4 | 5
2 | 0 | 0 | 0
1 | 0 | 1 | 0
7 | 5 | 4 | 4
7 | 5 | 5 | 4
5 | 4 | 4 | 4
4 | 4 | 5 | 6
7 | 5 | 4 | 1
7 | 5 | 5 | 1
6 | 5 | 4 | 5
My only way of thinking how to do it would be to "flatten" the table into one column since there is no need for multiple columns and do distinct sid, but I haven't learnt how to do that yet.
pno | sid
-----+--------
1 | 0 |
4 | 4 |
5 | 4 |
2 | 0 |
1 | 0 |
7 | 5 |
7 | 5 |
5 | 4 |
4 | 4 |
7 | 5 |
7 | 5 |
6 | 5 |
--where the new table starts
1 | 0 |
4 | 4 |
5 | 4 |
2 | 0 |
1 | 1 |
7 | 4 |
...
...
I also thought to create a table and going through each value, so
create table
for each row where pno = 1
check if a_sid in table
if not then add a_sid to table
check if b_sid in table
if not then add b_sid to table
check if c_sid in table
if not then add c_sid to table
Would there be a better way of doing this?
Use UNION
SELECT pno, a_sid from table
UNION
SELECT pno, b_sid from table
UNION
SELECT pno, c_sid from table
Depending on whether you want duplicated entries of the same pno with the same column on the right side, you can use UNION ALL instead of UNION.
You can create a view with this query.

How do I calculate shortest path between Origin - Destination pairs using pgRouting?

First of all I just want to state that I'm very new to GIS and that I'm probably not that great at the terminology yet, so bear with me.
I'm having my internship right now and have been tasked with making a bike commuting potential analysis. The data I'm using is road layer (which I have already created a topology for using pgr_createTopology) and two point layers for where individuals live and work created from the centroids of 500x500m squares.
I have managed to do some sort of calculation between my two point layers using pgr_dijkstraCost that looks like this:
SELECT *
FROM pgr_dijkstraCost(
'SELECT gid AS id,
source,
target,
extlen / 1.3 / 60 AS cost
FROM roads',
array(select source FROM living),
array(select target FROM work),
directed := false);
The source and target value in the living and work test tables has a value from 1 to 50 since I initially though that I could make the calculation by calculating when source and target has the same value. I now know that's not possible since pgr_dijkstra wont allow calculations when they are the same. The result I'm getting right now is for every combination I don't want. The final calculation will be for around 300 000 pairs.
So is there a way for me to only do the calculation on specified pairs and not for every possible combination?
Starting from Version 3.1 there is this signature
pgr_dijkstra(Edges SQL, Combinations SQL, end_vids, [, directed])
RETURNS SET OF (seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost)
OR EMPTY SET
example usage (taken from the pgRouting documentation)
CREATE TABLE combinations_table (
source BIGINT,
target BIGINT
);
INSERT INTO combinations_table (source, target)
VALUES (1, 2), (1, 4), (2, 1), (2, 4), (2, 17);
SELECT * FROM pgr_dijkstra(
'SELECT id, source, target, cost, reverse_cost FROM edge_table',
'SELECT * FROM combinations_table',
FALSE
);
seq | path_seq | start_vid | end_vid | node | edge | cost | agg_cost
----+----------+-----------+---------+------+------+------+----------
1 | 1 | 1 | 2 | 1 | 1 | 1 | 0
2 | 2 | 1 | 2 | 2 | -1 | 0 | 1
3 | 1 | 1 | 4 | 1 | 1 | 1 | 0
4 | 2 | 1 | 4 | 2 | 2 | 1 | 1
5 | 3 | 1 | 4 | 3 | 3 | 1 | 2
6 | 4 | 1 | 4 | 4 | -1 | 0 | 3
7 | 1 | 2 | 1 | 2 | 1 | 1 | 0
8 | 2 | 2 | 1 | 1 | -1 | 0 | 1
9 | 1 | 2 | 4 | 2 | 2 | 1 | 0
10 | 2 | 2 | 4 | 3 | 3 | 1 | 1
11 | 3 | 2 | 4 | 4 | -1 | 0 | 2
(11 rows)

double precision in MATLAB

So double precision takes 64 bits in MATLAB. I know that 0 or 1 will take one bit.
But when I type realmax('double') I get a really big number 1.7977e+308. How can this number be saved in only 64 bits?
Would appreciate any clarafication. Thanks.
This is not a MATLAB question. A 64-bit IEEE 754 double-precision binary floating-point format is represented in this format:
bit layout:
| 0 | 1 | 2 | ... | 11 | 12 | 13 | 14 | ... | 63 |
| sign | exponent(E) (11 bit) | fraction (52 bit) |
The first bit is the sign:
0 => +
1 => -
The next 11 bits are used for the representation of the exponent. So we can have integers all the way to +2^10-1 = 1023. Wait... that does not sound good! To represent large numbers, the so-called biased form is used in which the value is represented as:
2^(E-1023)
where E is what the exponent represents. Say, The exponent bits are like these examples:
Bit representation of the exponent:
Bit no: | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
Example 1: | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
Example 2: | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
Example 3: | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
Example 4: | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
Example 5: | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Base 10 representation:
Example 1 => E1: 1
Example 2 => E2: 32
Example 3 => E3: 515
Example 4 => E4: 2046
Example 5 => E4: Infinity or NaN (**** Special case ****)
Biased form:
Example 1 => 2^(E1-1023) = 2^-1022 <= The smallest possible exponent
Example 2 => 2^(E2-1023) = 2^-991
Example 3 => 2^(E3-1023) = 2^-508
Example 4 => 2^(E4-1023) = 2^+1023 <= The largest possible exponent
Example 5 => 2^(E5-1023) = Infinity or NaN
When E meets 0 < E < 2047 then the number is known as a normalized number represented by:
Number = (-1)^sign * 2^(E-1023) * (1.F)
but if E is 0, then the number if known as a denormalized number represented by:
Number = (-1)^sign * 2^(E-1022) * (0.F)
Now F is basically the what is determined by the fraction bits:
// Sum over i = 12, 13, ..... , 63
F = sum(Bit(i) * 2^(-i))
and Bit(i) refers the ith bit of the number. Examples:
Bit representation of the fraction:
Bit no: | 12 | 13 | 14 | 15 | ... ... ... ... | 62 | 63 |
Example 1: | 0 | 0 | 0 | 0 | 0 ... .... 0 | 0 | 1 |
Example 2: | 1 | 0 | 0 | 0 | 0 ... .... 0 | 0 | 0 |
Example 3: | 1 | 1 | 1 | 1 | 1 ... .... 1 | 1 | 1 |
F value assuming 0 < E < 2047:
Example 1 => 1.F1 = 1 + 2^-52
Example 2 => 1.F2 = 1 + 2^-1
Example 3 => 1.F3 = 1 + 1 - 2^-52
But when I type realmax('double') I get a really big number
1.7977e+308. How can this number be saved in only 64 bits?
realmax('double')'s binary representation is
| sign | exponent(E) (11 bit) | fraction (52 bit) |
0 11111111110 1111111111111111111111111111111111111111111111111111
Which is
+2^1023 x (1 + (1-2^-52)) = 1.79769313486232e+308
I took some definitions and examples from this Wikipedia page.

Architecture Design for Bus Routing with Time

This is to confirm if my design is good enough or get the better ideas to solve the bus routing problem with time. Here is my solution with the primary steps given below:
Have one edges table which represents all the edges (the source and target represent vertices (bus stops):
postgres=# select id, source, target, cost from busedges;
id | source | target | cost
----+--------+--------+------
1 | 1 | 2 | 1
2 | 2 | 3 | 1
3 | 3 | 4 | 1
4 | 4 | 5 | 1
5 | 1 | 7 | 1
6 | 7 | 8 | 1
7 | 1 | 6 | 1
8 | 6 | 8 | 1
9 | 9 | 10 | 1
10 | 10 | 11 | 1
11 | 11 | 12 | 1
12 | 12 | 13 | 1
13 | 9 | 15 | 1
14 | 15 | 16 | 1
15 | 9 | 14 | 1
16 | 14 | 16 | 1
Have a table which represents bus details like from time, to time, edge etc.
NOTE: I have used integer format for "from" and "to" column for faster results as I can do an integer query, but I can replace it with any better format if available.
postgres=# select id, "busedgeId", "busId", "from", "to" from busedgetimes;
id | busedgeId | busId | from | to
----+-----------+-------+-------+-------
18 | 1 | 1 | 33000 | 33300
19 | 2 | 1 | 33300 | 33600
20 | 3 | 2 | 33900 | 34200
21 | 4 | 2 | 34200 | 34800
22 | 1 | 3 | 36000 | 36300
23 | 2 | 3 | 36600 | 37200
24 | 3 | 4 | 38400 | 38700
25 | 4 | 4 | 38700 | 39540
Use dijkstra algorithm to find the nearest path.
Get the upcoming buses from the busedgetimes table in the earliest first order for the nearest path detected by dijkstra algorithm. => This leads to a bit complex query though.
Can I do any kind of improvements to this, or are there any better designs?
Links to docs, articles related to this would be really helpful.
This is totally normal and the regular way to do it. See also,
PgRouting Example