text: 
  /******************************************************************************
   *
   *   FILE
   *   ----
   *   UDPListener.c
   *
   *   History
   *   -------
   *   2015-01-20   File created
   *
   *******************************************************************************
   *
   *   This file is generated by the 'acplt_builder' command
   *
   ******************************************************************************/
  
  
  #ifndef OV_COMPILE_LIBRARY_UDPbind
  #define OV_COMPILE_LIBRARY_UDPbind
  #endif
  
  
  #include "UDPbind.h"
  #include "ov_macros.h"
  #include "ov_result.h"
  #include "UDPbind_helper.h"
  #include "UDPbind_config.h"
  #include "ks_logfile.h"
  
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <errno.h>
  
  #if !OV_SYSTEM_NT
  #include <arpa/inet.h>
  #include <sys/socket.h>
  #include <sys/ioctl.h>
  #include <netinet/in.h>
  #include <netinet/tcp.h>
  #include <unistd.h>
  #include <fcntl.h>
  #include <netdb.h>
  /*	defines if not defined in netdb.h	*/
  #ifndef NI_MAXHOST
  #define NI_MAXHOST 1025
  #endif
  #ifndef NI_MAXSERV
  #define NI_MAXSERV 32
  #endif
  /* for select */
  #include <sys/select.h>
  #else
  #undef _WIN32_WINNT
  #define _WIN32_WINNT 0x501
  #ifndef IPV6_V6ONLY
  #define IPV6_V6ONLY 27
  #endif
  #include <winsock2.h>
  #include <ws2tcpip.h>
  #endif
  
  OV_DLLFNCEXPORT OV_INT UDPbind_UDPListener_port_get(
  		OV_INSTPTR_UDPbind_UDPListener          pobj
  ) {
  	return pobj->v_port;
  }
  
  OV_DLLFNCEXPORT OV_RESULT UDPbind_UDPListener_port_set(
  		OV_INSTPTR_UDPbind_UDPListener          pobj,
  		const OV_INT  value
  ) {
  	if(pobj->v_socket[0] != -1)
  	{
  		UDPBIND_CLOSE_SOCKET(pobj->v_socket[0]);
  		pobj->v_SocketState = 0;
  		pobj->v_socket[0] = -1;
  	}
  
  	if(pobj->v_socket[1] != -1)
  	{
  		UDPBIND_CLOSE_SOCKET(pobj->v_socket[1]);
  		pobj->v_SocketState = 0;
  		pobj->v_socket[1] = -1;
  	}
  
  	pobj->v_port = value;
  	return OV_ERR_OK;
  }
  
  OV_DLLFNCEXPORT OV_RESULT UDPbind_UDPListener_constructor(
  		OV_INSTPTR_ov_object 	pobj
  ) {
  	/*
  	 *   local variables
  	 */
  	OV_INSTPTR_UDPbind_UDPListener pinst = Ov_StaticPtrCast(UDPbind_UDPListener, pobj);
  	OV_RESULT    result;
  
  	/* do what the base class does first */
  	result = ksbase_ComTask_constructor(pobj);
  	if(Ov_Fail(result))
  		return result;
  
  	/* do what */
  	//start inactive at construction. Begin listening in typemethod
  	pinst->v_actimode = 0;
  	pinst->v_usesStreamProtocol = FALSE;
  	pinst->v_isLocal = TRUE;		//FIXME: this is NOT the clean way. It's just a workaournd to function as ks-MANAGER, knowing we would NOT recognize remote connections.
  	return OV_ERR_OK;
  }
  
  OV_DLLFNCEXPORT void UDPbind_UDPListener_shutdown(
  		OV_INSTPTR_ov_object 	pobj
  ) {
  	/*
  	 *   local variables
  	 */
  	OV_INSTPTR_UDPbind_UDPListener pinst = Ov_StaticPtrCast(UDPbind_UDPListener, pobj);
  
  	/* do what */
  	//close socket
  	if(pinst->v_socket[0] != -1)
  	{
  		UDPBIND_CLOSE_SOCKET(pinst->v_socket[0]);
  		pinst->v_socket[0] = -1;
  	}
  
  	if(pinst->v_socket[1] != -1)
  	{
  		UDPBIND_CLOSE_SOCKET(pinst->v_socket[1]);
  		pinst->v_socket[1] = -1;
  	}
  	pinst->v_SocketState = 0;
  	pinst->v_actimode = 0;
  	/* set the object's state to "shut down" */
  	ov_object_shutdown(pobj);
  
  	return;
  }
  
  typedef enum UDPBIND_PROT {PROTUNDEFINED=0,IPv4=4,IPv6=6} UDPBIND_PROT;
  
  OV_DLLFNCEXPORT void UDPbind_UDPListener_typemethod (
  		OV_INSTPTR_ksbase_ComTask	this
  ) {
  	/*
  	 *   local variables
  	 */
  	OV_INSTPTR_UDPbind_UDPListener thisLi = Ov_StaticPtrCast(UDPbind_UDPListener, this);
  	OV_INSTPTR_ksbase_ProtocolIdentificator pProtIdent = NULL;
  	OV_VTBLPTR_ksbase_ProtocolIdentificator pVTBLProtIdent = NULL;
  	OV_INSTPTR_ksbase_ClientHandler pClientHandler = NULL;
  	OV_VTBLPTR_ksbase_ClientHandler pVTBLClientHandler = NULL;
  	OV_BOOL protV4only = FALSE;
  	struct addrinfo *resultingaddrinfo;
  	struct addrinfo hints;
  	int ret;
  	#define NUMPROT 2
  	UDPBIND_PROT Protocolfamily[NUMPROT] = {PROTUNDEFINED, PROTUNDEFINED};
  	UDPBIND_SOCKET sockfds[NUMPROT]={UDPBIND_INVALID_SOCKET, UDPBIND_INVALID_SOCKET};
  	UDPBIND_SOCKET fd = 0;
  	int opt_on = 1;
  
  	struct sockaddr_storage sa_stor;
  	socklen_t sockaddsize;
  	struct sockaddr* sockaddress = (struct sockaddr*) &sa_stor;
  	char hostbuf[NI_MAXHOST];
  	char portbuf[NI_MAXSERV];
  	int flags = NI_NUMERICHOST | NI_NUMERICSERV;
  	fd_set fds;
  	UDPBIND_SOCKET highest;
  	int i;
  	struct timeval waitd;
  	OV_BYTE* tempdata = NULL;
  	OV_BOOL datareceived = FALSE;
  	OV_RESULT result;
  
  	/*
  	 * If no socket is open, open one and start listening.
  	 * This code was copied from ct magazine 19/12. It is meant to make the sockets IPv6 compatible.
  	 */
  	if(!thisLi->v_SocketState)	//no socket open
  	{
  		ov_memstack_lock();
  		if(!ov_vendortree_getcmdlineoption_value("UDPBIND_NO_IPv6")){
  			protV4only = FALSE;
  		}else{
  			protV4only = TRUE;
  		}
  		ov_memstack_unlock();
  		if(protV4only){
  			Protocolfamily[0] = IPv4;
  		} else {
  			Protocolfamily[0] = IPv4;
  			Protocolfamily[1] = IPv6;
  		}
  		portbuf[0] = '\0';
  
  		for (i = 0; i < NUMPROT; i++){
  			memset(&hints, 0, sizeof(struct addrinfo));
  			hints.ai_socktype = SOCK_DGRAM;
  			hints.ai_flags = AI_PASSIVE;
  			if(Protocolfamily[i] == IPv4){
  				hints.ai_family = AF_INET;
  			}else if(Protocolfamily[i] == IPv6){
  				hints.ai_family = PF_INET6;
  			}else{
  				hints.ai_family = PF_UNSPEC;
  			}
  
  			if(UDPbind_UDPListener_port_get(thisLi) != -1){
  				snprintf(portbuf, NI_MAXSERV, "%" OV_PRINT_INT, UDPbind_UDPListener_port_get(thisLi));
  			} else if(portbuf[0] == '\0') {
  				snprintf(portbuf, NI_MAXSERV, "%" OV_PRINT_INT, 0);
  			} else {
  				//reuse port from the last protocol
  			}
  
  			if((ret = getaddrinfo(NULL, portbuf, &hints, &resultingaddrinfo)) != 0) {
  				KS_logfile_error(("%s: getaddrinfo failed: %d", this->v_identifier, ret));
  				thisLi->v_SocketState = UDPbind_CONNSTATE_COULDNOTOPEN;
  				return;
  			}
  
  			//create an endpoint for communication
  			//setting protocol type
  			fd = socket(resultingaddrinfo->ai_family, resultingaddrinfo->ai_socktype, resultingaddrinfo->ai_protocol);
  			if(fd == UDPBIND_INVALID_SOCKET){
  #if OV_SYSTEM_NT
  				errno = WSAGetLastError();
  #endif
  				//error. Try next protocol
  				freeaddrinfo(resultingaddrinfo);
  				resultingaddrinfo = NULL;
  				continue;
  			}
  
  			if(resultingaddrinfo->ai_family == AF_INET) {
  				KS_logfile_debug(("%s: found IPv4 socket: %d", thisLi->v_identifier, fd));
  			} else if (resultingaddrinfo->ai_family == AF_INET6) {
  				KS_logfile_debug(("%s: found IPv6 socket: %d", thisLi->v_identifier, fd));
  				//restricting this port to V6 only, not IPv4 mapped address like ::ffff:10.1.1.1
  				if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&opt_on, sizeof(opt_on)) == -1) {
  					//error. Try next protocol
  					freeaddrinfo(resultingaddrinfo);
  					resultingaddrinfo = NULL;
  					continue;
  				}
  			} else {
  				//Blacklisting other than IPv4 and IPv6, should not get hit
  				KS_logfile_debug(("%s: found non INET-socket: %d. closing socket", thisLi->v_identifier, fd));
  				UDPBIND_CLOSE_SOCKET(fd);
  				freeaddrinfo(resultingaddrinfo);
  				resultingaddrinfo = NULL;
  				continue;
  			}
  
  			if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt_on, sizeof(opt_on))) {
  				KS_logfile_warning(("%s: could not set option SO_REUSEADDR for socket: %d", thisLi->v_identifier, fd));
  				KS_logfile_print_sysMsg();
  			}
  
  			//setting source address and port
  			if (bind(fd, resultingaddrinfo->ai_addr, resultingaddrinfo->ai_addrlen)) {
  				freeaddrinfo(resultingaddrinfo);
  				resultingaddrinfo = NULL;
  				continue;
  			}
  
  			//sockaddsize should indicate the amount of space of addr (in bytes) but could be actual size of the last socket address.
  			sockaddsize = sizeof(sa_stor);
  			//get the current address to which we are bound
  			if(getsockname(fd, sockaddress, &sockaddsize)) {
  				KS_logfile_error(("%s: getsockname failed", this->v_identifier));
  				KS_logfile_print_sysMsg();
  				thisLi->v_SocketState = UDPbind_CONNSTATE_COULDNOTOPEN;
  				freeaddrinfo(resultingaddrinfo);
  				resultingaddrinfo = NULL;
  				return;
  			}
  
  			//convert the socket address to a corresponding host and service
  			if(getnameinfo( sockaddress, sockaddsize, hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf), flags)) {
  				KS_logfile_error(("%s: getnameinfo failed", this->v_identifier));
  				KS_logfile_print_sysMsg();
  				thisLi->v_SocketState = UDPbind_CONNSTATE_COULDNOTOPEN;
  				freeaddrinfo(resultingaddrinfo);
  				resultingaddrinfo = NULL;
  				return;
  			}
  
  			KS_logfile_debug(("%s: listening on %s on port %s (socket: %d)",this->v_identifier, hostbuf, portbuf, fd));
  
  			if(Protocolfamily[i] == IPv4){
  				sockfds[0] = fd;
  			}else if(Protocolfamily[i] == IPv6){
  				sockfds[1] = fd;
  			}
  		//End of loop --> sockets are open
  		}
  		freeaddrinfo(resultingaddrinfo);
  
  		if(sockfds[0] == UDPBIND_INVALID_SOCKET && sockfds[1] == UDPBIND_INVALID_SOCKET){
  			KS_logfile_error(("%s: failed to open socket: %d", thisLi->v_identifier, errno));
  			ks_logfile_print_sysMsg();
  			thisLi->v_SocketState = UDPbind_CONNSTATE_COULDNOTOPEN;
  			return;
  		}
  
  		if(UDPbind_UDPListener_port_get(thisLi) == -1) {
  			UDPbind_UDPListener_port_set(thisLi, atoi(portbuf));
  		}
  		//remembering IPv4 socket
  		OV_UDPBIND_SETSOCKET2INT(sockfds[0], thisLi->v_socket[0]);
  
  		//remembering IPv6 socket
  		OV_UDPBIND_SETSOCKET2INT(sockfds[1], thisLi->v_socket[1]);
  
  		//the OV variable can hold only a valid socket or -1 (no INVALID_SOCKET even on windows)
  		if(thisLi->v_socket[0] != -1 || thisLi->v_socket[1] != -1) {
  			thisLi->v_SocketState = KSBASE_CONNSTATE_OPEN;
  		} else {
  			thisLi->v_SocketState = KSBASE_CONNSTATE_COULDNOTOPEN;
  		}
  	}
  	/**
  	 * Socket is open now
  	 */
  	if(thisLi->v_SocketState == UDPbind_CONNSTATE_OPEN) {
  		OV_UDPBIND_SETINT2SOCKET(thisLi->v_socket[0], sockfds[0]);
  		OV_UDPBIND_SETINT2SOCKET(thisLi->v_socket[1], sockfds[1]);
  
  		highest = 0;
  		FD_ZERO(&fds);
  		for (i = 0; i < NUMPROT; i++) {
  			if(sockfds[i] != UDPBIND_INVALID_SOCKET){
  				FD_SET(sockfds[i], &fds);
  				highest = (sockfds[i] > highest ? sockfds[i] : highest);
  			}
  		}
  
  		waitd.tv_sec = 0;     // Set Timeout
  		waitd.tv_usec = 0;    //  do not wait
  		//just check for read
  		ret = select(highest+1, &fds, NULL, NULL, &waitd);
  		if(ret) {
  			KS_logfile_debug(("%s: select returned: %d; line %d",this->v_identifier, ret, __LINE__));
  		}
  		if(ret == UDPBIND_SOCKET_ERROR) {
  #if OV_SYSTEM_NT
  			errno = WSAGetLastError();
  #endif
  			KS_logfile_error(("%s: select returned error %d", this->v_identifier, errno));
  			KS_logfile_print_sysMsg();
  		}
  
  		if(ret>0)	//data arrived on the socket(s)
  		{
  			for (i = 0; (i < NUMPROT); i++) {
  				if ((sockfds[i] == UDPBIND_INVALID_SOCKET) || (!FD_ISSET(sockfds[i], &fds))){
  					continue;
  				}
  				//receive data in chunks (we dont know how much it will be)
  				do
  				{
  					//reallocate memory for receiving data. Note the temp-pointer: if realloc fails, the original pointer is NOT freed
  					tempdata = ov_realloc(thisLi->v_inData.data, thisLi->v_inData.length + UDPbind_CHUNKSIZE);
  					if(!tempdata) {
  						KS_logfile_error(("%s: failed to allocate memory for received data (length: %u)", this->v_identifier, thisLi->v_inData.length+UDPbind_CHUNKSIZE));
  						ksbase_free_KSDATAPACKET(&(thisLi->v_inData));
  						return;
  					}
  
  					//if this is the first chunk of data in the packet, initialize the read pointer
  					if(!thisLi->v_inData.readPT) {
  						thisLi->v_inData.readPT = tempdata;
  					} else {
  						/*	get the readPT index and set readPT to this index in the newly allocated memory	*/
  						thisLi->v_inData.readPT = tempdata + (thisLi->v_inData.readPT - thisLi->v_inData.data);
  					}
  					thisLi->v_inData.data = tempdata;
  					/*	tempdata has done its job now. not used from here on	*/
  
  					if(!thisLi->v_inData.writePT) {
  						thisLi->v_inData.writePT = thisLi->v_inData.data;
  					} else {
  						thisLi->v_inData.writePT = thisLi->v_inData.data + thisLi->v_inData.length;
  					}
  					thisLi->v_remoteAddrLen = sizeof(thisLi->v_remoteAddress); /* init length of addresses */
  					//receive data
  					ret = recvfrom(sockfds[i], (char*) thisLi->v_inData.writePT, UDPbind_CHUNKSIZE, 0,
  							(struct sockaddr *)&thisLi->v_remoteAddress, &thisLi->v_remoteAddrLen);
  					if (ret == UDPBIND_SOCKET_ERROR){
  						KS_logfile_debug(("%s: error receiving. Closing socket.", this->v_identifier));
  						for (i = 0; i < NUMPROT; i++){
  							UDPBIND_CLOSE_SOCKET(sockfds[i]);
  							thisLi->v_socket[i] = -1;
  						}
  						thisLi->v_ConnectionState = UDPbind_CONNSTATE_CLOSED;
  						if(!thisLi->v_inData.length)	/*	nothing was received --> free memory	*/
  						{
  							ov_free(thisLi->v_inData.data);
  							thisLi->v_inData.data = NULL;
  						}
  						KS_logfile_debug(("%s: Setting ConnectionTimeOut to %u.", this->v_identifier, thisLi->v_UnusedDataTimeOut));
  						thisLi->v_ConnectionTimeOut = thisLi->v_UnusedDataTimeOut;
  						return;
  					}
  
  					//update data length
  					thisLi->v_inData.length += ret;
  					//move writept to end of data
  					thisLi->v_inData.writePT += ret;
  
  					datareceived = TRUE;
  
  				}while((ret == UDPbind_CHUNKSIZE) && FD_ISSET(sockfds[i], &fds));
  
  				if(datareceived) {
  					thisLi->v_lastRecvSocket = sockfds[i];
  					/**********************************************************************************************************************************************************
  					 *	Associate ClientHandler if needed
  					 *********************************************************************************************************************************************************/
  					if(thisLi->v_ClientHandlerAssociated != KSBASE_CH_ASSOCIATED){
  						pProtIdent = Ov_GetChild(UDPbind_AssocSpecificClientHandler, thisLi);
  						if(pProtIdent) {
  							Ov_GetVTablePtr(ksbase_ProtocolIdentificator, pVTBLProtIdent, pProtIdent);
  							if(!pVTBLProtIdent) {
  								KS_logfile_error(("%s: error getting VTablePtr for %s", this->v_identifier, pProtIdent->v_identifier));
  							} else {
  								pVTBLProtIdent->m_createClientHandler(pProtIdent, Ov_StaticPtrCast(ksbase_Channel, thisLi));
  							}
  						} else {
  							UDPbind_UDPListener_AssociateClientHandler(Ov_StaticPtrCast(ksbase_Channel, thisLi));
  						}
  					}
  
  					/*****************************************************************************************************************************************************************************
  					 *	Process received data
  					 ****************************************************************************************************************************************************************************/
  					//update receivetime
  					ov_time_gettime(&(thisLi->v_LastReceiveTime));
  					if(thisLi->v_ClientHandlerAssociated == KSBASE_CH_ASSOCIATED)
  					{	//there is a ClientHandler associated. Call its HandleRequest function.
  						pClientHandler = Ov_GetChild(ksbase_AssocChannelClientHandler, thisLi);
  						if(pClientHandler)
  						{
  							Ov_GetVTablePtr(ksbase_ClientHandler, pVTBLClientHandler, pClientHandler);
  							if(pVTBLClientHandler)
  							{
  								KS_logfile_debug(("%s: handing over data to %s to handle it.", thisLi->v_identifier, pClientHandler->v_identifier));
  								result = pVTBLClientHandler->m_HandleRequest(pClientHandler, Ov_StaticPtrCast(ksbase_Channel, thisLi), &(thisLi->v_inData), &(thisLi->v_outData));
  								if(Ov_Fail(result))
  								{
  									KS_logfile_error(("%s: processing of received data by %s failed: %s", thisLi->v_identifier, pClientHandler->v_identifier, ov_result_getresulttext(result)));
  									ksbase_free_KSDATAPACKET(&(thisLi->v_inData));
  									ksbase_free_KSDATAPACKET(&(thisLi->v_outData));
  									return;
  								} else 	{
  									ksbase_free_KSDATAPACKET(&(thisLi->v_inData));
  									UDPbind_UDPListener_SendData(Ov_StaticPtrCast(ksbase_Channel, thisLi));
  									return;
  								}
  							} else {
  								KS_logfile_error(("%s: no Vtable found for ClientHandler %s.", thisLi->v_identifier, pClientHandler->v_identifier));
  								ksbase_free_KSDATAPACKET(&(thisLi->v_inData));
  								ksbase_free_KSDATAPACKET(&(thisLi->v_outData));
  								return;
  							}
  						} else {
  							KS_logfile_error(("%s: no ClientHandler associated.", thisLi->v_identifier));
  							ksbase_free_KSDATAPACKET(&(thisLi->v_inData));
  							ksbase_free_KSDATAPACKET(&(thisLi->v_outData));
  							return;
  						}
  					}
  					thisLi->v_ClientHandlerAssociated = KSBASE_CH_NOTASSOCATIED;
  					/*****************************************************************************************************************************************************************************
  					 * Send data if there is still something in the buffer
  					 ****************************************************************************************************************************************************************************/
  					if(thisLi->v_outData.length) {
  						UDPbind_UDPListener_SendData(Ov_StaticPtrCast(ksbase_Channel, thisLi));
  					}
  				}
  			}
  		}
  	}
  	return;
  }
  
  OV_DLLFNCEXPORT OV_RESULT UDPbind_UDPListener_SendData(
  		OV_INSTPTR_ksbase_Channel this
  ) {
  	OV_INSTPTR_UDPbind_UDPListener pListener = Ov_StaticPtrCast(UDPbind_UDPListener, this);
  	OV_INT ret;
  	if((pListener->v_lastRecvSocket != -1) && pListener->v_outData.length){
  		do{
  			ret = sendto(pListener->v_lastRecvSocket, (char*) pListener->v_outData.readPT,
  					pListener->v_outData.length - (pListener->v_outData.readPT - pListener->v_outData.data),
  					0, (struct sockaddr*) &pListener->v_remoteAddress, pListener->v_remoteAddrLen);
  			if (ret == UDPBIND_SOCKET_ERROR) {
  #if OV_SYSTEM_NT
  				errno = WSAGetLastError();
  #endif
  				KS_logfile_error(("%s: error sending data (errno is %d)", this->v_identifier, errno));
  				KS_logfile_print_sysMsg();
  				ksbase_free_KSDATAPACKET(&pListener->v_outData);
  				pListener->v_remoteAddrLen = 0;
  				return OV_ERR_GENERIC;
  			}
  			pListener->v_outData.readPT += ret;
  			} while(pListener->v_outData.readPT < (pListener->v_outData.data + pListener->v_outData.length));
  			if((pListener->v_outData.readPT - pListener->v_outData.data) >= (OV_INT) pListener->v_outData.length)
  			{
  				ksbase_free_KSDATAPACKET(&(pListener->v_outData));
  				KS_logfile_debug(("%s: everything sent", pListener->v_identifier));
  			}
  	}
  	return OV_ERR_OK;
  }
  
  OV_DLLFNCEXPORT OV_RESULT UDPbind_UDPListener_OpenLocalConn(
  		OV_INSTPTR_ksbase_Channel this,
  		OV_STRING port
  ) {
  	KS_logfile_info(("%s: OpenLocalConn called for UDPListener. Doing nothing...", this->v_identifier));
  	return OV_ERR_OK;
  }
  
  OV_DLLFNCEXPORT OV_RESULT UDPbind_UDPListener_OpenConnection(
  		OV_INSTPTR_ksbase_Channel this,
  		OV_STRING host,
  		OV_STRING port
  ) {
  	KS_logfile_info(("%s: OpenConnection called for UDPListener. Doing nothing...", this->v_identifier));
  	return OV_ERR_OK;
  }
  
  OV_DLLFNCEXPORT void UDPbind_UDPListener_CloseConnection(
  		OV_INSTPTR_ksbase_Channel this
  ) {
  	KS_logfile_info(("%s: CloseConnection called for UDPListener. Doing nothing...", this->v_identifier));
  	return;
  }
  
  OV_DLLFNCEXPORT OV_RESULT UDPbind_UDPListener_AssociateClientHandler(
  		OV_INSTPTR_ksbase_Channel this
  ) {
  
  	OV_INSTPTR_ov_class pClassProtIdent = NULL;
  	OV_INSTPTR_ksbase_ProtocolIdentificator pProtIdent = NULL;
  	OV_VTBLPTR_ksbase_ProtocolIdentificator pVTBLProtIdent = NULL;
  	OV_RESULT result;
  
  	//iterate over all classes derived from ksbase_ProtocolIdentificator
  	pClassProtIdent = (Ov_StaticPtrCast(ov_class, Ov_GetFirstChild(ov_inheritance, pclass_ksbase_ProtocolIdentificator)));
  	while(pClassProtIdent)
  	{
  		//iterate over all instances of the identificator class
  		pProtIdent = Ov_StaticPtrCast(ksbase_ProtocolIdentificator, Ov_GetFirstChild(ov_instantiation, pClassProtIdent));
  		while(pProtIdent)
  		{
  			//get VTable of protocol identificator
  			Ov_GetVTablePtr(ksbase_ProtocolIdentificator, pVTBLProtIdent, pProtIdent);
  			if(!pVTBLProtIdent)
  			{
  				KS_logfile_error(("Could not determine VTable of ProtocolIdentificator %s - Cancelling operation.", pProtIdent->v_identifier));
  				return OV_ERR_NOTIMPLEMENTED;
  			}
  			else
  			{
  				//check if protocol is recognized by this Identificator
  				if(pVTBLProtIdent->m_identify(pProtIdent, this) == TRUE)
  				{	//if so, create ClientHandler
  					KS_logfile_debug(("Protocol identified by %s (Class %s). Creating Clienthandler", pProtIdent->v_identifier, Ov_GetParent(ov_instantiation, pProtIdent)->v_identifier));
  					result = pVTBLProtIdent->m_createClientHandler(pProtIdent, this);
  					if(Ov_Fail(result))
  					{
  						KS_logfile_error(("ClientHandler could not be created. Reason: %s", ov_result_getresulttext(result)));
  						return result;
  					}
  					KS_logfile_debug(("ClientHandler created."));
  					this->v_ClientHandlerAssociated = KSBASE_CH_ASSOCIATED;
  					this->v_ConnectionTimeOut = UDPbind_TTL_AFTER_ASSOC;
  					break;
  				}
  			}
  			pProtIdent = Ov_StaticPtrCast(ksbase_ProtocolIdentificator, Ov_GetNextChild(ov_instantiation, pProtIdent));
  		}
  		//if ClientHandler could be Associated, do not go on
  		if(this->v_ClientHandlerAssociated == KSBASE_CH_ASSOCIATED)
  			break;
  		else
  			pClassProtIdent = Ov_StaticPtrCast(ov_class, Ov_GetNextChild(ov_inheritance, pClassProtIdent));
  	}
  	//if no ClientHanlder could be associated Delete Channel
  	if(this->v_ClientHandlerAssociated == KSBASE_CH_NOTASSOCATIED)
  	{
  		this->v_ClientHandlerAssociated = KSBASE_CH_NOTFOUND;
  		KS_logfile_error(("No ClientHandler could be associated."));
  	}
  	return OV_ERR_OK;
  }
  