- IEC 61850 server/ MMS server: maximum number of client connections configurable at runtime

pull/72/head
Michael Zillgith 7 years ago
parent e980a519ae
commit 51c29fe9a7

@ -51,7 +51,7 @@
#define CONFIG_MMS_THREADLESS_STACK 0 #define CONFIG_MMS_THREADLESS_STACK 0
/* number of concurrent MMS client connections the server accepts, -1 for no limit */ /* number of concurrent MMS client connections the server accepts, -1 for no limit */
#define CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS 5 #define CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS 100
/* activate TCP keep alive mechanism. 1 -> activate */ /* activate TCP keep alive mechanism. 1 -> activate */
#define CONFIG_ACTIVATE_TCP_KEEPALIVE 1 #define CONFIG_ACTIVATE_TCP_KEEPALIVE 1

@ -56,6 +56,19 @@ namespace IEC61850.Server
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern byte IedServerConfig_getEdition(IntPtr self); static extern byte IedServerConfig_getEdition(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedServerConfig_setMaxMmsConnections(IntPtr self, int maxConnections);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int IedServerConfig_getMaxMmsConnections(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool IedServerConfig_isDynamicDataSetServiceEnabled(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedServerConfig_enableDynamicDataSetService(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool enable);
internal IntPtr self; internal IntPtr self;
public IedServerConfig () public IedServerConfig ()
@ -91,6 +104,10 @@ namespace IEC61850.Server
} }
} }
/// <summary>
/// Gets or sets the edition of the IEC 61850 standard to use
/// </summary>
/// <value>The IEC 61850 edition to use.</value>
public Iec61850Edition Edition public Iec61850Edition Edition
{ {
get { get {
@ -101,6 +118,30 @@ namespace IEC61850.Server
} }
} }
/// <summary>
/// Gets or sets maximum number of MMS clients
/// </summary>
/// <value>The max number of MMS client connections.</value>
public int MaxMmsConnections
{
get {
return IedServerConfig_getMaxMmsConnections (self);
}
set {
IedServerConfig_setMaxMmsConnections (self, value);
}
}
public bool DynamicDataSetServiceEnabled
{
get {
return IedServerConfig_isDynamicDataSetServiceEnabled (self);
}
set {
IedServerConfig_enableDynamicDataSetService (self, value);
}
}
/// <summary> /// <summary>
/// Releases all resource used by the <see cref="IEC61850.Server.IedServerConfig"/> object. /// Releases all resource used by the <see cref="IEC61850.Server.IedServerConfig"/> object.
/// </summary> /// </summary>

@ -90,6 +90,7 @@ main(int argc, char** argv)
/* Set buffer size for buffered report control blocks to 200000 bytes */ /* Set buffer size for buffered report control blocks to 200000 bytes */
IedServerConfig_setReportBufferSize(config, 200000); IedServerConfig_setReportBufferSize(config, 200000);
/* Set stack compliance to a specific edition of the standard (WARNING: data model has also to be checked for compliance) */
IedServerConfig_setEdition(config, IEC_61850_EDITION_2); IedServerConfig_setEdition(config, IEC_61850_EDITION_2);
/* Set the base path for the MMS file services */ /* Set the base path for the MMS file services */
@ -103,6 +104,9 @@ main(int argc, char** argv)
IedServerConfig_enableLogService(config, true); IedServerConfig_enableLogService(config, true);
/* set maximum number of clients */
IedServerConfig_setMaxMmsConnections(config, 2);
/* Create a new IEC 61850 server instance */ /* Create a new IEC 61850 server instance */
iedServer = IedServer_createWithConfig(&iedModel, NULL, config); iedServer = IedServer_createWithConfig(&iedModel, NULL, config);
@ -132,7 +136,7 @@ main(int argc, char** argv)
IedServer_start(iedServer, 102); IedServer_start(iedServer, 102);
if (!IedServer_isRunning(iedServer)) { if (!IedServer_isRunning(iedServer)) {
printf("Starting server failed! Exit.\n"); printf("Starting server failed (maybe need root permissions or another server is already using the port)! Exit.\n");
IedServer_destroy(iedServer); IedServer_destroy(iedServer);
exit(-1); exit(-1);
} }

@ -65,6 +65,9 @@ struct sIedServerConfig
/** IEC 61850 edition (0 = edition 1, 1 = edition 2, 2 = edition 2.1, ...) */ /** IEC 61850 edition (0 = edition 1, 1 = edition 2, 2 = edition 2.1, ...) */
uint8_t edition; uint8_t edition;
/** maximum number of MMS (TCP) connections */
int maxMmsConnections;
}; };
/** /**
@ -113,9 +116,22 @@ IedServerConfig_setReportBufferSize(IedServerConfig self, int reportBufferSize);
int int
IedServerConfig_getReportBufferSize(IedServerConfig self); IedServerConfig_getReportBufferSize(IedServerConfig self);
/**
* \brief Set the maximum number of MMS (TCP) connections the server accepts
*
* NOTE: Parameter has to be smaller than CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS if
* CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS != -1
*
* \param maxConnection maximum number of TCP connections
*/
void void
IedServerConfig_setMaxMmsConnections(IedServerConfig self, int maxConnections); IedServerConfig_setMaxMmsConnections(IedServerConfig self, int maxConnections);
/**
* \brief Get the maximum number of MMS (TCP) connections the server accepts
*
* \return maximum number of TCP connections
*/
int int
IedServerConfig_getMaxMmsConnections(IedServerConfig self); IedServerConfig_getMaxMmsConnections(IedServerConfig self);
@ -150,10 +166,10 @@ bool
IedServerConfig_isFileServiceEnabled(IedServerConfig self); IedServerConfig_isFileServiceEnabled(IedServerConfig self);
void void
IedServerConfig_enableFileWriteService(IedServerConfig self, bool enable); IedServerConfig_enableSetFileService(IedServerConfig self, bool enable);
bool bool
IedServerConfig_isFileWriteServiceEnabled(IedServerConfig self); IedServerConfig_isSetFileServiceEnabled(IedServerConfig self);
/** /**
* \brief Enable/disable the dynamic data set service for MMS * \brief Enable/disable the dynamic data set service for MMS

@ -439,6 +439,7 @@ IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguratio
MmsServer_enableDynamicNamedVariableListService(self->mmsServer, serverConfiguration->enableDynamicDataSetService); MmsServer_enableDynamicNamedVariableListService(self->mmsServer, serverConfiguration->enableDynamicDataSetService);
MmsServer_enableJournalService(self->mmsServer, serverConfiguration->enableLogService); MmsServer_enableJournalService(self->mmsServer, serverConfiguration->enableLogService);
MmsServer_setFilestoreBasepath(self->mmsServer, serverConfiguration->fileServiceBasepath); MmsServer_setFilestoreBasepath(self->mmsServer, serverConfiguration->fileServiceBasepath);
MmsServer_setMaxConnections(self->mmsServer, serverConfiguration->maxMmsConnections);
} }
#endif #endif

@ -125,3 +125,15 @@ IedServerConfig_isLogServiceEnabled(IedServerConfig self)
{ {
return self->enableLogService; return self->enableLogService;
} }
void
IedServerConfig_setMaxMmsConnections(IedServerConfig self, int maxConnections)
{
self->maxMmsConnections = maxConnections;
}
int
IedServerConfig_getMaxMmsConnections(IedServerConfig self)
{
return self->maxMmsConnections;
}

@ -94,6 +94,9 @@ IsoServer_create(TLSConfiguration tlsConfiguration);
void void
IsoServer_setTcpPort(IsoServer self, int port); IsoServer_setTcpPort(IsoServer self, int port);
void
IsoServer_setMaxConnections(IsoServer self, int maxConnections);
void void
IsoServer_setLocalIpAddress(IsoServer self, const char* ipAddress); IsoServer_setLocalIpAddress(IsoServer self, const char* ipAddress);

@ -225,6 +225,14 @@ MmsServer_installFileAccessHandler(MmsServer self, MmsFileAccessHandler handler,
void void
MmsServer_setFilestoreBasepath(MmsServer self, const char* basepath); MmsServer_setFilestoreBasepath(MmsServer self, const char* basepath);
/**
* \brief Set the maximum number of TCP client connections
*
* \param[in] maxConnections the maximum number of TCP client connections to accept
*/
void
MmsServer_setMaxConnections(MmsServer self, int maxConnections);
/** /**
* \brief Enable/disable MMS file services at runtime * \brief Enable/disable MMS file services at runtime
* *

@ -165,6 +165,7 @@ struct sMmsServer {
#endif #endif
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) #if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
int maxConnections;
bool fileServiceEnabled; bool fileServiceEnabled;
bool dynamicVariableListServiceEnabled; bool dynamicVariableListServiceEnabled;
bool journalServiceEnabled; bool journalServiceEnabled;

@ -107,6 +107,12 @@ MmsServer_setFilestoreBasepath(MmsServer self, const char* basepath)
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) #if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
void
MmsServer_setMaxConnections(MmsServer self, int maxConnections)
{
IsoServer_setMaxConnections(self->isoServer, maxConnections);
}
void void
MmsServer_enableFileService(MmsServer self, bool enable) MmsServer_enableFileService(MmsServer self, bool enable)
{ {

@ -72,10 +72,14 @@ struct sIsoServer {
TLSConfiguration tlsConfiguration; TLSConfiguration tlsConfiguration;
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
int maxConnections;
#endif
#if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1) #if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1)
LinkedList openClientConnections; LinkedList openClientConnections;
#else #else
IsoConnection* openClientConnections; IsoConnection openClientConnections[CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS];
#endif /* (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1) */ #endif /* (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1) */
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
@ -355,11 +359,6 @@ setupIsoServer(IsoServer self)
setState(self, ISO_SVR_STATE_RUNNING); setState(self, ISO_SVR_STATE_RUNNING);
#if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS != -1)
if (DEBUG_ISO_SERVER)
printf("ISO_SERVER: server is limited to %i client connections.\n", (int) CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS);
#endif
exit_function: exit_function:
return success; return success;
} }
@ -374,6 +373,17 @@ handleIsoConnections(IsoServer self)
if ((connectionSocket = ServerSocket_accept((ServerSocket) self->serverSocket)) != NULL) { if ((connectionSocket = ServerSocket_accept((ServerSocket) self->serverSocket)) != NULL) {
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
if (private_IsoServer_getConnectionCounter(self) >= self->maxConnections) {
if (DEBUG_ISO_SERVER)
printf("ISO_SERVER: maximum number of connections reached -> reject connection attempt.\n");
Socket_destroy(connectionSocket);
return;
}
#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */
#if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS != -1) #if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS != -1)
if (private_IsoServer_getConnectionCounter(self) >= CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS) { if (private_IsoServer_getConnectionCounter(self) >= CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS) {
if (DEBUG_ISO_SERVER) if (DEBUG_ISO_SERVER)
@ -416,6 +426,17 @@ handleIsoConnectionsThreadless(IsoServer self)
if ((connectionSocket = ServerSocket_accept((ServerSocket) self->serverSocket)) != NULL) { if ((connectionSocket = ServerSocket_accept((ServerSocket) self->serverSocket)) != NULL) {
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
if (private_IsoServer_getConnectionCounter(self) >= self->maxConnections) {
if (DEBUG_ISO_SERVER)
printf("ISO_SERVER: maximum number of connections reached -> reject connection attempt.\n");
Socket_destroy(connectionSocket);
return;
}
#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */
#if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS != -1) #if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS != -1)
if (private_IsoServer_getConnectionCounter(self) >= CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS) { if (private_IsoServer_getConnectionCounter(self) >= CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS) {
if (DEBUG_ISO_SERVER) if (DEBUG_ISO_SERVER)
@ -499,9 +520,6 @@ IsoServer_create(TLSConfiguration tlsConfiguration)
#if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1) #if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1)
self->openClientConnections = LinkedList_create(); self->openClientConnections = LinkedList_create();
#else
self->openClientConnections = (IsoConnection*)
GLOBAL_CALLOC(CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS, sizeof(IsoConnection));
#endif #endif
#if (CONFIG_MMS_THREADLESS_STACK != 1) && (CONFIG_MMS_SINGLE_THREADED == 0) #if (CONFIG_MMS_THREADLESS_STACK != 1) && (CONFIG_MMS_SINGLE_THREADED == 0)
@ -514,6 +532,14 @@ IsoServer_create(TLSConfiguration tlsConfiguration)
return self; return self;
} }
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
void
IsoServer_setMaxConnections(IsoServer self, int maxConnections)
{
self->maxConnections = maxConnections;
}
#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */
void void
IsoServer_setTcpPort(IsoServer self, int port) IsoServer_setTcpPort(IsoServer self, int port)
{ {
@ -769,8 +795,6 @@ IsoServer_destroy(IsoServer self)
lockClientConnections(self); lockClientConnections(self);
#endif #endif
#else
GLOBAL_FREEMEM(self->openClientConnections);
#endif /* (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1) */ #endif /* (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1) */
#if (CONFIG_MMS_THREADLESS_STACK != 1) && (CONFIG_MMS_SINGLE_THREADED == 0) #if (CONFIG_MMS_THREADLESS_STACK != 1) && (CONFIG_MMS_SINGLE_THREADED == 0)

@ -612,3 +612,5 @@ EXPORTS
IedServerConfig_isLogServiceEnabled IedServerConfig_isLogServiceEnabled
IedServerConfig_setEdition IedServerConfig_setEdition
IedServerConfig_getEdition IedServerConfig_getEdition
IedServerConfig_setMaxMmsConnections
IedServerConfig_getMaxMmsConnections

@ -740,3 +740,5 @@ EXPORTS
IedServerConfig_isLogServiceEnabled IedServerConfig_isLogServiceEnabled
IedServerConfig_setEdition IedServerConfig_setEdition
IedServerConfig_getEdition IedServerConfig_getEdition
IedServerConfig_setMaxMmsConnections
IedServerConfig_getMaxMmsConnections

Loading…
Cancel
Save