|
libwebsockets
Lightweight C library for HTML5 websockets
|
Go to the source code of this file.
Data Structures | |
| struct | lws_dns_score |
| struct | lws_route |
| struct | lws_peer_entry |
| struct lws_dns_score |
Definition at line 42 of file lws-network-helper.h.
| Data Fields | ||
|---|---|---|
| uint8_t | precedence | |
| uint8_t | label | |
| struct lws_route |
Definition at line 51 of file lws-network-helper.h.
| Data Fields | ||
|---|---|---|
| lws_dll2_t | list | |
| lws_sockaddr46 | src | |
| lws_sockaddr46 | dest | |
| lws_sockaddr46 | gateway | |
| lws_dns_score_t | score | |
| int | if_idx | |
| int | priority | |
| int | ifa_flags | |
| lws_route_uidx_t | uidx | |
| uint8_t | proto | |
| uint8_t | dest_len | |
| uint8_t | src_len | |
| uint8_t | scope | |
| uint8_t | af | |
| uint8_t | source_ads:1 | |
| uint8_t | has_source:1 | |
| struct lws_peer_entry |
struct lws_peer_entry - one layer of who the peer is
Definition at line 411 of file lws-network-helper.h.
| Data Fields | ||
|---|---|---|
| lws_sockaddr46 | sa46 |
the address, port 0 if unknown |
| uint8_t | cred | |
| uint8_t | kind | |
| #define LWS_ITOSA_USABLE 0 |
Definition at line 130 of file lws-network-helper.h.
| #define LWS_ITOSA_NOT_EXIST -1 |
Definition at line 131 of file lws-network-helper.h.
| #define LWS_ITOSA_NOT_USABLE -2 |
Definition at line 132 of file lws-network-helper.h.
| #define LWS_ITOSA_BUSY |
Definition at line 133 of file lws-network-helper.h.
| #define LWS_HOST_KEY_LEN 32 |
Definition at line 297 of file lws-network-helper.h.
| #define LWS_HOST_KEY_UNKNOWN "unknown" |
Definition at line 299 of file lws-network-helper.h.
| #define LWS_HOST_KEY_UNPROVEN "unproven" |
Definition at line 304 of file lws-network-helper.h.
| #define LWS_PEER_WALK_MAX 3 |
Definition at line 421 of file lws-network-helper.h.
| #define LWS_PEER_DESC_TOKEN (1 << 0) /* one token, no spaces, see below */ |
Definition at line 478 of file lws-network-helper.h.
| #define LWS_PEER_DESC_BARE_SINGLE (1 << 1) /* one proven entry: its address */ |
Definition at line 479 of file lws-network-helper.h.
| #define LWS_PEER_DESC_LEN 224 |
Definition at line 485 of file lws-network-helper.h.
| typedef uint16_t lws_route_uidx_t |
Definition at line 40 of file lws-network-helper.h.
| typedef struct lws_dns_score lws_dns_score_t |
| typedef struct lws_route lws_route_t |
| typedef lws_route_t lws_dns_sort_t |
Definition at line 81 of file lws-network-helper.h.
| typedef enum lws_peer_cred lws_peer_cred_t |
enum lws_peer_cred - how far a peer address entry can be believed
The levels are ordered, so they compare with >= : what we saw ourselves (ROUTABLE) ranks above what an intermediary we trust tells us (VOUCHED).
| typedef enum lws_peer_kind lws_peer_kind_t |
enum lws_peer_kind - where a peer address entry came from
| typedef struct lws_peer_entry lws_peer_entry_t |
struct lws_peer_entry - one layer of who the peer is
| enum lws_peer_cred |
enum lws_peer_cred - how far a peer address entry can be believed
The levels are ordered, so they compare with >= : what we saw ourselves (ROUTABLE) ranks above what an intermediary we trust tells us (VOUCHED).
| Enumerator | |
|---|---|
| LWS_PEER_CRED_NONE | empty slot |
| LWS_PEER_CRED_HEARSAY | nothing proves it: a datagram's source, a claim carried in one, an untrusted header |
| LWS_PEER_CRED_VOUCHED | an intermediary we trust says so, over a link that is itself >= ROUTABLE: PROXY v2 from a trusted front on TCP |
| LWS_PEER_CRED_ROUTABLE | we saw it ourselves: a round trip carrying a value it could not guess (a TCP handshake, QUIC address validation, or a protocol's evidence via lws_peer_raise()) |
| LWS_PEER_CRED_CRYPTO | bound to a key the peer proved: a QUIC handshake done on a validated path |
Definition at line 379 of file lws-network-helper.h.
| enum lws_peer_kind |
enum lws_peer_kind - where a peer address entry came from
Definition at line 397 of file lws-network-helper.h.
| LWS_VISIBLE LWS_EXTERN struct lws_dll2_owner * lws_routing_table_get | ( | struct lws_context * | cx | ) |
| LWS_VISIBLE LWS_EXTERN const char *LWS_WARN_UNUSED_RESULT lws_canonical_hostname | ( | struct lws_context * | context | ) |
lws_canonical_hostname() - returns this host's hostname
This is typically used by client code to fill in the host parameter when making a client connection. You can only call it after the context has been created.
| context | Websocket context |
References LWS_EXTERN, LWS_VISIBLE, and LWS_WARN_UNUSED_RESULT.
| LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_get_peer_addresses | ( | struct lws * | wsi, |
| lws_sockfd_type | fd, | ||
| char * | name, | ||
| int | name_len, | ||
| char * | rip, | ||
| int | rip_len ) |
lws_get_peer_addresses() - Get client address information
| wsi | Local struct lws associated with |
| fd | Connection socket descriptor |
| name | Buffer to take client address name |
| name_len | Length of client address name buffer |
| rip | Buffer to take client address IP dotted quad |
| rip_len | Length of client address IP buffer This function fills in name and rip with the name and IP of the client connected with socket descriptor fd. Names may be truncated if there is not enough room. If either cannot be determined, they will be returned as valid zero-length strings. |
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN const char * lws_get_peer_simple | ( | struct lws * | wsi, |
| char * | name, | ||
| size_t | namelen ) |
lws_get_peer_simple() - Get client address information without RDNS
| wsi | Local struct lws associated with |
| name | Buffer to take client address name |
| namelen | Length of client address name buffer |
This provides a 123.123.123.123 type IP address in name from the peer that has connected to wsi. Returns name, or NULL with name empty if wsi has no connection.
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN const char * lws_get_peer_simple_fd | ( | lws_sockfd_type | fd, |
| char * | name, | ||
| size_t | namelen ) |
| LWS_VISIBLE LWS_EXTERN int lws_interface_to_sa | ( | int | ipv6, |
| const char * | ifname, | ||
| struct sockaddr_in * | addr, | ||
| size_t | addrlen ) |
lws_interface_to_sa() - Convert interface name or IP to sockaddr struct
| ipv6 | Allow IPV6 addresses |
| ifname | Interface name or IP |
| addr | struct sockaddr_in * to be written |
| addrlen | Length of addr |
This converts a textual network interface name to a sockaddr usable by other network functions.
If the network interface doesn't exist, it will return LWS_ITOSA_NOT_EXIST.
If the network interface is not usable, eg ethernet cable is removed, it may logically exist but not have any IP address. As such it will return LWS_ITOSA_NOT_USABLE.
If the network interface exists and is usable, it will return LWS_ITOSA_USABLE, and only then has addr been written.
If the interfaces can't be listed (eg, the process is out of fds), a numeric address is still converted, but an interface name reads as LWS_ITOSA_NOT_EXIST, since it may be there when asked again later.
On FreeRTOS, interface names are lwIP's, eg "st1" or "ap2" (as netif_find() takes them). OP-TEE has no interfaces to look up, so it always returns LWS_ITOSA_NOT_EXIST, and a vhost iface there fails.
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN int lws_sa46_compare_ads | ( | const lws_sockaddr46 * | sa46a, |
| const lws_sockaddr46 * | sa46b ) |
lws_sa46_compare_ads() - checks if two sa46 have the same address
| sa46a | first |
| sa46b | second |
Returns 0 if the address family is INET or INET6 and the address is the same, or if the AF is the same but not INET or INET6, otherwise nonzero.
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN int lws_sa46_on_net | ( | const lws_sockaddr46 * | sa46a, |
| const lws_sockaddr46 * | sa46_net, | ||
| int | net_len ) |
lws_sa46_compare_sin6_addr() - compare two sin6_addr objects safely
| a | first |
| b | second |
Returns 0 if equal, else non-zero. Operates directly on the s6_addr array to avoid static analysis warnings about padding in the struct. lws_sa46_on_net() - checks if an sa46 is on the subnet represented by another
| sa46a | first |
| sa46_net | network |
| net_len | length of network non-mask |
Returns 0 if sa46a belongs on network sa46_net/net_len
If there is an ipv4 / v6 mismatch between the ip and the net, the ipv4 address is promoted to ::ffff:x.x.x.x before the comparison.
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN int lws_parse_numeric_address | ( | const char * | ads, |
| uint8_t * | result, | ||
| size_t | max_len ) |
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN int lws_host_is_ambiguous_numeric | ( | const char * | host | ) |
lws_host_is_ambiguous_numeric() - a host libc would take as ipv4 but we don't
| host | the host name or address string |
libc's getaddrinfo() also takes a host whose last label is a number as an ipv4 address, in the inet_aton() forms lws_parse_numeric_address() refuses: octets with a leading zero are octal, 0x is hex, and fewer than four parts are allowed ("012.0.0.1", "10.1" and "167772161" are all 10.0.0.1 to it). Such a host means different things to different resolvers, so lws refuses to resolve it for a client connection; a filter deciding whether a host is acceptable should refuse it too.
Returns 1 if host is not a strict numeric address, but its last label (ignoring one trailing '.') is all decimal digits, or "0x" and hex digits; else 0.
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN int lws_host_is_localhost | ( | const char * | host | ) |
lws_host_is_localhost() - a host lws resolves to loopback itself
| host | the host name |
RFC 6761 6.3 reserves "localhost" and every name under it for the loopback interface, and asks that queries for them are never sent to a nameserver. lws resolves such a host to loopback itself, whether through libc or async dns, so eg, "other.localhost" reaches a local server on every platform.
Returns 1 if the last label of host (ignoring one trailing '.') is "localhost", in any case, else 0.
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN int lws_sa46_parse_numeric_address | ( | const char * | ads, |
| lws_sockaddr46 * | sa46 ) |
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN int lws_sa46_is_ipv4_mapped | ( | const lws_sockaddr46 * | sa46 | ) |
lws_sa46_is_ipv4_mapped() - is an AF_INET6 sa46 an IPv4-mapped address?
| sa46 | the sa46 to test |
Returns 1 if sa46 is AF_INET6 and holds an IPv4-mapped IPv6 address (::ffff:a.b.c.d), else 0. Useful for deciding that an AF_INET6 socket targeting this address must be dual-stack (IPV6_V6ONLY = 0) to actually reach the IPv4 peer through the mapping.
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN int lws_sa46_host_key | ( | const lws_sockaddr46 * | sa46, |
| char * | key, | ||
| size_t | len ) |
lws_sa46_host_key() - the key a peer's host is accounted under
| sa46 | the peer address |
| key | buffer for the key, at least LWS_HOST_KEY_LEN |
| len | size of key |
Per-peer admission caps, strikes and rate limits must count one host as one peer. For IPv4 that is the address, but an IPv6 host commands its whole /64 (2^64 source addresses), so counting per address does not bound it at all. The key is therefore:
Keys compare equal with strcmp() exactly when the hosts are the same. LWS_WITH_PEER_LIMITS (.ip_limit_wsi, .ip_limit_ah) counts hosts the same way.
Returns 0 if the key is a host's, or 1 if it is LWS_HOST_KEY_UNKNOWN.
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN const char * lws_get_peer_host_key | ( | struct lws * | wsi, |
| char * | key, | ||
| size_t | len ) |
lws_get_peer_host_key() - the host key of the client connected to wsi
| wsi | the connection |
| key | buffer for the key, at least LWS_HOST_KEY_LEN |
| len | size of key |
lws_sa46_host_key() of the address lws_get_peer_simple() gives, ie, the client a trusted PROXY v2 proxy named where there is one. A peer whose address can't be determined or parsed gets LWS_HOST_KEY_UNKNOWN.
But only if the address is believable, ie, the connection's effective peer entry (lws_peer_effective()) is at least LWS_PEER_CRED_VOUCHED. If it is only hearsay, eg, the source of a datagram, or a QUIC connection's before QUIC validated its address, anyone may have written it: it is neither keyed as its own host, which would let a sender spread itself over keys of its choice or spend a victim's budget, nor as unknown, but as LWS_HOST_KEY_UNPROVEN, one key shared by all such peers, which a caller should give a budget sized for the unproven traffic it expects. Peer limits (LWS_WITH_PEER_LIMITS) make the same decision, the same way.
Use this to key per-client admission decisions, so they all agree on who the client is.
Returns key.
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN int lws_peer_walk | ( | struct lws * | wsi, |
| lws_peer_entry_t * | dest, | ||
| int | max ) |
lws_peer_walk() - copy out the peer address stack of a connection
| wsi | the connection, or a stream on it |
| dest | array to take the entries |
| max | number of entries dest has room for |
Copies the stack top first, so dest[0] is the most specific claim and the last entry is the transport's own peer. Given a stream (an h1 transaction, an h2 / h3 stream), the stack is its connection's.
Returns the number of entries copied, at most max and at most LWS_PEER_WALK_MAX, 0 if the connection has no peer (yet).
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN int lws_peer_effective | ( | struct lws * | wsi, |
| lws_peer_entry_t * | dest ) |
lws_peer_effective() - the entry that stands for who the peer is
| wsi | the connection, or a stream on it |
| dest | the entry to fill |
The effective entry is the first one, walking from the top, that is at least LWS_PEER_CRED_VOUCHED. If none is, it is the top entry, which is then only hearsay: a caller making per-client decisions must look at its cred and not let it stand for a proven peer. So a hearsay claim above a believable entry is never taken as the peer's identity, and cannot move a client into another client's accounting.
lws_get_peer_simple() gives the effective entry's address for a connection carrying a claim.
Returns 0 with dest filled, or nonzero if there is no peer.
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN int lws_peer_entries_effective | ( | const lws_peer_entry_t * | e, |
| int | count ) |
lws_peer_entries_effective() - which of some peer entries is effective
| e | the entries, top first, as lws_peer_walk() gives them |
| count | the number of entries in e |
The rule of lws_peer_effective(), on entries the caller has, eg a connection's stack with a layer of its own on top: the first entry from the top at LWS_PEER_CRED_VOUCHED or better, else the top one.
Returns the index of the effective entry in e, or -1 if count is not positive.
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN const char * lws_peer_entries_describe | ( | const lws_peer_entry_t * | e, |
| int | count, | ||
| char * | buf, | ||
| size_t | len, | ||
| int | flags ) |
lws_peer_entries_describe() - format peer address entries as text
| e | the entries, top first, as lws_peer_walk() gives them |
| count | the number of entries in e |
| buf | the buffer for the text |
| len | the size of buf |
| flags | 0, or LWS_PEER_DESC_TOKEN and / or LWS_PEER_DESC_BARE_SINGLE |
By default, for logs, each entry is "<address>[:<port>] <kind>/<cred>", joined top first with " < ", eg
"203.0.113.9:51234 proxy-v2/vouched < 10.0.0.2:40122 socket/routable"
With LWS_PEER_DESC_TOKEN, for a single field of a log line, there are no spaces: each entry is "<address>[:<port>]~<h|v|r|c>" (the cred's initial), joined with "<", eg
"203.0.113.9:51234~v<10.0.0.2:40122~r"
With LWS_PEER_DESC_BARE_SINGLE, a single entry the transport proved, at LWS_PEER_CRED_ROUTABLE or better, or an AF_UNIX (LWS_PEER_KIND_LOCAL) one, is just its bare address, without port, kind or cred, eg "10.0.0.2": the peer is usually only the transport's, and that is what logs have always shown for it. A single entry below ROUTABLE, eg a datagram's source, is still described in full, so that hearsay never looks like a proven peer in a log, and so are deeper stacks, since then the other layers are exactly what a log needs to show.
An IPv6 address with a port is bracketed, eg "[2001:db8::1]:443". An AF_UNIX (LWS_PEER_KIND_LOCAL) entry's address is "unix", and an address of any other family that is not IPv4 or IPv6 is "unknown", so that a token never contains spaces.
The result is always NUL-terminated if len is nonzero, and ends with "..." if it was cut short. A buffer of LWS_PEER_DESC_LEN is never cut short.
Returns buf.
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN const char * lws_peer_describe | ( | struct lws * | wsi, |
| char * | buf, | ||
| size_t | len, | ||
| int | flags ) |
lws_peer_describe() - format the peer address stack of a connection
| wsi | the connection, or a stream on it |
| buf | the buffer for the text |
| len | the size of buf |
| flags | 0, or LWS_PEER_DESC_TOKEN and / or LWS_PEER_DESC_BARE_SINGLE |
lws_peer_entries_describe() of what lws_peer_walk() gives for wsi; a connection with no peer gives "unknown".
The description comes only from the stack, what the connection recorded when it was accepted or connected: the socket is not asked again, so it is the same when the connection is being closed, after the peer reset it, or (for a stream) after its connection's socket was closed.
With LWS_PEER_DESC_BARE_SINGLE, a connection whose only entry is its proven IP peer is described by its bare address, the text lws_get_peer_simple() gives for it, so that a log or access log line is the same as it always was in the usual case, and only grows the other layers when there are some. An AF_UNIX peer is "unix". This is how lws describes the peer in its own logs and access log.
Returns buf.
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN int lws_peer_raise | ( | struct lws * | wsi, |
| const lws_sockaddr46 * | seen, | ||
| lws_peer_cred_t | cred ) |
lws_peer_raise() - raise the cred of an entry a protocol has evidence for
| wsi | the connection, or a stream on it |
| seen | the address the evidence came from |
| cred | the level the evidence supports |
A protocol can prove an address as it goes, eg an answer that echoes a value we only sent to that address shows the address is really there. This raises every entry on the connection's stack whose address equals seen's (and whose port does too, unless seen's port is 0) to cred. A cred is never lowered.
The address is the evidence, so it must be the one the evidence was seen from: an entry that has since moved on to another address (eg, a raw UDP socket's last datagram source) is not raised by an answer from the old one.
The raise covers only what the entry stands for now. On a UDP socket each datagram is a new observation of its source, which anyone can write, so the next datagram, even from the same address and port, is hearsay again; and a client connection dialling again (eg, after a redirect) starts over.
Returns 0 if an entry matched, or nonzero if none did (or cred is not a level).
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN const char * lws_peer_cred_name | ( | lws_peer_cred_t | cred | ) |
lws_peer_cred_name() - the name of a cred level, eg "routable"
| cred | the level |
Returns a constant string, "?" for an unknown level.
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN const char * lws_peer_kind_name | ( | lws_peer_kind_t | kind | ) |
lws_peer_kind_name() - the name of an entry kind, eg "proxy-v2"
| kind | the kind |
Returns a constant string, "?" for an unknown kind.
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN int lws_write_numeric_address | ( | const uint8_t * | ads, |
| int | size, | ||
| char * | buf, | ||
| size_t | len ) |
lws_write_numeric_address() - convert network byte order ads to text
| ads | network byte order address array |
| size | number of bytes valid in ads |
| buf | result buffer to take text format |
| len | max size of text buffer |
Converts an array of network-ordered byte address elements to a textual representation of the numeric address, like "1.2.3.4" or "::1". Returns the number of chars written into buf, else < 0. ipv6 only supported with LWS_IPV6=1 at cmake.
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN int lws_sa46_write_numeric_address | ( | lws_sockaddr46 * | sa46, |
| char * | buf, | ||
| size_t | len ) |
lws_sa46_write_numeric_address() - convert sa46 ads to textual numeric ads
| sa46 | the sa46 whose address to show |
| buf | result buffer to take text format |
| len | max size of text buffer |
Converts the ipv4 or ipv6 address in an lws_sockaddr46 to a textual representation of the numeric address, like "1.2.3.4" or "::1". Returns the number of chars written into buf, else < 0. ipv6 only supported with LWS_IPV6=1 at cmake.
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN int lws_parse_mac | ( | const char * | ads, |
| uint8_t * | result_6_bytes ) |
lws_parse_mac() - convert XX:XX:XX:XX:XX:XX to 6-byte MAC address
| ads | mac address as XX:XX:XX:XX:XX:XX string |
| result_6_bytes | result buffer to take 6 bytes |
Converts a string representation of a 6-byte hex mac address to a 6-byte array.
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN int lws_parse_cidr | ( | const char * | cidr, |
| lws_sockaddr46 * | sa46, | ||
| int * | len ) |
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN int lws_is_lan_address | ( | const char * | ads | ) |
lws_is_lan_address() - checks if the given string represents a LAN address
| ads | The address string |
Returns 1 if the address is a local/LAN unroutable address
References LWS_EXTERN, and LWS_VISIBLE.
| LWS_VISIBLE LWS_EXTERN int lws_is_local_address | ( | const char * | ads | ) |
References LWS_EXTERN, and LWS_VISIBLE.