1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

introduce-network-connect-filter-callback.patch

Signed-off-by: Andy Green <andy.green@linaro.org>
This commit is contained in:
Andy Green 2011-02-13 08:37:12 +00:00
parent c85619dbcd
commit 0703409235
4 changed files with 142 additions and 2 deletions

View file

@ -133,6 +133,70 @@ libwebsocket_close_and_free_session(struct libwebsocket *wsi)
free(wsi);
}
/**
* libwebsockets_get_peer_addresses() - Get client address information
* @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 qotted 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.
*/
void
libwebsockets_get_peer_addresses(int fd, char *name, int name_len,
char *rip, int rip_len)
{
unsigned int len;
struct sockaddr_in sin;
struct hostent *host;
struct hostent *host1;
char ip[128];
char *p;
int n;
rip[0] = '\0';
name[0] = '\0';
len = sizeof sin;
if (getpeername(fd, (struct sockaddr *) &sin, &len) < 0) {
perror("getpeername");
return;
}
host = gethostbyaddr((char *) &sin.sin_addr, sizeof sin.sin_addr,
AF_INET);
if (host == NULL) {
perror("gethostbyaddr");
return;
}
strncpy(name, host->h_name, name_len);
name[name_len - 1] = '\0';
host1 = gethostbyname(host->h_name);
if (host1 == NULL)
return;
p = (char *)host1;
n = 0;
while (p != NULL) {
p = host1->h_addr_list[n++];
if (p == NULL)
continue;
if (host1->h_addrtype != AF_INET)
continue;
sprintf(ip, "%d.%d.%d.%d",
p[0], p[1], p[2], p[3]);
p = NULL;
strncpy(rip, ip, rip_len);
rip[rip_len - 1] = '\0';
}
}
/**
* libwebsocket_service_fd() - Service polled socket with something waiting
@ -187,6 +251,20 @@ libwebsocket_service_fd(struct libwebsocket_context *this,
break;
}
/*
* look at who we connected to and give user code a chance
* to reject based on client IP. There's no protocol selected
* yet so we issue this to protocols[0]
*/
if ((this->protocols[0].callback)(wsi,
LWS_CALLBACK_FILTER_NETWORK_CONNECTION,
(void*)(long)accept_fd, NULL, 0)) {
fprintf(stderr, "Callback denied network connection\n");
close(accept_fd);
break;
}
/* accepting connection to main listener */
new_wsi = malloc(sizeof(struct libwebsocket));

View file

@ -41,6 +41,7 @@ enum libwebsocket_callback_reasons {
LWS_CALLBACK_CLIENT_WRITEABLE,
LWS_CALLBACK_HTTP,
LWS_CALLBACK_BROADCAST,
LWS_CALLBACK_FILTER_NETWORK_CONNECTION,
LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
/* external poll() management support */
@ -180,6 +181,16 @@ struct libwebsocket_context;
* was able to take another packet without blocking, you'll get
* this callback at the next call to the service loop function.
*
* LWS_CALLBACK_FILTER_NETWORK_CONNECTION: called when a client connects to
* the server at network level; the connection is accepted but then
* passed to this callback to decide whether to hang up immediately
* or not, based on the client IP. @user contains the connection
* socket's descriptor. Return non-zero to terminate
* the connection before sending or receiving anything.
* Because this happens immediately after the network connection
* from the client, there's no websocket protocol selected yet so
* this callback is issued only to protocol 0.
*
* LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: called when the handshake has
* been received and parsed from the client, but the response is
* not sent yet. Return non-zero to disallow the connection.
@ -373,4 +384,8 @@ libwebsocket_canonical_hostname(struct libwebsocket_context *this);
extern void
libwebsocket_client_close(struct libwebsocket *wsi);
extern void
libwebsockets_get_peer_addresses(int fd, char *name, int name_len,
char *rip, int rip_len);
#endif

View file

@ -1,3 +1,32 @@
<h2>libwebsockets_get_peer_addresses - Get client address information</h2>
<i>void</i>
<b>libwebsockets_get_peer_addresses</b>
(<i>int</i> <b>fd</b>,
<i>char *</i> <b>name</b>,
<i>int</i> <b>name_len</b>,
<i>char *</i> <b>rip</b>,
<i>int</i> <b>rip_len</b>)
<h3>Arguments</h3>
<dl>
<dt><b>fd</b>
<dd>Connection socket descriptor
<dt><b>name</b>
<dd>Buffer to take client address name
<dt><b>name_len</b>
<dd>Length of client address name buffer
<dt><b>rip</b>
<dd>Buffer to take client address IP qotted quad
<dt><b>rip_len</b>
<dd>Length of client address IP buffer
</dl>
<h3>Description</h3>
<blockquote>
This function fills in <tt><b>name</b></tt> and <tt><b>rip</b></tt> with the name and IP of
the client connected with socket descriptor <tt><b>fd</b></tt>. Names may be
truncated if there is not enough room. If either cannot be
determined, they will be returned as valid zero-length strings.
</blockquote>
<hr>
<h2>libwebsocket_service_fd - Service polled socket with something waiting</h2>
<i>int</i>
<b>libwebsocket_service_fd</b>
@ -485,12 +514,28 @@ accept another write packet without blocking. If it already
was able to take another packet without blocking, you'll get
this callback at the next call to the service loop function.
</blockquote>
<h3>LWS_CALLBACK_FILTER_NETWORK_CONNECTION</h3>
<blockquote>
called when a client connects to
the server at network level; the connection is accepted but then
passed to this callback to decide whether to hang up immediately
or not, based on the client IP. <tt><b>user</b></tt> contains the connection
socket's descriptor. Return non-zero to terminate
the connection before sending or receiving anything.
Because this happens immediately after the network connection
from the client, there's no websocket protocol selected yet so
this callback is issued only to protocol 0.
</blockquote>
<h3>LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION</h3>
<blockquote>
called when the handshake has
been received and parsed from the client, but the response is
not sent yet. Return non-zero to disallow the connection.
<tt><b>user</b></tt> is a pointer to an array of
<tt><b>user</b></tt> is a pointer to an array of struct lws_tokens, you can
use the header enums lws_token_indexes from libwebsockets.h
to check for and read the supported header presence and
content before deciding to allow the handshake to proceed or
to kill the connection.
<p>
<p>
The next four reasons are optional and only need taking care of if you

View file

@ -77,6 +77,8 @@ static int callback_http(struct libwebsocket *wsi,
void *in, size_t len)
{
int n;
char client_name[128];
char client_ip[128];
switch (reason) {
case LWS_CALLBACK_HTTP:
@ -98,7 +100,7 @@ static int callback_http(struct libwebsocket *wsi,
/*
* callbacks for managing the external poll() array appear in
* protocl 0 callback
* protocol 0 callback
*/
case LWS_CALLBACK_ADD_POLL_FD: