I'm playing with integrating the gssapi into node.js. Im not sure how to represent this:
The gss_init_sec_context function contains many struct based parameters, some of which are nested pretty deeply. For example this struct:
typedef struct gss_ctx_id_struct
{
gss_OID mech;
#ifdef USE_KERBEROS5
struct _gss_krb5_ctx_struct *krb5;
#endif
} gss_ctx_id_desc;
So based on this I'm guessing I need to implement some kind of Structure (with ref-struct) to represent the krb5 pointer (since kerberos5 is being used). So I looked at this _gss_krb_ctx_struct and saw this...
typedef struct _gss_krb5_ctx_struct {
Shishi *sh;
Shishi_ap *ap;
Shishi_tkt *tkt;
Shishi_key *key;
gss_name_t peerptr;
int acceptor;
uint32_t acceptseqnr;
uint32_t initseqnr;
OM_uint32 flags;
int reqdone;
int repdone;
} _gss_krb5_ctx_desc, *_gss_krb5_ctx_t;
Where Shishi is a pointer to a library, and shishi_ap appears to be a pointer to a function. I'm not sure how to implement these things in node-ffi. Can someone give me some guidance here?
Related
I am working on a Hardware Abstraction Layer. The aim of this HAL is to easily switch between the drivers for linux and the drivers for an MCU.
I am working on the SPI interface. Below is the signature of the function of the HAL that "open" the interface of SPI.
hal/spi.h
spi_handle_t spi_open(spi_port_t channel, spi_config_t config);
spi_port_t :
On Linux, it is an elementary type : uint32_t
On the MCU, it is a struct.
spi_config_t :
On both Linux and the MCU it is a struct but with different fields.
So in mcu/spi.c I have at some point this :
typedef spiBASE_t spi_channel_t;
typedef spiDAT1_t spi_config_t;
spi_handle_t spi_open(spi_channel_t channel, spi_config_t config) {
.
.
.
}
And for linux/spi.c :
typedef uint32_t spi_channel_t;
typedef ChannelConfig_t spi_config_t;
spi_handle_t spi_open(spi_channel_t channel, spi_config_t config) {
.
.
.
}
Now the problem is in hal/spi.h, I need to define what is spi_channel_t and spi_config_t.
Is there a way to make something like (I know it is impossible with extern, but for explanation matters...) :
extern spi_channel_t;
extern spi_config_t;
This would say to the compiler : "Ok these two types are not defined in the header file, still you can find their storage size on one of the files I passed to the toolchain".
What you seem to be looking for is the trick called opaque type. It's a way to use forward declaration of structs in order to achieve private encapsulation and polymorphism in C. It is commonly used for professionally-written embedded systems drivers in particular and can be implemented like this:
hal/spi.h
// forward declaration of a struct, with typedef and struct tag:
typedef struct spi_handle_t spi_handle_t;
// Require the caller to declare a spi_handle_t* pointer, not an object:
spi_handle_t* spi_init (...);
mcu/spi.c
struct spi_handle_t
{
// whatever you need here - these are now 100% private members
};
spi_handle_t* spi_init (...)
{
spi_handle* result = address_of_some_static_memory_pool;
/* init struct members here */
return result;
}
linux/spi.c
struct spi_handle_t
{
uint32_t something;
// whatever you need here - these are now 100% private members
};
spi_handle_t* spi_init (...)
{
spi_handle* result = malloc(sizeof *result); // malloc is fine to use in Linux
/* init struct members here */
return result;
}
Now the caller will have to pass along the spi_handle* to other functions in the driver. This isn't just handy for OO design, but it also makes it possible to run the same code with multiple instances. For example if you have 2 different SPI hardware peripherals on the MCU and want to use them differently, but with the same driver code.
The typical way of doing this would be to use the preprocessor in hal/spi.h:
#if defined(HAL_LINUX)
typedef uint32_t spi_port_t; /* int in linux */
#elif defined(HAL_MCU)
typedef struct {
/* your struct in bare metal app */
} spi_port_t;
#else
#error "Platform not defined!"
#endif
You could also put the different types into different headers like hal/spi_linux.h and hal/spi_mcu.h and conditionally include one of them in hal/spi.h.
Alternatively, you could just take pointers and cast them to their actual type. This would be less safe because you would have to check the platform at runtime and decide the type behind the pointer, but this decision depends on many other things.
I had a plan earlier tonight, and now it's turning into a total mess.....I think I'm missing some fundamental concept.
Here's the idea:
I have to send some stuff over uart that looks like this (for example):
rpmL.txt="10"
vbatt.txt="20.4"
info.txt="Low Temperature"
battIcon.pic='8'
Simple enough, right?
Now, I have a bunch of different things that all have that same sort of format, but the only things that change are:
rpmL, vbatt, etc.
txt (this can be txt or pic)
10, 20.4, Low Temperature, 8 (this can be an int or a float or a string or an enumeration...You'll see the enum below )
So, my idea was, just make a typedef'd struct that has all these things that can change in it, and then make another struct that holds a bunch of those typedef'd 'things'.
anyway, here's the code, and i just want to increment things in different ways depending on it's type:
screen.h
typedef enum _ScreenType{
T_INT,
T_FLOAT,
T_CHAR,
T_TEMP_ICON,
T_BATT_ICON
} ScreenType;
typedef enum _tempIcon{
TEMP_LOW = 0,
TEMP_MED,
TEMP_HIGH,
//Add More Elements Up Here
TEMP_MAX_ELEMENTS
}TempIcon;
typedef enum _battIcon{
BATT_ZERO = 0,
BATT_TWENTY_FIVE,
BATT_FIFTY,
BATT_SEVENTY_FIVE,
BATT_FULL,
//Add More Elements Up Here
BATT_MAX_ELEMENTS
}BattIcon;
// Jam everything together so we can just pass the memeber of the following struct to the LCD TX function
typedef struct _packedStringVars{
ScreenType ScreenType; // I think I need this to achieve some crude polymorphism later on...
void* var; //I think I should do this because this can be a float, int or char*...
char* label; //This is always a string...nothing special about this.
}packedStringVars;
typedef struct{
packedStringVars temp;
packedStringVars wattage;
packedStringVars battPercent;
packedStringVars rpmL;
packedStringVars rpmR;
packedStringVars vbat;
packedStringVars tempIcon;
packedStringVars battIcon;
}mainScreenVariables;
and here's the source:
screen.c
#include "screen.h"
#include ..........Everything Else that You Would Expect.......
//This is where I'm trying to 'initialize' the values...I was doing *(int*) and *(float*), etc., but that went nowhere...
mainScreenVariables screenData = {
.temp = {T_INT,0,"temp"},
.wattage = {T_INT,0,"watts"},
.rpmL = {T_INT,0,"rpmL"},
.rpmR = {T_INT,0,"rpmR"},
.vbat = {T_FLOAT,0,"vbat"},
.tempIcon = {T_TEMP_ICON,(TempIcon*)TEMP_LOW,"p1"},
.battIcon = {T_BATT_ICON,(BattIcon*)BATT_FULL,"battIcon"}
};
static void updateValues(void)
{
// As you can see, now i'm typecasting them as I'm using them, which feels all kinds of wrong and also, as it turns out, doesn't even work! surprise surprise....
*(int*)screenData.temp.var++;
*(int*)screenData.wattage.var++;
*(int*)screenData.battPercent.var++;
*(int*)screenData.rpmL.var++;
*(int*)screenData.rpmR.var++;
*(float*)screenData.vbat.var+=0.1;
*(TempIcon*)screenData.tempIcon.var++;
*(ScreenType*)screenData.battIcon.var++;
}
There's more code to make sure the enumerations don't grow beyond their bounds and so forth, but really, all I want to do is set this conceptual object, and send it to the the UART, with a function signature that looks like this:
void ForChristsSakesJustSendTheDamnString(screenData * dat);
I'm sure there's some better, idiomatic way to do this. This is totally out of control and just feels wrong.
Thanks!
I'm not even sure how to properly formulate question about this.
I'm writing a library where I have multiple implementations (multiple libraries out of one). I want to hide as much as possible, if not all, implementation details from client app, in order to write an app disregarding implementation details.
It's all fine when implementation is contained within one function. However, often I need to instantiate a struct from library, do something to it with a function from library, resume writing app as normal, and then return to a function from library with data from previous function from library.
Struct details are important ONLY to library functions. I don't need to see or touch those from client application apart from passing them around because of this.
So, is there a way to hide struct details from client app and still be able to use it or if there's another way of doing this by some form of encapsulation or maybe even some kind of data (globals?) visible only to library?
Here's my lame illustration example with code:
/*
library_private.h
*/
#if (A)
{
struct mystruct_t {
A *something;
}
}
#else
struct mystruct_t {
B *something;
}
#endif
/*
library_public.h
*/
struct mystruct_t;
/*
library.c
*/
struct mystruct_t* create() {
struct mystruct_t *handle = malloc(sizeof(struct mystruct_t));
return handle;
}
/*
client.h
*/
struct mystruct_t;
/* but, I need a definition, so I have to repeat either from library_private.h */
/*
client.c
*/
int main(int argc, char const *argv[]) {
struct mystruct_t *handle = create();
/*...*/
something(handle);
return 0;
}
Cast to a void * when returning and back to structure mystruct_t just after passing into a function. This is not great as you will loose some of the compiler type checking.
client.c (or client.h) should include library_public.h. There is no need to have the structure definition. Only its declaration struct mystruct_t; is enough to use pointers to the structure. Of course, you cannot access its members, but that is exactly what you want in this case.
The structure looks like this
typedef struct _PROCESS_INFORMATION {
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
} PROCESS_INFORMATION, *LPPROCESS_INFORMATION;
struct PLAYER
{
/* 0x0/0 */ struct PROCESS_INFORMATION *ProcessInformation;
/* 0x4/4 */ unsigned long dword4;
/* 0x8/8 */ unsigned long dword8;
/* 0xC/12 */ unsigned long dwordC;
//... Lots of fields here
}
Here is the prototype for TerminateProcess
BOOL WINAPI TerminateProcess(
_In_ HANDLE hProcess,
_In_ UINT uExitCode
);
I tried all 3 of these below and failed.
unsigned int v102; //exit code.
struct PLAYER *player; // eax#9
TerminateProcess(player->ProcessInformation->hProcess, v102);
TerminateProcess(player->ProcessInformation.hProcess, v102);
TerminateProcess(*(player->ProcessInformation)->hProcess, v102);
The arrow -> works for other members of the PLAYER struct pointer but if the member inside the struct PLAYER is a pointer to another struct then I get compiler problems.
All 3 above give me the compiler problems.
Maybe I had to use *LPPROCESS_INFORMATION inside the struct PLAYER or maybe I had to use struct _PROCESS_INFORMATION * because I really hate using typedef's
(yeah I just started using C only a week ago I usually code in Java/C#/VB.NET so this is all new to me.)
Edit: Seems I found the problem I was using a stupid typedef no wonder I had so much problems.. Those typedef's eliminate the use for a type which in this case is a struct so my structure was very screwed up..
Fix was to replace
/* 0x0/0 */ struct PROCESS_INFORMATION *ProcessInformation;
with
/* 0x0/0 */ struct _PROCESS_INFORMATION *ProcessInformation;
Now I can use the beautifiul arrows non-stop
player->ProcessInformation->hProcess
Is this right?
player->ProcessInformation->hProcess
is correct. Good luck!
Since I will use the Linux's built-in crypto API for different purposes, I've been reading the sources carefully.
While attempting to understand what's going on, I have been struck by the instance handling part of the code.
The code is C, nevertheless this part is clearly object-oriented. Thus, when a user needs to perform some encryption, it will ask for the allocation of a transform instance which will involve the use of a particular algorithm in a particular encryption mode. The pair (algorithm, mode) will be handled this way in the crypto API :
The "pure" algorithm is stored in a struct crypto_alg structure.
The mode is defined through a struct crypto_template which says how to initialize a specific struct crypto_instance
Here are the definitions of the structures crypto_instance and crypto_spawn
struct crypto_instance {
struct crypto_alg alg;
/*
* The alg struct will be filled according to the template 'alloc' method
*/
struct crypto_template *tmpl;
struct hlist_node list;
void *__ctx[] CRYPTO_MINALIGN_ATTR;
};
struct crypto_spawn {
struct list_head list; // Embedded list_head to list the spawns
struct crypto_alg *alg; // Ptr to the underlying algorithm
struct crypto_instance *inst;
const struct crypto_type *frontend;
u32 mask;
}
Then, to me it looks like there is a kind of hierarchy : the crypto_spawn is here to manage the combination of an encryption mode defined by a crypto_instance and a pure encryption algorithm defined by a crypto_alg. In terms of model object, we can see that crypto_instance inherits crypto_alg and it is totally reasonable to consider "cascading" templates over a given algorithm.
The thing I don't understand is why the crypto_spawn and the crypto_instance structures are not merged together. This question has even more struck me when I met the instance allocation code :
struct crypto_instance *crypto_alloc_instance(const char *name,
struct crypto_alg *alg)
{
struct crypto_instance *inst;
struct crypto_spawn *spawn;
int err;
inst = crypto_alloc_instance2(name, alg, 0);
if (IS_ERR(inst))
goto out;
spawn = crypto_instance_ctx(inst);
/*
* This line expands to :
* spawn = inst->__ctx;
*/
err = crypto_init_spawn(spawn, alg, inst,
CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);
if (err)
goto err_free_inst;
return inst;
err_free_inst:
kfree(inst);
inst = ERR_PTR(err);
out:
return inst;
}
The crypto_alloc_instance2 just allocates the physical memory to hold the structure and fills the inst->alg structure's name fields :
void *crypto_alloc_instance2(const char *name, struct crypto_alg *alg,
unsigned int head)
{
struct crypto_instance *inst;
char *p;
int err;
p = kzalloc(head + sizeof(*inst) + sizeof(struct crypto_spawn),
GFP_KERNEL);
if (!p)
return ERR_PTR(-ENOMEM);
inst = (void *)(p + head);
/* Names editing + error checking ... */
return p;
}
As you can see, a spawn is "physically" bound to an instance, so why are they defined separately. I find it very troubling when then trying to understand how the whole thing is mixed and handled.
At the moment, the only reason that came to my mind is that it allows the API to opacify the underlying algorithm from the crypto_instance object. But since the last bytes of the structure will easily give the spawn through the spawn = inst->__ctx instruction, it is not very very opaque.
As a recall after this bunch of code and comments, the question is :
What reasons lead the developers to make this "separation" between the instance and the spawn structure ?
Thanks in advance for any enlightenment !
Note : I added the tag cryptography because I thought that developers interested in this tag have probably already taken a look into the Linux Kernel crypto part.