MINOR: sample: Add converters to parse FIX messages

This patch implements a couple of converters to validate and extract tag value
from a FIX (Financial Information eXchange) message. The validation consists in
a few checks such as mandatory fields and checksum computation. The extraction
can get any tag value based on a tag string or tag id.

This patch requires the istend() function. Thus it depends on "MINOR: ist: Add
istend() function to return a pointer to the end of the string".

Reviewed and Fixed by Christopher Faulet <cfaulet@haproxy.com>
This commit is contained in:
Baptiste Assmann
2020-10-22 15:39:03 +02:00
committed by Willy Tarreau
parent cf26623780
commit e138dda1e0
6 changed files with 564 additions and 1 deletions

70
include/haproxy/fix-t.h Normal file
View File

@@ -0,0 +1,70 @@
/*
* include/haproxy/fix-t.h
* This file contains structure declarations for FIX protocol.
*
* Copyright 2020 Baptiste Assmann <bedis9@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, version 2.1
* exclusively.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _HAPROXY_FIX_T_H
#define _HAPROXY_FIX_T_H
#include <import/ist.h>
/*
* FIX messages are composed by a list of Tag=Value separated by a 'delimiter'
*/
#define FIX_DELIMITER 0x01
/*
* know FIX version strings
*/
#define FIX_4_0 (ist("FIX.4.0"))
#define FIX_4_1 (ist("FIX.4.1"))
#define FIX_4_2 (ist("FIX.4.2"))
#define FIX_4_3 (ist("FIX.4.3"))
#define FIX_4_4 (ist("FIX.4.4"))
#define FIX_5_0 (ist("FIXT.1.1"))
/* FIX_5_0SP1 and FIX_5_0SP2 have the same version string than FIX5_0 */
/*
* Supported FIX tag ID
*/
#define FIX_TAG_BeginString 8
#define FIX_TAG_BodyLength 9
#define FIX_TAG_CheckSum 10
#define FIX_TAG_MsgType 35
#define FIX_TAG_SenderComID 49
#define FIX_TAG_TargetComID 56
#define FIX_MSG_MINSIZE 26 /* Minimal length for a FIX Message */
#define FIX_CHKSUM_SIZE 7 /* Length of the CheckSum tag (10=NNN<delim>) */
/*
* return code when parsing / validating FIX messages
*/
#define FIX_INVALID_MESSAGE -1
#define FIX_NEED_MORE_DATA 0
#define FIX_VALID_MESSAGE 1
#endif /* _HAPROXY_FIX_T_H */
/*
* Local variables:
* c-indent-level: 8
* c-basic-offset: 8
* End:
*/

97
include/haproxy/fix.h Normal file
View File

@@ -0,0 +1,97 @@
/*
* include/haproxy/fix.h
* This file contains functions and macros declarations for FIX protocol decoding.
*
* Copyright 2020 Baptiste Assmann <bedis9@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, version 2.1
* exclusively.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _HAPROXY_FIX_H
#define _HAPROXY_FIX_H
#include <import/ist.h>
#include <haproxy/fix-t.h>
#include <haproxy/tools.h>
unsigned int fix_check_id(const struct ist str, const struct ist version);
int fix_validate_message(const struct ist msg);
struct ist fix_tag_value(const struct ist msg, unsigned int tagid);
/*
* Return the FIX version string (one of FIX_X_Y macros) correspoding to
* <str> or IST_NULL if not found.
*/
static inline struct ist fix_version(const struct ist str)
{
/* 7 is the minimal size for the FIX version string */
if (istlen(str) < 7)
return IST_NULL;
if (isteq(FIX_4_0, str))
return FIX_4_0;
else if (isteq(FIX_4_1, str))
return FIX_4_1;
else if (isteq(FIX_4_2, str))
return FIX_4_2;
else if (isteq(FIX_4_3, str))
return FIX_4_3;
else if (isteq(FIX_4_4, str))
return FIX_4_4;
else if (isteq(FIX_5_0, str))
return FIX_5_0;
return IST_NULL;
}
/*
* Return the FIX tag ID corresponding to <tag> if one found or 0 if not.
*
* full list of tag ID available here, just in case we need to support
* more "string" equivalent in the future:
* https://www.onixs.biz/fix-dictionary/4.2/fields_by_tag.html
*/
static inline unsigned int fix_tagid(const struct ist tag)
{
unsigned id = fix_check_id(tag, IST_NULL);
if (id)
return id;
else if (isteqi(tag, ist("MsgType")))
return FIX_TAG_MsgType;
else if (isteqi(tag, ist("CheckSum")))
return FIX_TAG_CheckSum;
else if (isteqi(tag, ist("BodyLength")))
return FIX_TAG_BodyLength;
else if (isteqi(tag, ist("TargetComID")))
return FIX_TAG_TargetComID;
else if (isteqi(tag, ist("BeginString")))
return FIX_TAG_BeginString;
else if (isteqi(tag, ist("SenderComID")))
return FIX_TAG_SenderComID;
return 0;
}
#endif /* _HAPROXY_FIX_H */
/*
* Local variables:
* c-indent-level: 8
* c-basic-offset: 8
* End:
*/