diff options
author | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
commit | 84adefa331c4159d432d22840663c38f155cd4c1 (patch) | |
tree | bff9a9c66adda4df2106dfd0e5c053ab182a12bd /erts/emulator/beam/packet_parser.h | |
download | otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2 otp-84adefa331c4159d432d22840663c38f155cd4c1.zip |
The R13B03 release.OTP_R13B03
Diffstat (limited to 'erts/emulator/beam/packet_parser.h')
-rw-r--r-- | erts/emulator/beam/packet_parser.h | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/erts/emulator/beam/packet_parser.h b/erts/emulator/beam/packet_parser.h new file mode 100644 index 0000000000..1c3a9aa3da --- /dev/null +++ b/erts/emulator/beam/packet_parser.h @@ -0,0 +1,181 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2008-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +/* A protocol decoder. Simple packet length extraction as well as packet + * body parsing with protocol specific callback interfaces (http and ssl). + */ +#ifndef __PACKET_PARSER_H__ +#define __PACKET_PARSER_H__ + +#include <erl_driver.h> +#include "sys.h" + + +/* INET_LOPT_PACKET options */ +enum PacketParseType { + TCP_PB_RAW = 0, + TCP_PB_1 = 1, + TCP_PB_2 = 2, + TCP_PB_4 = 3, + TCP_PB_ASN1 = 4, + TCP_PB_RM = 5, + TCP_PB_CDR = 6, + TCP_PB_FCGI = 7, + TCP_PB_LINE_LF = 8, + TCP_PB_TPKT = 9, + TCP_PB_HTTP = 10, + TCP_PB_HTTPH = 11, + TCP_PB_SSL_TLS = 12, + TCP_PB_HTTP_BIN = 13, + TCP_PB_HTTPH_BIN = 14 +}; + +typedef struct http_atom { + struct http_atom* next; /* next in bucket */ + unsigned long h; /* stored hash value */ + const char* name; + int len; + int index; /* index in table + bit-pos */ + ErlDrvTermData atom; /* erlang atom rep */ +} http_atom_t; + +typedef struct { + enum { + URI_STAR, /* '*' */ + URI_STRING, /* "string(s1)" */ + URI_ABS_PATH,/* {abs_path, "path(s1)"} */ + URI_SCHEME, /* {scheme, "scheme(s1)", "string(s2)"} */ + URI_HTTP, /* {absoluteURI, http, "host(s1)", Port, "path(s2)"} */ + URI_HTTPS /* {absoluteURI, https, ... */ + } type; + const char* s1_ptr; + int s1_len; + const char* s2_ptr; + int s2_len; + int port; /* 0=undefined */ +}PacketHttpURI; + +typedef int HttpResponseMessageFn(void* arg, int major, int minor, int status, + const char* phrase, int phrase_len); +typedef int HttpRequestMessageFn(void* arg, const http_atom_t* meth, const char* meth_ptr, + int meth_len, const PacketHttpURI*, int major, int minor); +typedef int HttpEohMessageFn(void *arg); +typedef int HttpHeaderMessageFn(void* arg, const http_atom_t* name, const char* name_ptr, + int name_len, const char* value_ptr, int value_len); +typedef int HttpErrorMessageFn(void* arg, const char* buf, int len); +typedef int SslTlsFn(void* arg, unsigned type, unsigned major, unsigned minor, + const char* data, int len, const char* prefix, int plen); + +typedef struct { + HttpResponseMessageFn* http_response; + HttpRequestMessageFn* http_request; + HttpEohMessageFn* http_eoh; + HttpHeaderMessageFn* http_header; + HttpErrorMessageFn* http_error; + SslTlsFn* ssl_tls; +}PacketCallbacks; + + +/* Called once at emulator start + */ +void packet_parser_init(void); + +/* Returns > 0 Total packet length. + * = 0 Length unknown, need more data. + * < 0 Error, invalid format. + */ +int packet_get_length(enum PacketParseType htype, + const char* ptr, unsigned n, /* Bytes read so far */ + unsigned max_plen, /* Packet max length, 0=no limit */ + unsigned trunc_len, /* Truncate (lines) if longer, 0=no limit */ + int* statep); /* Internal protocol state */ + +ERTS_GLB_INLINE +void packet_get_body(enum PacketParseType htype, + const char** bufp, /* In: Packet header, Out: Packet body */ + int* lenp); /* In: Packet length, Out: Body length */ + +/* Returns 1 = Packet parsed and handled by callbacks. +** 0 = No parsing support for this packet type +** -1 = Error +*/ +ERTS_GLB_INLINE +int packet_parse(enum PacketParseType htype, + const char* buf, int len, /* Total packet */ + int* statep, PacketCallbacks* pcb, void* arg); + + + +/* Internals for the inlines below: */ + +#define FCGI_VERSION_1 1 +struct fcgi_head { + unsigned char version; + unsigned char type; + unsigned char requestIdB1; + unsigned char requestIdB0; + unsigned char contentLengthB1; + unsigned char contentLengthB0; + unsigned char paddingLength; + unsigned char reserved; + /* char data[] */ + /* char padding[paddingLength] */ +}; +int packet_parse_http(const char*, int, int*, PacketCallbacks*, void*); +int packet_parse_ssl(const char*, int, PacketCallbacks*, void*); + + +#if ERTS_GLB_INLINE_INCL_FUNC_DEF +ERTS_GLB_INLINE +void packet_get_body(enum PacketParseType htype, const char** bufp, int* lenp) +{ + switch (htype) { + case TCP_PB_1: *bufp += 1; *lenp -= 1; break; + case TCP_PB_2: *bufp += 2; *lenp -= 2; break; + case TCP_PB_4: *bufp += 4; *lenp -= 4; break; + case TCP_PB_FCGI: + *lenp -= ((struct fcgi_head*)*bufp)->paddingLength; + break; + default: + ;/* Return other packets "as is" */ + } +} + +ERTS_GLB_INLINE +int packet_parse(enum PacketParseType htype, const char* buf, int len, + int* statep, PacketCallbacks* pcb, void* arg) +{ + switch (htype) { + case TCP_PB_HTTP: + case TCP_PB_HTTPH: + case TCP_PB_HTTP_BIN: + case TCP_PB_HTTPH_BIN: + if (packet_parse_http(buf, len, statep, pcb, arg) < 0) + pcb->http_error(arg, buf, len); + return 1; + case TCP_PB_SSL_TLS: + return packet_parse_ssl(buf, len, pcb, arg); + default:; + } + return 0; +} +#endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */ + +#endif /* !__PACKET_PARSER_H__ */ + |