Where is the structure for payload of netlink message defined for NETLINK_XFRM socket - sockets

I am running strongswan daemon to perform IKEv2 messaging.
I wrote some python code to be notified everytime any xfrm change happens.
The socket is created like so:
my_socket = socket.socket(socketAF_NETLINK, socket.SOCK_RAW, socket.NETLINK_XFRM)
I receive and decode the nlmsghdr structure defined in ./uapi/linux/netlink.h like so:
while True:
data = my_socket.recv(65535)
msg_len, msg_type, flags, seq, pid = struct.unpack("=LHHLL", data[:16])
print msg_type
This works fine, I get the message type every time an new SA is made or updated or deleted.
Now, I attempt to decode the payload of this message, but I cannot locate the structure in linux to decode it with.
There is a file called uapi/linux/xfrm.h but I am not sure if this file contains the payload structure.
Can someone share where the payload structure is defined for xfrm netlink messages?

uapi/linux/xfrm.h is indeed the file you needed. struct xfrm_usersa_info is the struct you're looking for

Related

parse kdb+ HTTP response type

I am trying to communicate with kdb+ via HTTP. I succeeded to get the the response from the DB when I did it from the browser, but for some reason, the response is neither JSON nor anything that looks machine readable.
What I did:
Opened a port on q console (8080)
Defined a function getData that gives me the data I want.
The above steps can be presented in this .q file I created:
\p 8080
system["l db"]
getData: {[a;b] ?[table;((>=;`start;$[`long;a]);(<=;`end;$[`long;b]));0b;()]}
h:hopen `:localhost:8080:user:pass
I then typed http://localhost:8080/?getData[1;2] in the browser to get the results
Got the results as text with spaces inside <pre> tag.
The Problem
I have no I idea how to parse it to JSON. How can I solve this? is there a way to tell kdb+ to send response in JSON format?
The solution I found:
If you add .json before the ? in the url (i.e. http://localhost:8080/.json?getData[1;2]) the response will be in JSON.
It looks like, based on your code, the following may work to return data:
http://localhost:8080/?getData[a;b]
Where a and b are start and end times (or dates, this will depend on your data).
e.g.
http://localhost:8080/?getData[2021.07.23;2021.07.30]
In order to convert a KDB+ object to json you can make use of the .j.j operator.
For example you can change your code to something like:
getData:{[a;b] t:?[table;((>=;`start;$[`long;a]);(<=;`end;$[`long;b]));0b;()];.j.j t}
If you want to see what the incoming request looks like on your Q process you could add some logging to .z.ph (the default http message handler), e.g. something like:
.z.ph:{[zph;x]zph 0N!x}[.z.ph]
This will log any incoming requests out to your q process using 0N! and then run the usual .z.ph message handing code on it

Monitor TCP/IP stream

I am interested in learning Vapor, so I decided to work on a website that displays government issued weather alerts. Alert distribution is done via a TCP/IP data stream (streaming1.naad-adna.pelmorex.com port 8080).
What I have in mind is to use IBM's BlueSocket (https://github.com/IBM-Swift/BlueSocket) to create a socket, though after this point, I gave it a bit of thought but was unable to come to a conclusion on what the next steps would be.
Alerts are streamed over the data stream, so I am aware the socket would need to be opened and listened on but wasn't able to get to much past that.
A few things with the data stream are that the start and end of an alert is detected using the start and end tags of the XML document (alert and /alert). There are no special or proprietary headers added to the data, it's only raw XML. I know some alerts also include an XML declaration so I assume the encoding should be taken into account if the declaration is available.
I was then thinking of using XMLParser to parse the XML and use the data I am interested in from the alert.
So really, the main thing I am struggling with is, when the socket is open, what would be the method to listen to it, determine the start and end of the alert and then pass that XML alert for processing.
I would appreciate any input, I am also not restricted to BlueSocket so if there is a better option for what I am trying to achieve, I would be more than open to it.
So really, the main thing I am struggling with is, when the socket is
open, what would be the method to listen to it, determine the start
and end of the alert and then pass that XML alert for processing.
The method that you should use is read(into data: inout Data). It stores any available data that the server has sent into data. There are a few reasons for this method to fail, such as the connection disconnecting.
Here's an example of how to use it:
import Foundation
import Socket
let s = try Socket.create()
try s.connect(to: "streaming1.naad-adna.pelmorex.com", port: 8080)
while true {
if try Socket.wait(for: [s], timeout: 0, waitForever: true) != nil {
var alert = Data()
try s.read(into: &alert)
if let message = String(data: alert, encoding: .ascii) {
print(message)
}
}
}
s.close()
First create the socket. The default is what we want, a IPv4 TCP Stream.
Second connect() to the server using the hostname and port. Without this step, the socket isn't connected and cannot receive or send any data.
wait() until hostname has sent us some data. It returns a list of sockets that have data available to read.
read() the data, decode it and print it. By default this call will block if there is no data available on the socket.
close() the socket. This is good practice.
You might also like to consider thinking about:
non blocking sockets
error handling
streaming (a single call to read() might not give a complete alert).
I hope this answers your question.

How to produce a response body with asynchronously created body chunks in Swift Vapor

I am looking into the Swift Vapor framework.
I am trying to create a controller class that maps data obtained on an SSL link to a third party system (an Asterisk PBX server..) into a response body that is sent over some time down to the client.
So I need to send received text lines (obtained separately on the SSL connection) as they get in, without waiting for a 'complete response' to be constructed.
Seeing this example:
return Response(status: .ok) { chunker in
for name in ["joe\n", "pam\n", "cheryl\n"] {
sleep(1)
try chunker.send(name)
}
try chunker.close()
}
I thought it might be the way to go.
But what I see connecting to the Vapor server is that the REST call waits for the loop to complete, before the three lines are received as result.
How can I obtain to have try chunker.send(name) send it's characters back the client without first waiting for the loop to complete?
In the real code the controller method can potentially keep an HTTP connection to the client open for a long time, sending Asterisk activity data to the client as soon as it is obtained. So each .send(name) should actually pass immediately data to the client, not waiting for the final .close() call.
Adding a try chunker.flush() did not produce any better result..
HTTP requests aren't really designed to work like that. Different browsers and clients will function differently depending on their implementations.
For instance, if you connect with telnet to the chunker example you pasted, you will see the data is sent every second. But Safari on the other hand will wait for the entire response before displaying.
If you want to send chunked data like this reliably, you should use a protocol like WebSockets that is designed for it.

Can ZeroMQ be used to accept traditional socket requests?

I'm trying to re-write one of our old Servers using ZeroMQ, for now I have the following Server setup, (which works for Zmq requests):
using (var context = ZmqContext.Create())
using (var server = context.CreateSocket(SocketType.REP)) {
server.Bind("tcp://x.x.x.x:5705");
while (true) { ... }
This kind of setup works fine if I use the Zmq client library to connect context.CreateSocket(SocketType.REQ)
But unfortunately we've got a lot of legacy code that needs to connect to this server and the sockets are created using .net socket libs:
Socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
Socket.Connect(ipAddress, port);
Is there a way to write a ZeroMQ Server to accept these traditional .net socket connections?
You can achieve this using ZMQ_STREAM sockets.
Please note that since zeroMQ 4.x, the RAW router option has been deprecated for a new ZMQ_STREAM socket type, that works the same way as ROUTER + RAW.
It seems it is bound to evolve, though.
I recently tried ZMQ_STREAM sockets in version 4.0.1.
You can open one, use zmq_rcv until you receive the whole message (you have to check it is whole yourself), or zmq_msg_rcv to let ZeroMQ handle it. You will receive an identifier message part, just like the identifier you would find in ROUTER sockets, directly followed by one ONLY body part. There is no empty delimiter between them like there would be using a REQ Socket talking to a ROUTER Socket. So if you route them, be sure to add it yourself.
Beware though: if there is latency on the other end or if your message exceeds ZeroMQ ZMQ_STREAM buffers (mine are 8192 bytes long), your message can be interpreted by zeroMQ as a series of messages.
In that case, you will receive as many different ZeroMQ messages including both the identifier part and the body part, and it is your job to aggregate them, knowing that if several clients are talking to the STREAM socket, they might get mixed up. I personnally use a hash table using the binary identifier as a key, and delete the entry from the table when I know the message is complete and sent to the next node.
Sending through a ZMQ_STREAM with zmq_msg_send or zmq_send works fine as is.
You probably have to use zmq's RAW socket type (instead of REP) to connect with and read client data without zmq-specific framing.
HTTP Server in C (from Pieter's blog)
http://hintjens.com/blog:42
RAW Socket type info
https://github.com/hintjens/libzmq/commit/777c38ae32a5d1799b3275d38ff8d587c885dd55

Mirth: overwriting msg object with contents in an XML object

The task is to send an XML object from Channel-A to Channel-B
<MyMessage>
<ID>42</ID>
<hl7v2>
MSH|^~\&|LAB|....
PID|1|....
</hl7v2>
</MyMessage>
The steps of the channel communication:
in the Channel-B's source transformer, extract the HL7v2 contents
OVERWRITE the current msg object in Channel-B with the extracted contents
continue in the other Channel-B source transformers and expecting to reference msg['PID']['PID.5'] as normal.
The good news is that I can extract the HL7v2 'payload' into a variable. The problem or difficulty is resetting the msg object, or any other object to be able to reference the HL7 properties as expected.
When I create a new variable with the SerializerFactory.getHL7Serializer, it wraps with the tags <HL7Message>.
channelMap.put('MessageID', msg['ID']); //successful
channelMap.put('v2payload',msg['HL7v2']); //also looks good
var v2Msg = SerializerFactory.getHL7Serializer(false,false,true).toXML(msg['HL7v2']);
channelMap.put('v2Msg', v2Msg );
link to full size image
Question: Do you have any suggestions on how to overwrite the msg object?
How can I start referencing the msg as such:
msg['PID']['PID.5']
Current Conditions
the receiving channel's input type is XML
the need is to take extract all the properties from that XML object; ID is a database PK to be used later in the destination.
I'm sorry my original answer was bogged down with the peculiarities of my own scenario. I have reworked and tested to ensure that this works in your scenario.
Sending Channel - wraps the raw hl7 into your xml structure, and forwards to a channel called ReceiveXML. I have coded this in the Source Transformer, but you should code it where it works for you.
var wrappedHL7 = <MyMessage><ID>123</ID>
<hl7v2>{messageObject.getRawData()}</hl7v2>
</MyMessage>;
router.routeMessage("ReceiveXML", wrappedHL7);
Receiving Channel - extracts the hl7 from the xml, converts it to xml, and assigns back to the msg object. I have coded this in the source Filter - hence "return true;"
msg = new XML(SerializerFactory.getHL7Serializer(false,false,true).toXML(msg['hl7v2'].toString()));
return true;
All you have to do is put your incoming xml message into the inbound template area in mirth and then use the message tree to drag and drop the info from the XML that you need to the javascript section of the connector.