aboutsummaryrefslogtreecommitdiffstats
path: root/readme.md
blob: 4156e51286efdc950cba4614d348218df8ea5ead (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# OPC UA Discovery

A small C project that demonstrates OPC UA server discovery using the
[open62541](https://www.open62541.org/) library. Three programs work together:

- **ServerLDS** — Local Discovery Server that other servers register with
- **ServerRegister** — a server that periodically registers itself with the LDS
- **Client** — queries the LDS for servers, lists endpoints, or reads the current time from a server

## Prerequisites

- CMake 4.0+
- A C11 compiler (GCC or Clang)
- OpenSSL development libraries (`libssl-dev` / `openssl-devel`)
- `openssl` CLI (for generating certificates)

## Getting started

Clone the repository with its submodule:

```sh
git clone --recursive https://git.tvcloud.fr/opcua_c
cd opcua_c
```

### Generate certificates

The programs use TLS certificates for mutual authentication. Four identities
are needed — run these from the project root:

```sh
tools/generate_certificate.sh certs ServerLDS
tools/generate_certificate.sh certs ServerRegister
tools/generate_certificate.sh certs ServerRegisterClient
tools/generate_certificate.sh certs ClientFindServers
```

### Populate the trust stores

Each program trusts a specific set of peers. Copy the certificates into the
trust store directories so they can find each other:

```sh
mkdir -p certs/trust/{server_lds,server_register,server_register_client,client}

cp certs/ServerRegisterClient_cert.der certs/ClientFindServers_cert.der \
   certs/trust/server_lds/

cp certs/ServerLDS_cert.der certs/ClientFindServers_cert.der \
   certs/trust/server_register/

cp certs/ServerLDS_cert.der \
   certs/trust/server_register_client/

cp certs/ServerLDS_cert.der certs/ServerRegister_cert.der \
   certs/trust/client/
```

### Build

```sh
cmake -B build
cmake --build build --parallel
```

open62541 is fetched from the submodule and built automatically — the first
build takes a bit longer.

## Running

Start the programs in order, each in its own terminal, from the project root:

```sh
# 1. Local Discovery Server
build/ServerLDS config/server_lds.conf

# 2. Register Server (connects to the LDS on port 4840)
build/ServerRegister config/server_register.conf \
  config/server_register_client.conf opc.tcp://localhost:4840

# 3. Find registered servers via the LDS
build/Client config/client.conf find-servers opc.tcp://localhost:4840

# 4. List endpoints on the registered server
build/Client config/client.conf get-endpoints opc.tcp://localhost:4841

# 5. Read the current time from the registered server
build/Client config/client.conf read-time opc.tcp://localhost:4841
```

All three programs accept an optional log level as the last argument
(`trace`, `debug`, `info`, `warning`, `error`, `fatal`). The default is `info`.

## Tests

Integration tests exercise four combinations of security and authentication:

| Test | Security | Auth |
|------|----------|------|
| `none_anon` | None | anonymous |
| `none_user` | None | user/password |
| `basic256sha256_anon` | SignAndEncrypt / Basic256Sha256 | anonymous |
| `aes128_user` | SignAndEncrypt / Aes128_Sha256_RsaOaep | user/password |

Run them:

```sh
ctest --test-dir build --output-on-failure
```

### Memory leak check

Rebuild with AddressSanitizer, run the tests, then switch back:

```sh
# ASan build
cmake -B build \
  -DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer" \
  -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address"
cmake --build build --parallel

ASAN_OPTIONS="detect_leaks=1" ctest --test-dir build --output-on-failure

# Restore normal build
cmake -B build -DCMAKE_C_FLAGS="" -DCMAKE_EXE_LINKER_FLAGS=""
cmake --build build --parallel
```

## Configuration

Programs are configured through plain text files (`key = value`, one per line).
Example configs are in `config/`.