Aluf

What happens when you enter... fully Explained and combined

Jan 24th, 2015
381
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.95 KB | None | 0 0
  1. What happens when...
  2. ====================
  3. MADE BY ALUF
  4. ------------
  5. @2015-C
  6.  
  7. This repository is an attempt to answer the age old interview question "What
  8. happens when you type google.com into your browser's address box and press
  9. enter?"
  10.  
  11. Except instead of the usual story, we're going to try to answer this question
  12. in as much detail as possible. No skipping out on anything.
  13.  
  14. This is a collaborative process, so dig in and try to help out! There's tons of
  15. details missing, just waiting for you to add them! So send us a pull request,
  16. please!
  17.  
  18. This is all licensed under the terms of the `Creative Commons Zero`_ license.
  19.  
  20. Table of Contents
  21. ====================
  22.  
  23. .. contents::
  24. :backlinks: none
  25. :local:
  26.  
  27. The "enter" key bottoms out
  28. ---------------------------
  29.  
  30. To pick a zero point, let's choose the enter key on the keyboard hitting the
  31. bottom of its range. At this point, an electrical circuit specific to the enter
  32. key is closed (either directly or capacitively). This allows a small amount of
  33. current to flow into the logic circuitry of the keyboard, which scans the state
  34. of each key switch, debounces the electrical noise of the rapid intermittent
  35. closure of the switch, and converts it to a keycode integer, in this case 13.
  36. The keyboard controller then encodes the keycode for transport to the computer.
  37. This is now almost universally over a Universal Serial Bus (USB) or Bluetooth
  38. connection, but historically has been over PS/2 or ADB connections.
  39.  
  40. *In the case of the USB keyboard:*
  41.  
  42. - The USB circuitry of the keyboard is powered by the 5V supply provided over
  43. pin 1 from the computer's USB host controller.
  44.  
  45. - The keycode generated is stored by internal keyboard circuitry memory in a
  46. register called "endpoint".
  47.  
  48. - The host USB controller polls that "endpoint" every ~10ms (minimum value
  49. declared by the keyboard), so it gets the keycode value stored on it.
  50.  
  51. - This value goes to the USB SIE (Serial Interface Engine) to be converted in
  52. one or more USB packets that follows the low level USB protocol.
  53.  
  54. - Those packets are sent by a differential electrical signal over D+ and D-
  55. pins (the middle 2) at a maximum speed of 1.5 Mb/s, as an HID
  56. (Human Interface Device) device is always declared to be a "low speed device"
  57. (USB 2.0 compliance).
  58.  
  59. - This serial signal is then decoded at the computer's host USB controller, and
  60. interpreted by the computer's Human Interface Device (HID) universal keyboard
  61. device driver. The value of the key is then passed into the operating
  62. system's hardware abstraction layer.
  63.  
  64. *In the case of Virtual Keyboard (as in touch screen devices):*
  65.  
  66. - In modern capacitive touch screens when the user puts his finger on the
  67. screen a tiny amount of current from the electrostatic field of the
  68. conductive layer gets transferred to the finger completing the circuit
  69. and creating a voltage dropping at that point on the screen so that the
  70. ``screen controller`` raises an interrupt reporting the coordinate of
  71. the 'click'.
  72.  
  73. - Then the mobile OS notifies the current focused application of a click event
  74. in one of its GUI elements (which now is the virtual keyboard application
  75. buttons).
  76.  
  77. - The virtual keyboard can now raise a software interrupt for sending a
  78. 'key pressed' message back to the OS.
  79.  
  80. - Which in turn notifies the current focused application of a 'key pressed'
  81. event.
  82.  
  83.  
  84. Interrupt fires [NOT for USB keyboards]
  85. ---------------------------------------
  86.  
  87. The keyboard sends signals on its interrupt request line (IRQ), which is mapped
  88. to an ``interrupt vector`` (integer) by the interrupt controller. The CPU uses
  89. the ``Interrupt Descriptor Table`` (IDT) to map the interrupt vectors to
  90. functions (``interrupt handlers``) which are supplied by the kernel. When an
  91. interrupt arrives, the CPU indexes the IDT with the interrupt vector and runs
  92. the appropriate handler. Thus, the kernel is entered.
  93.  
  94. (On Windows) A ``WM_KEYDOWN`` message is sent to the app
  95. --------------------------------------------------------
  96.  
  97. The HID transport passes the key down event to the ``KBDHID.sys`` driver which
  98. converts the HID usage into a scancode. In this case the scan code is
  99. ``VK_RETURN`` (``0x0D``). The ``KBDHID.sys`` driver interfaces with the
  100. ``KBDCLASS.sys`` (keyboard class driver). This driver is responsible for
  101. handling all keyboard and keypad input in a secure manner. It then calls into
  102. ``Win32K.sys`` (after potentially passing the message through 3rd party
  103. keyboard filters that are installed). This all happens in kernel mode.
  104.  
  105. ``Win32K.sys`` figures out what window is the active window through the
  106. ``GetForegroundWindow()`` API. This API provides the window handle of the
  107. browser's address box. The main Windows "message pump" then calls
  108. ``SendMessage(hWnd, WM_KEYDOWN, VK_RETURN, lParam)``. ``lParam`` is a bitmask
  109. that indicates further information about the keypress: repeat count (0 in this
  110. case), the actual scan code (can be OEM dependent, but generally wouldn't be
  111. for ``VK_RETURN``), whether extended keys (e.g. alt, shift, ctrl) were also
  112. pressed (they weren't), and some other state.
  113.  
  114. The Windows ``SendMessage`` API is a straightforward function that
  115. adds the message to a queue for the particular window handle (``hWnd``).
  116. Later, the main message processing function (called a ``WindowProc``) assigned
  117. to the ``hWnd`` is called in order to process each message in the queue.
  118.  
  119. The window (``hWnd``) that is active is actually an edit control and the
  120. ``WindowProc`` in this case has a message handler for ``WM_KEYDOWN`` messages.
  121. This code looks within the 3rd parameter that was passed to ``SendMessage``
  122. (``wParam``) and, because it is ``VK_RETURN`` knows the user has hit the ENTER
  123. key.
  124.  
  125. (On OS X) A ``KeyDown`` NSEvent is sent to the app
  126. --------------------------------------------------
  127.  
  128. The interrupt signal triggers an interrupt event in the I/O Kit kext keyboard
  129. driver. The driver translates the signal into a key code which is passed to the
  130. OS X ``WindowServer`` process. Resultantly, the ``WindowServer`` dispatches an
  131. event to any appropriate (e.g. active or listening) applications through their
  132. Mach port where it is placed into an event queue. Events can then be read from
  133. this queue by threads with sufficient privileges calling the
  134. ``mach_ipc_dispatch`` function. This most commonly occurs through, and is
  135. handled by, an ``NSApplication`` main event loop, via an ``NSEvent`` of
  136. ``NSEventType`` ``KeyDown``.
  137.  
  138. (On GNU/Linux) the Xorg server listens for keycodes
  139. ---------------------------------------------------
  140.  
  141. When a graphical ``X server`` is used, ``X`` will use the generic event
  142. driver ``evdev`` to acquire the keypress. A re-mapping of keycodes to scancodes
  143. is made with ``X server`` specific keymaps and rules.
  144. When the scancode mapping of the key pressed is complete, the ``X server``
  145. sends the character to the ``window manager`` (DWM, metacity, i3, etc), so the
  146. ``window manager`` in turn sends the character to the focused window.
  147. The graphical API of the window that receives the character prints the
  148. appropriate font symbol in the appropriate focused field.
  149.  
  150.  
  151. Parse URL
  152. ---------
  153.  
  154. * The browser now has the following information contained in the URL (Uniform
  155. Resource Locator):
  156.  
  157. - ``Protocol`` "http"
  158. Use 'Hyper Text Transfer Protocol'
  159.  
  160. - ``Resource`` "/"
  161. Retrieve main (index) page
  162.  
  163.  
  164. Is it a URL or a search term?
  165. -----------------------------
  166.  
  167. When no protocol or valid domain name is given the browser proceeds to feed
  168. the text given in the address box to the browser's default web search engine.
  169.  
  170.  
  171. Check HSTS list...
  172. ------------------
  173.  
  174. Convert non-ASCII Unicode characters in hostname
  175. ------------------------------------------------
  176.  
  177. * The browser checks the hostname for characters that are not in ``a-z``,
  178. ``A-Z``, ``0-9``, ``-``, or ``.``.
  179. * Since the hostname is ``google.com`` there won't be any, but if there were
  180. the browser would apply `Punycode`_ encoding to the hostname portion of the
  181. URL.
  182.  
  183. DNS lookup...
  184. -------------
  185.  
  186. * Browser checks if the domain is in its cache.
  187. * If not found, calls ``gethostbyname`` library function (varies by OS) to do
  188. the lookup.
  189. * ``gethostbyname`` checks if the hostname can be resolved by reference in the
  190. local ``hosts`` file (whose location `varies by OS`_) before trying to
  191. resolve the hostname through DNS.
  192. * If ``gethostbyname`` does not have it cached nor in the ``hosts`` file then a
  193. request is made to the known DNS server that was given to the network stack.
  194. This is typically the local router or the ISP's caching DNS server.
  195.  
  196. * The local DNS server is looked up.
  197.  
  198. * If the DNS server is on the same subnet the ARP cache is checked for an ARP
  199. entry for the DNS server. If there is no entry in the ARP cache we do the
  200. ``ARP process`` (see below) for the DNS server. If there is an entry in the
  201. ARP cache, we get the information: DNS.server.ip.address = dns:mac:address
  202.  
  203. * If the DNS server is on a different subnet, we check the ARP cache for the
  204. default gateway IP. If we do not have an entry in the ARP cache we do the
  205. ``ARP process`` (see below) for the default gateway IP. If we have an entry
  206. in the ARP cache, we get the information:
  207. default.gateway.ip.address = gateway:mac:address
  208.  
  209.  
  210. ARP process
  211. -----------
  212. In order to send an ARP broadcast we need to have a Target IP address we want
  213. to look up. We also need to know the MAC address of the interface we are going
  214. to use to send out the ARP broadcast.
  215.  
  216. * The ARP cache is checked for an ARP entry for our target IP. If it's in the
  217. cache, we return the result: Target IP = MAC.
  218.  
  219. If the entry is not in the ARP cache:
  220.  
  221. * The route table is looked up, to see if the Target IP address is on any of
  222. the subnets on the local route table. If it is, we use the interface
  223. associated with that subnet. If it is not, we use the interface that has the
  224. subnet of our default gateway.
  225.  
  226. * The MAC address of the selected network interface is looked up.
  227.  
  228. * We send a Layer 2 ARP request:
  229.  
  230. ``ARP Request``::
  231.  
  232. Sender MAC: interface:mac:address:here
  233. Sender IP: interface.ip.goes.here
  234. Target MAC: 255.255.255.255 (Broadcast)
  235. Target IP: target.ip.goes.here
  236.  
  237. Depending on what type of hardware we have between us and the router:
  238.  
  239. Directly connected:
  240.  
  241. * If we are directly connected to the router the router will respond with an
  242. ``ARP Reply`` (see below)
  243.  
  244. Hub:
  245.  
  246. * If we are connected to a HUB the HUB will broadcast the ARP request out all
  247. other ports of the HUB. If the router is connected on the same "wire" it will
  248. respond with an ``ARP Reply`` (see below).
  249.  
  250. Switch:
  251.  
  252. * If we are connected to a switch it will check it's local CAM/MAC table to see
  253. which port has the MAC address we are looking for. If the switch has no entry
  254. for the MAC address it will rebroadcast the ARP request to all other ports.
  255.  
  256. * If the switch has an entry in the MAC/CAM table it will send the ARP request
  257. to the port that has the MAC address we are looking for.
  258.  
  259. * If the router is on the same "wire" it will respond with an ``ARP Reply``
  260. (see below)
  261.  
  262. ``ARP Reply``::
  263.  
  264. Sender MAC: target:mac:address:here
  265. Sender IP: target.ip.goes.here
  266. Target MAC: interface:mac:address:here
  267. Target IP: interface.ip.goes.here
  268.  
  269. Now that we have the IP address of either our DNS server or the default gateway
  270. we can resume our DNS process:
  271.  
  272. * Port 53 is opened to send a UDP request to DNS server (if the response size
  273. is too large, TCP will be used instead).
  274. * If the local/ISP DNS server does not have it, then a recursive search is
  275. requested and that flows up the list of DNS servers until the SOA is reached,
  276. and if found an answer is returned.
  277.  
  278. Opening of a socket
  279. -------------------
  280. Once the browser receives the IP address of the destination server it takes
  281. that and the given port number from the URL (the http protocol defaults to port
  282. 80, and https to port 443) and makes a call to the system library function
  283. named ``socket`` and requests a TCP socket stream - ``AF_INET`` and
  284. ``SOCK_STREAM``.
  285.  
  286. * This request is first passed to the Transport Layer where a TCP segment is
  287. crafted. The destination port is added to the header, and a source port is
  288. chosen from within the kernel's dynamic port range (ip_local_port_range in
  289. Linux).
  290. * This segment is sent to the Network Layer, which wraps an additional IP
  291. header. The IP address of the destination server as well as that of the
  292. current machine is inserted to form a packet.
  293. * The packet next arrives at the Link Layer. A frame header is added that
  294. includes the MAC address of the machine's NIC as well as the MAC address of
  295. the gateway (local router). As before, if the kernel does not know the MAC
  296. address of the gateway, it must broadcast an ARP query to find it.
  297.  
  298. At this point the packet is ready to be transmitted through either:
  299.  
  300. * `Ethernet`_
  301. * `WiFi`_
  302. * `Cellular data network`_
  303.  
  304. For most home or small business Internet connections the packet will pass from
  305. your computer, possibly through a local network, and then through a modem
  306. (MOdulator/DEModulator) which converts digital 1's and 0's into an analog
  307. signal suitable for transmission over telephone, cable, or wireless telephony
  308. connections. On the other end of the connection is another modem which converts
  309. the analog signal back into digital data to be processed by the next `network
  310. node`_ where the from and to addresses would be analyzed further.
  311.  
  312. Most larger businesses and some newer residential connections will have fiber
  313. or direct Ethernet connections in which case the data remains digital and
  314. is passed directly to the next `network node`_ for processing.
  315.  
  316. Eventually, the packet will reach the router managing the local subnet. From
  317. there, it will continue to travel to the AS's border routers, other ASes, and
  318. finally to the destination server. Each router along the way extracts the
  319. destination address from the IP header and routes it to the appropriate next
  320. hop. The TTL field in the IP header is decremented by one for each router that
  321. passes. The packet will be dropped if the TTL field reaches zero or if the
  322. current router has no space in its queue (perhaps due to network congestion).
  323.  
  324. This send and receive happens multiple times following the TCP connection flow:
  325.  
  326. * Client chooses an initial sequence number (ISN) and sends the packet to the
  327. server with the SYN bit set to indicate it is setting the ISN
  328. * Server receives SYN and if it's in an agreeable mood:
  329. * Server chooses its own initial sequence number
  330. * Server sets SYN to indicate it is choosing its ISN
  331. * Server copies the (client ISN +1) to its ACK field and adds the ACK flag
  332. to indicate it is acknowledging receipt of the first packet
  333. * Client acknowledges the connection by sending a packet:
  334. * Increases its own sequence number
  335. * Increases the receiver acknowledgment number
  336. * Sets ACK field
  337. * Data is transferred as follows:
  338. * As one side sends N data bytes, it increases its SEQ by that number
  339. * When the other side acknowledges receipt of that packet (or a string of
  340. packets), it sends an ACK packet with the ACK value equal to the last
  341. received sequence from the other
  342. * To close the connection:
  343. * The closer sends a FIN packet
  344. * The other sides ACKs the FIN packet and sends its own FIN
  345. * The closer acknowledges the other side's FIN with an ACK
  346.  
  347. UDP packets
  348. ~~~~~~~~~~~
  349.  
  350. TLS handshake
  351. -------------
  352. * The client computer sends a ``Client hello`` message to the server with it
  353. TLS version, list of cipher algorithms and compression methods available.
  354.  
  355. * The server replies with a ``Server hello`` message to the client with the
  356. TLS version, cipher and compression methods selected + the Server public
  357. certificate signed by a CA (Certificate Authority) that also contains a
  358. public key.
  359.  
  360. * The client verifies the server digital certificate and cipher a symmetric
  361. cryptography key using an asymmetric cryptography algorithm, attaching the
  362. server public key and an encrypted message for verification purposes.
  363.  
  364. * The server decrypts the key using its private key and decrypts the
  365. verification message with it, then replies with the verification message
  366. decrypted and signed with its private key
  367.  
  368. * The client confirm the server identity, cipher the agreed key and sends a
  369. ``finished`` message to the server, attaching the encrypted agreed key.
  370.  
  371. * The server sends a ``finished`` message to the client, encrypted with the
  372. agreed key.
  373.  
  374. * From now on the TLS session communicates information encrypted with the
  375. agreed key
  376.  
  377.  
  378. TCP packets
  379. ~~~~~~~~~~~
  380.  
  381. HTTP protocol...
  382. ----------------
  383.  
  384. If the web browser used was written by Google, instead of sending an HTTP
  385. request to retrieve the page, it will send a request to try and negotiate with
  386. the server an "upgrade" from HTTP to the SPDY protocol.
  387.  
  388. If the client is using the HTTP protocol and does not support SPDY, it sends a
  389. request to the server of the form::
  390.  
  391. GET / HTTP/1.1
  392. Host: google.com
  393. [other headers]
  394.  
  395. where ``[other headers]`` refers to a series of colon-separated key-value pairs
  396. formatted as per the HTTP specification and separated by single new lines.
  397. (This assumes the web browser being used doesn't have any bugs violating the
  398. HTTP spec. This also assumes that the web browser is using ``HTTP/1.1``,
  399. otherwise it may not include the ``Host`` header in the request and the version
  400. specified in the ``GET`` request will either be ``HTTP/1.0`` or ``HTTP/0.9``.)
  401.  
  402. After sending the request and headers, the web browser sends a single blank
  403. newline to the server indicating that the content of the request is done.
  404.  
  405. The server responds with a response code denoting the status of the request and
  406. responds with a response of the form::
  407.  
  408. 200 OK
  409. [response headers]
  410.  
  411. Followed by a single newline, and then sends a payload of the HTML content of
  412. ``www.google.com``. The server may then either close the connection, or if
  413. headers sent by the client requested it, keep the connection open to be reused
  414. for further requests.
  415.  
  416. If the HTTP headers sent by the web browser included sufficient information for
  417. the web server to determine if the version of the file cached by the web
  418. browser has been unmodified since the last retrieval (ie. if the web browser
  419. included an ``ETag`` header), it may have instead responded with a request of
  420. the form::
  421.  
  422. 304 Not Modified
  423. [response headers]
  424.  
  425. and no payload, and the web browser instead retrieves the HTML from its cache.
  426.  
  427. After parsing the HTML, the web browser (and server) will repeat this process
  428. for every resource (image, CSS, favicon.ico, etc) referenced by the HTML page,
  429. except instead of ``GET / HTTP/1.1`` the request will be
  430. ``GET /$(URL relative to www.google.com) HTTP/1.1``.
  431.  
  432. If the HTML referenced a resource on a different domain than
  433. ``www.google.com``, the web browser will go back to the steps involved in
  434. resolving the other domain, and follow all steps up to this point for that
  435. domain. The ``Host`` header in the request will be set to the appropriate
  436. server name instead of ``google.com``.
  437.  
  438. HTTP Server Request Handle
  439. --------------------------
  440. The HTTPD (HTTP Daemon) server is the one handling the requests/responses on
  441. the server side.
  442. The most common HTTPD servers are Apache for Linux, and IIS for windows.
  443.  
  444. * The HTTPD (HTTP Daemon) receives the request.
  445. * The server breaks down the request to the following parameters:
  446. * HTTP Request Method (GET, POST, HEAD, PUT and DELETE), in our case - GET.
  447. * Domain, in our case - google.com.
  448. * Requested path/page, in our case - / (as no specific path/page was
  449. requested, / is the default path).
  450. * The server verifies that there is a Virtual Host configured on the server
  451. that corresponds with google.com.
  452. * The server verifies that google.com can accept GET requests.
  453. * The server verifies that the client is allowed to use this method
  454. (by IP, authentication, etc.).
  455. * If the server has a rewrite module installed (like mod_rewrite for Apache or
  456. URL Rewrite for IIS), it tries to match the request against one of the
  457. configured rules. If a matching rule is found, the server uses that rule to
  458. rewrite the request.
  459. * The server goes to pull the content that corresponds with the request,
  460. in our case it will fall back to the index file, as "/" is the main file
  461. (some cases can override this, but this is the most common method).
  462. * The server will parse the file according to the handler, for example -
  463. let's say that Google is running on PHP.
  464. * The server will use PHP to interpret the index file, and catch the output.
  465. * The server will return the output, on the same request to the client.
  466.  
  467. HTML parsing
  468. ------------
  469.  
  470. * Fetch contents of requested document from network layer in 8kb chunks.
  471. * Parse HTML document (See
  472. https://html.spec.whatwg.org/multipage/syntax.html#parsing for more
  473. information).
  474. * Convert elements to DOM nodes in the content tree.
  475. * Fetch/prefetch external resources linked to the page (CSS, Images, JavaScript
  476. files, etc.)
  477. * Execute synchronous JavaScript code.
  478.  
  479. CSS interpretation
  480. ------------------
  481.  
  482. * Parse CSS files and ``<style>`` tag contents using `"CSS lexical and syntax
  483. grammar"`_
  484. * Each CSS file is parsed into a ``StyleSheet object``, where each object
  485. contains CSS rules with selectors and objects corresponding CSS grammar.
  486. * A CSS parser can be top-down or bottom-up when a specific parser generator
  487. is used.
  488.  
  489. Page Rendering
  490. --------------
  491.  
  492. * Create a 'Frame Tree' or 'Render Tree' by traversing the DOM nodes, and
  493. calculating the CSS style values for each node.
  494. * Calculate the preferred width of each node in the 'Frame Tree' bottom up
  495. by summing the preferred width of the child nodes and the node's
  496. horizontal margins, borders, and padding.
  497. * Calculate the actual width of each node top-down by allocating each node's
  498. available width to its children.
  499. * Calculate the height of each node bottom-up by applying text wrapping and
  500. summing the child node heights and the node's margins, borders, and padding.
  501. * Calculate the coordinates of each node using the information calculated
  502. above.
  503. * More complicated steps are taken when elements are ``floated``,
  504. positioned ``absolutely`` or ``relatively``, or other complex features
  505. are used. See
  506. http://dev.w3.org/csswg/css2/ and http://www.w3.org/Style/CSS/current-work
  507. for more details.
  508. * Create layers to describe which parts of the page can be animated as a group
  509. without being re-rasterized. Each frame/render object is assigned to a layer.
  510. * Textures are allocated for each layer of the page.
  511. * The frame/render objects for each layer are traversed and drawing commands
  512. are executed for their respective layer. This may be rasterized by the CPU
  513. or drawn on the GPU directly using D2D/SkiaGL.
  514. * All of the above steps may reuse calculated values from the last time the
  515. webpage was rendered, so that incremental changes require less work.
  516. * The page layers are sent to the compositing process where they are combined
  517. with layers for other visible content like the browser chrome, iframes
  518. and addon panels.
  519. * Final layer positions are computed and the composite commands are issued
  520. via Direct3D/OpenGL. The GPU command buffer(s) are flushed to the GPU for
  521. asynchronous rendering and the frame is sent to the window server.
  522.  
  523. GPU Rendering
  524. -------------
  525.  
  526. * During the rendering process the graphical computing layers can use general
  527. purpose ``CPU`` or the graphical processor ``GPU`` as well.
  528.  
  529. * When using ``GPU`` for graphical rendering computations the graphical
  530. software layers split the task into multiple pieces, so it can take advantage
  531. of ``GPU`` massive parallelism for float point calculations required for
  532. the rendering process.
  533.  
  534.  
  535. Window Server
  536. -------------
  537.  
  538. Post-rendering and user-induced execution
  539. -----------------------------------------
  540.  
  541. After rendering has completed, the browser executes JavaScript code as a result
  542. of some timing mechanism (such as a Google Doodle animation) or user
  543. interaction (typing a query into the search box and receiving suggestions).
  544. Plugins such as Flash or Java may execute as well, although not at this time on
  545. the Google homepage. Scripts can cause additional network requests to be
  546. performed, as well as modify the page or its layout, effecting another round of
  547. page rendering and painting.
  548.  
  549. .. _`Creative Commons Zero`: https://creativecommons.org/publicdomain/zero/1.0/
  550. .. _`"CSS lexical and syntax grammar"`: http://www.w3.org/TR/CSS2/grammar.html
  551. .. _`Punycode`: https://en.wikipedia.org/wiki/Punycode
  552. .. _`Ethernet`: http://en.wikipedia.org/wiki/IEEE_802.3
  553. .. _`WiFi`: https://en.wikipedia.org/wiki/IEEE_802.11
  554. .. _`Cellular data network`: https://en.wikipedia.org/wiki/Cellular_data_communication_protocol
  555. .. _`analog-to-digital converter`: https://en.wikipedia.org/wiki/Analog-to-digital_converter
  556. .. _`network node`: https://en.wikipedia.org/wiki/Computer_network#Network_nodes
  557. .. _`varies by OS` : https://en.wikipedia.org/wiki/Hosts_%28file%29#Location_in_the_file_system
Advertisement
Add Comment
Please, Sign In to add comment