Internal Error when sending notification to the NetConf client

Hi,
I suggest you run the examples.confd/netconf_notifications example on a machine of your choice, e.g. a laptop, and tcpdump the ConfD IPC port. Port 4565 in that example.
See the README in the example for details.
You can edit the example to send a notification similar to what you do in your application doing something similar to what I did in an earlier post in this thread:

Hi,

we managed to catch a message of the example application.
we compare the message I capture with tcpdump and the message of the sample application - the messages are almost equal.
The only different is on ncn_source_host.

In the message I send it looks like that:
0x0070: 6106 610c 610c 6129 612b 6200 0487 8b61 a.a.a.a)a+b…a
on the sample application it looks like that:
0x0070: 6106 611a 6109 612d 6135 6200 0dd1 4761 a.a.a.a-a5b…Ga

The code looks the same (see below the copy of the create notification code):
struct in_addr an_addr = {0xa0a0a0a0};

can you elaborate the diffrence between these 2 notifications?
can it cause th eInternal error we continue to receive in our application (and not in the sample application)?

thanks
Inbal

confd_tag_value_t values[11];
int Index = 0;
confd_hkeypath_t *p_KeyPath;
struct sockaddr_in SocketAddress;
struct in_addr an_addr = {0xa0a0a0a0};

//create socket to translate the keypath
int MappiSocket;
SocketAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
SocketAddress.sin_family = AF_INET;
SocketAddress.sin_port = htons(CONFD_PORT);

if ((MappiSocket = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
    DEBUG(netConfTraceP, <<"ConfDAdaptorManager::CommitWasDoneByOther socket creation failed " );
}
if (maapi_connect(MappiSocket, (struct sockaddr *)&SocketAddress, sizeof (SocketAddress)) < 0)
{
    DEBUG(netConfTraceP, <<"ConfDAdaptorManager::CommitWasDoneByOther socket connect failed " );
}
if (maapi_xpath2kpath(MappiSocket, Path, &p_KeyPath) != CONFD_OK) //translate the keypath
{
    DEBUG(netConfTraceP, << "Cannot translate xpath\n");
}
maapi_close(MappiSocket);
DEBUG(netConfTraceP, <<"ConfDAdaptorManager::CommitWasDoneByOther  maapi_close ");

//set the values of the notification
CONFD_SET_TAG_XMLBEGIN(&values[Index],   ncn_netconf_config_change, ncn__ns);
Index++;
CONFD_SET_TAG_XMLBEGIN(&values[Index],   ncn_changed_by,            ncn__ns);
Index++;
CONFD_SET_TAG_STR(&values[Index],        ncn_username,              "admin");
Index++;
CONFD_SET_TAG_UINT32(&values[Index],     ncn_session_id,            0);
Index++;
CONFD_SET_TAG_IPV4(&values[Index],       ncn_source_host,           an_addr);
Index++;
CONFD_SET_TAG_XMLEND(&values[Index],     ncn_changed_by,            ncn__ns);
Index++;
CONFD_SET_TAG_ENUM_VALUE(&values[Index], ncn_datastore,             ncn_running);
Index++;
CONFD_SET_TAG_XMLBEGIN(&values[Index],   ncn_edit,                  ncn__ns);
Index++;
CONFD_SET_TAG_OBJECTREF(&values[Index],  ncn_target,                p_KeyPath);
Index++;
CONFD_SET_TAG_XMLEND(&values[Index],     ncn_edit,                  ncn__ns);
Index++;
CONFD_SET_TAG_XMLEND(&values[Index],     ncn_netconf_config_change, ncn__ns);
Index++;

That part of the notification message (around offset 0x0070) is a time stamp, hex 61 ascii ‘a’ is uninitialized memory.

6106 610c 610c 6129 612b 6200 0487 8b61
 Jun   12   12   29   43  microsec

OK, the rest of the frame is the same.
The part that contains the data filled by the application is exactly the same.
And still, from the application I receive Internal Error, but when running the sample it doesn’t.
Can we have more detailed info regarding the “internal error”?

Hi,

I did dump to confd according to the instructions in the user guide (confd --debug-dump mydump1).

How can I send to you the output file so maybe you can find some clue why I get “devel-c Internal error on API request” when sending notification.

Thanks,

Debug dump files are something you send to Tail-f support if you have a support account setup with them.

Rather than trying to get help with debug dump files from the user forum, I suggest you enable the error log in confd.conf and print it using for example
$ confd --printlog error.log
When you get a “API request” error from sending your notification, look for something like a “capi_server proto_request” error message.
That should give you a bit more information on what ConfD received from your application that caused the “API request” error.

See ConfD 6.4 UG Chapter 28.12.4. “General Troubleshooting Strategies” under “Debug error log” on how to enable the error log in confd.conf.
See the confd(1) man page under “–printlog” on how to print the error log.

Hi,

When using the error.log I got the following printout:
11-Jul-2017::11:41:53.167 <0.79.0> <0.231.0> capi_server:2180: capi_server proto_request error:badarg for

<<131,104,6,97,170,100,0,7,78,69,84,67,79,78,70,100,0,9,117,110,100,101,102,
  105,110,101,100,104,2,97,19,104,9,98,0,0,7,225,97,7,97,11,97,11,97,41,97,
  53,98,0,0,98,56,97,0,97,0,97,2,104,2,100,0,4,104,120,109,108,108,0,0,0,11,
  104,2,108,0,0,0,1,98,74,47,101,144,98,125,90,189,67,100,0,5,115,116,97,114,
  116,104,2,108,0,0,0,1,98,74,47,101,144,98,43,247,138,89,100,0,5,115,116,97,
  114,116,104,2,98,51,229,49,111,109,0,0,0,5,97,100,109,105,110,104,2,98,22,
  52,231,188,104,2,97,12,97,0,104,2,98,83,114,28,102,104,4,97,160,97,160,97,
  160,97,160,104,2,108,0,0,0,1,98,74,47,101,144,98,43,247,138,89,100,0,4,115,
  116,111,112,104,2,98,26,203,106,18,104,2,97,28,97,0,104,2,108,0,0,0,1,98,
  74,47,101,144,98,102,79,133,106,100,0,5,115,116,97,114,116,104,2,98,114,23,
  140,120,104,2,97,34,108,0,0,0,3,98,61,148,157,135,98,0,211,222,254,108,0,0,
  0,1,98,100,243,39,133,98,33,25,200,79,106,104,2,108,0,0,0,1,98,74,47,101,
  144,98,102,79,133,106,100,0,4,115,116,111,112,104,2,108,0,0,0,1,98,74,47,
  101,144,98,125,90,189,67,100,0,4,115,116,111,112,106>>
  [{io_lib,format,
           ["\"~ts\" is not a valid value.",[12,0]],
           [{file,"io_lib.erl"},{line,168}]},
   {cs_error,add_str,2,[{file,"cs_error.erl"},{line,113}]},
   {cs_error,fmt_error,2,[{file,"cs_error.erl"},{line,63}]},
   {notif_server,strerror,1,[{file,"notif_server.erl"},{line,357}]},
   {capi_server,notif_log,3,[{file,"capi_server.erl"},{line,2294}]},
   {capi_server,socket_request,3,[{file,"capi_server.erl"},{line,2177}]},
   {capi_server,socket_loop,5,[{file,"capi_server.erl"},{line,2110}]},
   {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]

Can you let me know what it means? Can I know from it what is the problem? which attribute?

Thanks,

Hi,

Your struct confd_notification_ctx m_LiveContext contain some trash so that the ConfD internal “flags” field in the struct confd_notification_ctx is set to “2”.

I removed a bad suggestion from my previous post after an expert on this forum pointed out to me that the root cause to the flags being set is not “trash” but actually that you set the deamon context flags to CONFD_DAEMON_FLAG_STRINGSONLY. I.e.

confd_set_daemon_flags(dctx, CONFD_DAEMON_FLAG_STRINGSONLY);

And then your application send the notification as ConfD tag_values instead of strings. while the deamon context strings only flag will be reflected in your struct confd_notification_ctx m_LiveContext->flags == 2

Recommended way forward is to remove the call to confd_set_daemon_flags(dctx, CONFD_DAEMON_FLAG_STRINGSONLY) from your notifier application and just continue sending ConfD tag_values instead of strings.

Hi,

We did a short test and it seems to be the problem - no “internal error” when changing the flag from 2 to 0.

However, for configuration and “get” operations we must have the flag “string only”.
Therefore, I think we should have another deamon for notifications. Please advice regarding the following initialization with the additional deamon (for notification only):

confd_init("ConfdAdaptor", stderr , CONFD_TRACE);  <-- please advice if needed to do it double, one for each deamon.
//configuration deamon init
m_DeamonConfigContext = confd_init_daemon("ConfdAdaptor");
confd_set_daemon_flags(m_DeamonConfigContext , CONFD_DAEMON_FLAG_STRINGSONLY); <--config deamon only!!!
m_ControlSocket = socket(PF_INET, SOCK_STREAM, 0); 
confd_connect(m_DeamonConfigContext , m_ControlSocket, CONTROL_SOCKET, (struct sockaddr*)&socketAddress, sizeof (struct sockaddr_in))
m_WorkerSocket = socket(PF_INET, SOCK_STREAM, 0); 
confd_connect(m_DeamonConfigContext , m_WorkerSocket, WORKER_SOCKET,(struct sockaddr*)&socketAddress,sizeof (struct sockaddr_in))
 //registration for transaciton callbacks and configuration call backs 
confd_register_done(m_DeamonConfigContext );

//notification deamon init
m_DeamonNotifyContext = confd_init_daemon("ConfdNotifications");
confd_register_notification_stream(m_DeamonNotifyContext , &NotificationCallBack, &m_LiveContext) <-- this is done for the notification deamon
confd_register_done(m_DeamonNotifyContext );

Do I miss something?

Hi,

Your struct confd_notification_stream_cbs NotificationCallBack need a worker socket dedicated to sending notifications. That worker socket does not need to be polled. See confd_lib_dp man page “confd_register_notification_stream”