Rust: not exposing a shared library - rust

I'm looking for best practice defining a project structure in Rust. Let's say I have a project that consists of a client and a server component, and they share some functionality I'd like to move to a separate common library. So all in all, like this:
my_awesome_project
- common [library]
- client [binary] - uses common
- server [binary] - uses common
Obviously, all methods in the common crate used in either client or server must be public. However, I would like to avoid anyone who has the client binary (not the code) being able to call methods from common. Is that possible somehow?
I come from C# background, where common would be a DLL exposing public methods, easily callable. I've read that Rust uses static linking by default, but in my understanding, that does not provide what I am looking for.
And yes, I could double the common code in a private module for both server and client, but that's not optimal either.

To the extent that you have any control over what someone does with your code, Rust's static linking will sufficiently obfuscate the library boundary that you need not worry about the methods being callable.
You will not deliver the library to the user. You will deliver a single binary, hopefully stripped of debug information, which contains the code of client and all the code from common it needs, bundled together.
Unlike C#, there is no separate DLL file, and no metadata that makes it easy to discover and use library functions.

Related

NestJs - Class library

I am using nestjs to build several small applications, in doing so I would quite like a class library in which all projects can reference to pass the classes from one project to another if they'd like to, or at least standardise the objects to a contract they must adhere to.
Is there a way to approach this where I have a single standalone collection of simplistic domain classes not bound to a specific nestjs project, without specific domain logic involved, moreover the structure of how something should look as opposed to what it does?
Sounds like a perfect use case for using a NestJS Monorepo with a library, or to use something like Nx and use a library from there. In both cases, you're creating a reusable set of code (usually interfaces or classes) to be used throughout different parts of your servers/applications.

Library function that implements TPM2_MakeCredential

For remote attestation using a TPM, on the server-side I need the TPM2_MakeCredential function. Note that this function is implemented in the TPM but it is a bit off because it doesn't depend on any TPM state, it's completely stateless (unlike the TPM2_ActivateCredential function - to be run on the client-side - which critically depends on TPM keys). According to the documentation, it's provided as a convenience. That's OK but the problem is the server doesn't have (nor requires) a TPM. But I still want to use the TPM2_MakeCredential function.
Unfortunately, I haven't been able to find a library implementation of this function. There's a full-blown TPM2.0 emulator provided by Microsoft that the TPM.MSR libraries can interface to. This works, but it requires starting and managing the simulator process which sets up sockets etc. which I would rather avoid. I am wondering if there's a pure C/C++/C# implementation provided as a library? I have been working with various solutions but the function is not trivial to re-implement, and it's also not trivial to extract from the simulator.
It turns out the TPM.MSR library itself exposes this functionality (implemented purely in the library itself, not relying on a TPM) via the CreateActivationCredentials() function on TpmPublic.

WebAssembly: Standardized Interfaces

The way WebAssembly interfaces with the external world is quite elegant and secure. Adding a function interface is easy, but not yet standardized.
Have calling conventions been established already for Javascript environments (mostly for accessing the DOM in the Browser or the filesystem in Node)?
Conventions for manipulating DOM nodes or using external APIs have not been created yet, but a couple of the WebAssembly proposals / future features will support this.
The first is the reference types proposal, which allows extends the type system, adding a new anyref type that allows modules to hold references to objects provided by the host environment, i.e. you can pass a JS object to your wasm module.
The second is the host bindings proposal that allows WebAssembly modules to create, pass around, call, and manipulate JavaScript / DOM objects. It adds a number host bindings section that includes annotations that describes binding mechanism / interface that should be constructed.
Rust already has a tool, wasm-bindgen, that is very similar in purpose and closely aligns with this proposal. With wasm-bindgen you can pass objects such as strings across the wasm / JS boundary with ease. The tool adds the binding metadata to the wasm module, and generates the required JS glue code.

General terminology put into context

I learned Java programming before learning any other programming languages. As I learn Node.js, I'm getting all the terminology confused. I have always thought API as a library of methods, classes, etc. that someone has built to make our lives easier. Then I learned about module, which I basically assume to be the same thing as an API(list of methods already built by someone). THEN, I learned about the Express Framework, which again, is a list of methods just like a module and an API. Moreover, the way we incorporate these features into our program is all by doing something like
Var http = require('http');
Therefore, can someone who understands the distinctions between these terms put these terms in context(examples) that could address my question.
Thanks a lot for the help.
A library is just a collection of numerous modules, classes, functions, etc. that are related to each other.
A framework is either a type of or a part of a library that is setup for you to build on top of rather than just call upon. And the distinction between Library and Framework can sometimes be a bit blurred.
With Express, you build upon the Application and its Router which handles incoming requests and determines when to call your code.
app.get('/', function (req, res) {
// ...
});
Though, frameworks can also span beyond code into tools. compound.js' executable is a good example of this.
A module is an individual piece of a library or framework. With Node, it's a single script file and the Object that is exported from the script.
An API is the summary/description of how you interact with the library, framework, or module.
It's usually what you'll find in documentation and is the accessible members, their name, their type, what arguments they accept, etc.
Express' API is:
express
Type: function
Named Arguments: (none)
Returns: Application
Members
listen
Type: function
Named Arguments:
name: port
Type: Number
etc.
This is largely an opinionated question. But I will attempt to provide the some terms commonly used by the Node community, and roughly the factual differences between them.
Module as it pertains to Node is very similar to what you would associate with a Java Library. It provides a wrapper around things that Node users find they do a lot. Frequently providing wrappers around node library functions for doing things everyone wants to do. A simple example would be a recursive file system reader, like wrench. Modules also extend to files you use to modularize your code. For example, modules aren't only installed via NPM, but separate javascript files you write as part of your code base to separate code functionality, under standard OOP practices.
require('someNPMINStalledModule')
require('./someFileInYourCodeBase.js')
both are modules. One is installed via NPM and located in node_modules directory, in the directory you launched node from. The latter example is a javascript file located in the directory you launched node from.
Then there are frameworks. At the core these do the same thing as modules, however, they are meant to be more wide spread, and really change the way you use node. In the java world frameworks like Express would be similar to things like Grails. You can still include and do everything you can do in Java, but grails wraps some things for you, and provides convenient powerful method calls for doing batches of work in a less verbose way. In the end you end up with functionally equivalent code, but Grails has allowed you to accomplish more in fewer lines of code, by generalizing the language a little more. But it still, as I said, allows you to use native code, when Grails doesn't provide the functionality you need. At the cost of this 'few lines of code' gain, you have added a layer of abstraction, additional function calls, etc. This distinction is unimportant, unless you are one who cares deeply about style. A hardcore ExpressJS developer likely wouldn't like it if you included a plain node http server in your code. Not so much because it is invalid Node, or from a perforamnce view any different, it wrecks the style of your code. If your code uses a framework, you should stick to using the coding conventions as used in this framework. But if you use a module like wrench to recursively search a directory, it is still perfectly stylistically acceptable to use fs.readFile, to read a single file.
Then there are mini applications which is a module that allow you to quickly launch simple things like serving a file. For example: http-server will server a directory of files to any port you wish, with a simple command line. You wouldn't use them in your own code with 'require' but this type of module can honestly be some of the most useful thing node provides, I highly recommend using some. (Nodemon, http-server, and grunt are a few highly useful examples of modules that can help make your development life easier)
Finally there are Native Extensions. The concurrency that Node provides comes from the V8 backend. Replicating this in pure Javscript is impossible, and the only way to write truly asyncrhonous code is to take advantage of asynchronous operations provided by the Node API, do some really wonky logic with process.nextTick, fork child processes, or write native extensions. Native Extensions provide truly concurrent operations that Node does not provide. Database communication is the most obvious example, but anyone can develope a C++ extension that will spawn threads to do work. There is also a very handy module that launches threads to handle bits of Javascript called "threads a gogo". It simplifies the launching of truly concurrent work, though if you're in a position where such things are necessary, you may find that you're using the wrong language for your use case. Ultimately these are no different from Modules in the way that you use them, but being aware of the fact that they can provide additional concurrent method for I/O type of operations not provided by NodeJS APIs is a unique and very important distinction.

How to deal with dependencies in shared libraries, unix

I have created a dynamic(.so) library which bundles some functionality for a storage backend that I need.
As it is, it offers a known interface and provides backends for things like memcached, mysql, sqlite... etc.
Now my problem is that my shared library depends on libmemcached, on libsqlite3, on libmysqlclient.. etc., and I don't know how to pack it since clients that only want sqlite wouldn't need to have libmemcached installed.
I've been thinking on splitting it on different libraries but it seems like I'll end up with almost 20 .so libraries and I don't like that idea.
Any alternative?
One alternative is to put an interface within the shared library you made, which allows it to load dependencies at runtime. So, as an example you can have separate
init functions for different components:
init_memcached();
init_sqlite();
You implement these initialization functions using dlopen() and friends.
You can use dynamic loading using dlsym and dlopen.
The advantage of this approach is your application will run fine when the shared library is not found on client side.
You could load only needed shared libraries during run-time, but in my opinion, it is not so good approach.
I would split the shared library, but not into 20 libraries. See if you could group some common functionality.

Resources