From vfaion at gmail.com Sun Feb 1 13:10:30 2009 From: vfaion at gmail.com (Victor Faion) Date: Sun, 1 Feb 2009 21:10:30 +0000 Subject: [Xorp-hackers] Events and sockets in XORP In-Reply-To: <200901311258.n0VCwQ9a025468@fruitcake.ICSI.Berkeley.EDU> References: <38f1dbe80901300924i20661ac3uf649aa66af8b2267@mail.gmail.com> <200901311258.n0VCwQ9a025468@fruitcake.ICSI.Berkeley.EDU> Message-ID: <38f1dbe80902011310k27edf622xae316df6f6f95a16@mail.gmail.com> On Sat, Jan 31, 2009 at 12:58, Pavlin Radoslavov wrote: >> I was trying to use XORP to create an application layer protocol with >> the routers sending messages to each other over TCP sockets. I created >> a XORP process following the guide about static routes, but I still >> don't understand some things such as when functions of the process get >> called. For example in the main function of the process there is an >> event loop. How do the events correspond to functions called, and how >> do you generate events? For example how would you trigger a function >> call on receipt of a message? Also a more general question, I am >> trying to use the socket library provided by XORP and run this code on >> top of XORP, but I'm not sure if I should be making a XORP process to >> do this or is there another way of using the XORP socket library? (I >> also wanted to extract the shortest paths calculated by OSPF and use >> these to open socket connections instead of sending packets.) > > XORP processes are event-driven: you use the eventloop to > register callbacks for various events: timer expires, socket ready > for I/O, etc. > In other words, the functions/methods in your process are event > handlers. It is very important that those handlers return > promptly to the eventloop, otherwise the process operation will be > disturbed (background XRL timers might timeout, etc). > > Unlike other routing processes, the static routes process just > pushes the user configured routes, and doesn't send/receive any > control traffic. > You might want to have a look at RIP/RIPng for example which uses > UDP control packets. > > To send/receive TCP you can do it via the FEA so you don't have to > deal with sockets, etc. > Basically, you need to use the xrl/interfaces/socket4.xif XRL API to > register with the FEA to send/receive TCP. > Then in your protocol you need to implement the receiving (target) > side of socket4_user.xif . > The XRL library itself will take care of the rest: on reception it > will call the appropriate socket4_user.xif method. > Once you process the event, just return back to the eventloop. > I implemented these functions (basically just printing out their parameters): socket4_user_0_1_recv_event socket4_user_0_1_inbound_connect_event socket4_user_0_1_outgoing_connect_event socket4_user_0_1_disconnect_event socket4_user_0_1_error_event I'm not sure how to register with the FEA, I was trying to call send_tcp_listen in my startup function, but I didn't know what parameters to use (especially the sockid). The documentation on that function says: Listen for inbound connections on socket. When a connection request received the socket creator will receive notification through socket4_user/0.1/inbound_connect_event. Does this mean the callback parameter should be my implementation of inbound_connect_event, or is the callback passed just supposed to generate some error if listening on a socket didn't succeed? For the destination target name I was passing "socket4/0.1/tcp_listen", but I'm not sure if this is the right thing to use. > If you have transmission timers that are triggered periodically, > just call the "send" XRL (socket4.xif) and return back to the > eventloop. > The handlers for those timers are scheduled by using the EventLoop > API (e.g., new_oneoff_after(), etc). > > If you need to use raw IP packets, then you can use the > fea_rawpkt4.xif / fea_rawpkt4_client.xif API. > > Of course, you can create and use your own sockets, but then it is > up to you to deal with the extra details: add the socket file > descriptor to the eventoop (EventLoop::add_ioevent_cb()), buffer the > received data, etc. > > Hope that helps, > Pavlin > > P.S. I cannot answer the OSPF-related question because I am not > familiar with the OSPF implementation details. > Thank you for the help, its beginning to make more sense :) From pavlin at ICSI.Berkeley.EDU Mon Feb 2 01:51:45 2009 From: pavlin at ICSI.Berkeley.EDU (Pavlin Radoslavov) Date: Mon, 02 Feb 2009 01:51:45 -0800 Subject: [Xorp-hackers] Events and sockets in XORP In-Reply-To: <38f1dbe80902011310k27edf622xae316df6f6f95a16@mail.gmail.com> References: <38f1dbe80901300924i20661ac3uf649aa66af8b2267@mail.gmail.com> <200901311258.n0VCwQ9a025468@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902011310k27edf622xae316df6f6f95a16@mail.gmail.com> Message-ID: <200902020951.n129pjUe004725@fruitcake.ICSI.Berkeley.EDU> Victor Faion wrote: > > To send/receive TCP you can do it via the FEA so you don't have to > > deal with sockets, etc. > > Basically, you need to use the xrl/interfaces/socket4.xif XRL API to > > register with the FEA to send/receive TCP. > > Then in your protocol you need to implement the receiving (target) > > side of socket4_user.xif . > > The XRL library itself will take care of the rest: on reception it > > will call the appropriate socket4_user.xif method. > > Once you process the event, just return back to the eventloop. > > > > I implemented these functions (basically just printing out their parameters): > > socket4_user_0_1_recv_event > socket4_user_0_1_inbound_connect_event > socket4_user_0_1_outgoing_connect_event > socket4_user_0_1_disconnect_event > socket4_user_0_1_error_event > > I'm not sure how to register with the FEA, I was trying to call > send_tcp_listen in my startup function, but I didn't know what > parameters to use (especially the sockid). > > The documentation on that function says: > Listen for inbound connections on socket. When a connection request > received the socket creator will receive notification through > socket4_user/0.1/inbound_connect_event. > > Does this mean the callback parameter should be my implementation of > inbound_connect_event, or is the callback passed just supposed to > generate some error if listening on a socket didn't succeed? > > For the destination target name I was passing > "socket4/0.1/tcp_listen", but I'm not sure if this is the right thing > to use. First you need to open the TCP socket by using one of the tcp_open* XRLs, which will give you the sockid. Then you can use sockid for additional operations on the socket. You might also have a look at fea/test_xrl_sockets4_tcp.cc for usage of some of the TCP-related XRLs. Pavlin From vfaion at gmail.com Mon Feb 2 10:37:04 2009 From: vfaion at gmail.com (Victor Faion) Date: Mon, 2 Feb 2009 18:37:04 +0000 Subject: [Xorp-hackers] Events and sockets in XORP In-Reply-To: <200902020951.n129pjUe004725@fruitcake.ICSI.Berkeley.EDU> References: <38f1dbe80901300924i20661ac3uf649aa66af8b2267@mail.gmail.com> <200901311258.n0VCwQ9a025468@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902011310k27edf622xae316df6f6f95a16@mail.gmail.com> <200902020951.n129pjUe004725@fruitcake.ICSI.Berkeley.EDU> Message-ID: <38f1dbe80902021037t7c85a3aen662fe94727e6a9ad@mail.gmail.com> On Mon, Feb 2, 2009 at 09:51, Pavlin Radoslavov wrote: > Victor Faion wrote: > >> > To send/receive TCP you can do it via the FEA so you don't have to >> > deal with sockets, etc. >> > Basically, you need to use the xrl/interfaces/socket4.xif XRL API to >> > register with the FEA to send/receive TCP. >> > Then in your protocol you need to implement the receiving (target) >> > side of socket4_user.xif . >> > The XRL library itself will take care of the rest: on reception it >> > will call the appropriate socket4_user.xif method. >> > Once you process the event, just return back to the eventloop. >> > >> >> I implemented these functions (basically just printing out their parameters): >> >> socket4_user_0_1_recv_event >> socket4_user_0_1_inbound_connect_event >> socket4_user_0_1_outgoing_connect_event >> socket4_user_0_1_disconnect_event >> socket4_user_0_1_error_event >> >> I'm not sure how to register with the FEA, I was trying to call >> send_tcp_listen in my startup function, but I didn't know what >> parameters to use (especially the sockid). >> >> The documentation on that function says: >> Listen for inbound connections on socket. When a connection request >> received the socket creator will receive notification through >> socket4_user/0.1/inbound_connect_event. >> >> Does this mean the callback parameter should be my implementation of >> inbound_connect_event, or is the callback passed just supposed to >> generate some error if listening on a socket didn't succeed? >> >> For the destination target name I was passing >> "socket4/0.1/tcp_listen", but I'm not sure if this is the right thing >> to use. > > First you need to open the TCP socket by using one of the tcp_open* > XRLs, which will give you the sockid. Then you can use sockid for > additional operations on the socket. > > You might also have a look at fea/test_xrl_sockets4_tcp.cc for usage > of some of the TCP-related XRLs. > > Pavlin > I was trying to do something like this: int XrlBpsfNode::startup() { const IPv4 localIP("146.169.3.2"); const uint32_t localPort(1337); printf("%s\n", "Starting up XrlBpsfNode"); XrlSocket4V0p1Client cl(this); if(!cl.send_tcp_open_and_bind("socket4/0.1/tcp_open_and_bind", "bpsf/0.1", localIP, localPort, callback(this, &XrlBpsfNode::bind_cb))) { printf("%s\n", "Error opening and binding socket"); return(XORP_ERROR); } return cl.send_tcp_listen("socket4/0.1/tcp_listen", server_sockid, 100, callback(this, &XrlBpsfNode::listen_cb)); } but when I run make I keep getting errors like this: g++ -g -Werror -W -Wall -Wwrite-strings -Wcast-qual -Wpointer-arith -Wcast-align -Woverloaded-virtual -ftemplate-depth-25 -pipe -o xorp_bpsf xorp_bpsf.o ./.libs/libbpsf.a ../xrl/targets/.libs/libbpsfbase.a ../libxipc/.libs/libxipc.a ../libcomm/.libs/libcomm.a ../libxorp/.libs/libxorp.a -lpcap -lcrypto -lrt ./.libs/libbpsf.a(xrl_bpsf_node.o): In function `XrlBpsfNode::startup()': /root/project/xorp1.6/xorp-1.6/bpsf/xrl_bpsf_node.cc:37: undefined reference to `XrlSocket4V0p1Client::send_tcp_open_and_bind(char const*, std::basic_string, std::allocator > const&, IPv4 const&, unsigned int const&, ref_ptr, std::allocator > const*> > const&)' /root/project/xorp1.6/xorp-1.6/bpsf/xrl_bpsf_node.cc:44: undefined reference to `XrlSocket4V0p1Client::send_tcp_listen(char const*, std::basic_string, std::allocator > const&, unsigned int const&, ref_ptr > const&)' collect2: ld returned 1 exit status make: *** [xorp_bpsf] Error 1 even though I have included "xrl/interfaces/socket4_xif.hh" where those functions are defined. I'm not sure if the target destination I'm passing ("bpsf/0.1") is correct. This is the process I wrote which implements socket4_user/0.1, but for some reason the compiler doesn't like it. Victor From pavlin at ICSI.Berkeley.EDU Mon Feb 2 11:48:08 2009 From: pavlin at ICSI.Berkeley.EDU (Pavlin Radoslavov) Date: Mon, 02 Feb 2009 11:48:08 -0800 Subject: [Xorp-hackers] Events and sockets in XORP In-Reply-To: <38f1dbe80902021037t7c85a3aen662fe94727e6a9ad@mail.gmail.com> References: <38f1dbe80901300924i20661ac3uf649aa66af8b2267@mail.gmail.com> <200901311258.n0VCwQ9a025468@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902011310k27edf622xae316df6f6f95a16@mail.gmail.com> <200902020951.n129pjUe004725@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902021037t7c85a3aen662fe94727e6a9ad@mail.gmail.com> Message-ID: <200902021948.n12Jm8BQ008341@fruitcake.ICSI.Berkeley.EDU> > > First you need to open the TCP socket by using one of the tcp_open* > > XRLs, which will give you the sockid. Then you can use sockid for > > additional operations on the socket. > > > > You might also have a look at fea/test_xrl_sockets4_tcp.cc for usage > > of some of the TCP-related XRLs. > > > > Pavlin > > > > > I was trying to do something like this: > > int XrlBpsfNode::startup() { > const IPv4 localIP("146.169.3.2"); > const uint32_t localPort(1337); > printf("%s\n", "Starting up XrlBpsfNode"); > XrlSocket4V0p1Client cl(this); > if(!cl.send_tcp_open_and_bind("socket4/0.1/tcp_open_and_bind", > "bpsf/0.1", localIP, localPort, > callback(this, &XrlBpsfNode::bind_cb))) { > printf("%s\n", "Error opening and binding socket"); > return(XORP_ERROR); > } > return cl.send_tcp_listen("socket4/0.1/tcp_listen", server_sockid, 100, > callback(this, &XrlBpsfNode::listen_cb)); > } In the above code you cannot call send_tcp_open_and_bind() and send_tcp_listen() back-to-back. You must return to the eventloop after you call the first XRL, because only when the bind_cb is called you will get the sockid for the new socket. In other words, only after bind_cb is called you can call the rest of the XRL(s) that require sockid. > but when I run make I keep getting errors like this: > > g++ -g -Werror -W -Wall -Wwrite-strings -Wcast-qual -Wpointer-arith > -Wcast-align -Woverloaded-virtual -ftemplate-depth-25 -pipe -o > xorp_bpsf xorp_bpsf.o ./.libs/libbpsf.a > ../xrl/targets/.libs/libbpsfbase.a ../libxipc/.libs/libxipc.a > ../libcomm/.libs/libcomm.a ../libxorp/.libs/libxorp.a -lpcap -lcrypto > -lrt > ./.libs/libbpsf.a(xrl_bpsf_node.o): In function `XrlBpsfNode::startup()': > /root/project/xorp1.6/xorp-1.6/bpsf/xrl_bpsf_node.cc:37: undefined > reference to `XrlSocket4V0p1Client::send_tcp_open_and_bind(char > const*, std::basic_string, > std::allocator > const&, IPv4 const&, unsigned int const&, > ref_ptr std::char_traits, std::allocator > const*> > const&)' > /root/project/xorp1.6/xorp-1.6/bpsf/xrl_bpsf_node.cc:44: undefined > reference to `XrlSocket4V0p1Client::send_tcp_listen(char const*, > std::basic_string, std::allocator > > const&, unsigned int const&, ref_ptr const&> > const&)' > collect2: ld returned 1 exit status > make: *** [xorp_bpsf] Error 1 > > > even though I have included "xrl/interfaces/socket4_xif.hh" where > those functions are defined. I'm not sure if the target destination > I'm passing ("bpsf/0.1") is correct. This is the process I wrote which > implements socket4_user/0.1, but for some reason the compiler doesn't > like it. I think the issue is that you need to link your program with the particular XRL interface library as well: (top_builddir)/xrl/interfaces/libsocket4xif.la For reference, see the test_xrl_sockets4_tcp entry in fea/Makefile.am . Pavlin From vfaion at gmail.com Tue Feb 3 09:06:52 2009 From: vfaion at gmail.com (Victor Faion) Date: Tue, 3 Feb 2009 17:06:52 +0000 Subject: [Xorp-hackers] Events and sockets in XORP In-Reply-To: <200902021948.n12Jm8BQ008341@fruitcake.ICSI.Berkeley.EDU> References: <38f1dbe80901300924i20661ac3uf649aa66af8b2267@mail.gmail.com> <200901311258.n0VCwQ9a025468@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902011310k27edf622xae316df6f6f95a16@mail.gmail.com> <200902020951.n129pjUe004725@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902021037t7c85a3aen662fe94727e6a9ad@mail.gmail.com> <200902021948.n12Jm8BQ008341@fruitcake.ICSI.Berkeley.EDU> Message-ID: <38f1dbe80902030906q2ef8de48o631f87c9ff1b3012@mail.gmail.com> On Mon, Feb 2, 2009 at 19:48, Pavlin Radoslavov wrote: >> > First you need to open the TCP socket by using one of the tcp_open* >> > XRLs, which will give you the sockid. Then you can use sockid for >> > additional operations on the socket. >> > >> > You might also have a look at fea/test_xrl_sockets4_tcp.cc for usage >> > of some of the TCP-related XRLs. >> > >> > Pavlin >> > >> >> >> I was trying to do something like this: >> >> int XrlBpsfNode::startup() { >> const IPv4 localIP("146.169.3.2"); >> const uint32_t localPort(1337); >> printf("%s\n", "Starting up XrlBpsfNode"); >> XrlSocket4V0p1Client cl(this); >> if(!cl.send_tcp_open_and_bind("socket4/0.1/tcp_open_and_bind", >> "bpsf/0.1", localIP, localPort, >> callback(this, &XrlBpsfNode::bind_cb))) { >> printf("%s\n", "Error opening and binding socket"); >> return(XORP_ERROR); >> } >> return cl.send_tcp_listen("socket4/0.1/tcp_listen", server_sockid, 100, >> callback(this, &XrlBpsfNode::listen_cb)); >> } > > In the above code you cannot call send_tcp_open_and_bind() and > send_tcp_listen() back-to-back. You must return to the eventloop > after you call the first XRL, because only when the bind_cb is > called you will get the sockid for the new socket. > > In other words, only after bind_cb is called you can call the rest > of the XRL(s) that require sockid. > >> but when I run make I keep getting errors like this: >> >> g++ -g -Werror -W -Wall -Wwrite-strings -Wcast-qual -Wpointer-arith >> -Wcast-align -Woverloaded-virtual -ftemplate-depth-25 -pipe -o >> xorp_bpsf xorp_bpsf.o ./.libs/libbpsf.a >> ../xrl/targets/.libs/libbpsfbase.a ../libxipc/.libs/libxipc.a >> ../libcomm/.libs/libcomm.a ../libxorp/.libs/libxorp.a -lpcap -lcrypto >> -lrt >> ./.libs/libbpsf.a(xrl_bpsf_node.o): In function `XrlBpsfNode::startup()': >> /root/project/xorp1.6/xorp-1.6/bpsf/xrl_bpsf_node.cc:37: undefined >> reference to `XrlSocket4V0p1Client::send_tcp_open_and_bind(char >> const*, std::basic_string, >> std::allocator > const&, IPv4 const&, unsigned int const&, >> ref_ptr> std::char_traits, std::allocator > const*> > const&)' >> /root/project/xorp1.6/xorp-1.6/bpsf/xrl_bpsf_node.cc:44: undefined >> reference to `XrlSocket4V0p1Client::send_tcp_listen(char const*, >> std::basic_string, std::allocator > >> const&, unsigned int const&, ref_ptr> const&> > const&)' >> collect2: ld returned 1 exit status >> make: *** [xorp_bpsf] Error 1 >> >> >> even though I have included "xrl/interfaces/socket4_xif.hh" where >> those functions are defined. I'm not sure if the target destination >> I'm passing ("bpsf/0.1") is correct. This is the process I wrote which >> implements socket4_user/0.1, but for some reason the compiler doesn't >> like it. > > I think the issue is that you need to link your program with the > particular XRL interface library as well: > > (top_builddir)/xrl/interfaces/libsocket4xif.la > > For reference, see the test_xrl_sockets4_tcp entry in > fea/Makefile.am . > > Pavlin > I think I understand the way the eventloop is supposed to be used a little better, basically every function needs to be scheduled on the eventloop and have a callback. Am I allowed to chain events using callbacks (i.e., have a callback schedule an event)? I changed the open/bind/listening to go like this: int XrlBpsfNode::startup() { const IPv4 localIP("146.169.3.2"); const uint32_t localPort(1337); XLOG_INFO("%s\n", "Starting up XrlBpsfNode"); XrlSocket4V0p1Client cl(this); if(!cl.send_tcp_open_and_bind("socket4/0.1/tcp_open_and_bind", xrl_router().instance_name(), localIP, localPort, callback(this, &XrlBpsfNode::bind_cb))) { XLOG_ERROR("%s\n", "Error opening and binding socket"); return(XORP_ERROR); } return (XORP_OK); } and then the bind_cb function schedules the function that calls send_tcp_listen, but I'm not sure if this is how I'm supposed to schedule things: void XrlBpsfNode::bind_cb(const XrlError& e, const string* psockid) { if (e != XrlError::OKAY()) { XLOG_ERROR("Xrl Error: %s\n", e.str().c_str()); return; } server_sockid = *psockid; const TimeVal b(1, 0); bind_timer = event_loop.new_oneoff_after( b, callback(this, &XrlBpsfNode::listen)); } void XrlBpsfNode::listen() { XrlSocket4V0p1Client cl(this); cl.send_tcp_listen("socket4/0.1/tcp_listen", server_sockid, 100, callback(this, &XrlBpsfNode::listen_cb)); } void XrlBpsfNode::listen_cb(const XrlError& e) { if (e != XrlError::OKAY()) XLOG_INFO("%s\n", "Error when listening on socket"); } When I run xorp_rtrmgr I get an error regarding socket4: [ 2009/02/03 16:51:18 INFO xorp_rtrmgr:4034 RTRMGR +249 master_conf_tree.cc execute ] Changed modules: bpsf, interfaces, firewall, fea [ 2009/02/03 16:51:18 INFO xorp_rtrmgr:4034 RTRMGR +101 module_manager.cc execute ] Executing module: bpsf (bpsf/xorp_bpsf) [ 2009/02/03 16:51:18 INFO xorp_bpsf XrlBpsfTarget ] creating XrlBpsfNode [ 2009/02/03 16:51:18 INFO xorp_bpsf XrlBpsfTarget ] Starting up XrlBpsfNode [ 2009/02/03 16:51:18 WARNING xorp_rtrmgr:4034 XrlFinderTarget +407 ../xrl/targets/finder_base.cc handle_finder_0_2_resolve_xrl ] Handling method for finder/0.2/resolve_xrl failed: XrlCmdError 102 Command failed Target "socket4" does not exist or is not enabled. [ 2009/02/03 16:51:18 ERROR xorp_bpsf:4035 XrlBpsfTarget +275 xrl_bpsf_node.cc bind_cb ] Xrl Error: 201 Resolve failed [ 2009/02/03 16:51:20 INFO xorp_rtrmgr:4034 RTRMGR +101 module_manager.cc execute ] Executing module: interfaces (fea/xorp_fea) [ 2009/02/03 16:51:21 INFO xorp_fea MFEA ] MFEA enabled [ 2009/02/03 16:51:21 INFO xorp_fea MFEA ] CLI enabled [ 2009/02/03 16:51:21 INFO xorp_fea MFEA ] CLI started [ 2009/02/03 16:51:21 INFO xorp_fea MFEA ] MFEA enabled [ 2009/02/03 16:51:21 INFO xorp_fea MFEA ] CLI enabled [ 2009/02/03 16:51:21 INFO xorp_fea MFEA ] CLI started [ 2009/02/03 16:51:22 INFO xorp_rtrmgr:4034 RTRMGR +101 module_manager.cc execute ] Executing module: firewall (fea/xorp_fea) [ 2009/02/03 16:51:26 INFO xorp_rtrmgr:4034 RTRMGR +101 module_manager.cc execute ] Executing module: fea (fea/xorp_fea) [ 2009/02/03 16:51:32 INFO xorp_rtrmgr:4034 RTRMGR +2233 task.cc run_task ] No more tasks to run I'm not sure what you meant before when you said that I should register with the FEA to send/receive TCP. Does this mean calling something like send_register_class_event_interest? Many thanks for the help! Victor From pavlin at ICSI.Berkeley.EDU Tue Feb 3 09:45:59 2009 From: pavlin at ICSI.Berkeley.EDU (Pavlin Radoslavov) Date: Tue, 03 Feb 2009 09:45:59 -0800 Subject: [Xorp-hackers] Events and sockets in XORP In-Reply-To: <38f1dbe80902030906q2ef8de48o631f87c9ff1b3012@mail.gmail.com> References: <38f1dbe80901300924i20661ac3uf649aa66af8b2267@mail.gmail.com> <200901311258.n0VCwQ9a025468@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902011310k27edf622xae316df6f6f95a16@mail.gmail.com> <200902020951.n129pjUe004725@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902021037t7c85a3aen662fe94727e6a9ad@mail.gmail.com> <200902021948.n12Jm8BQ008341@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902030906q2ef8de48o631f87c9ff1b3012@mail.gmail.com> Message-ID: <200902031745.n13Hjx51005146@fruitcake.ICSI.Berkeley.EDU> Victor Faion wrote: > I think I understand the way the eventloop is supposed to be used a > little better, basically every function needs to be scheduled on the ~~~~~~~~~~~~~~ Small wording clarification: the above should read "every event processing". The functions/methods in the rest of your code are basically called directly or indirectly by the callbacks. The XRL related callbacks are are also event handling, except that you don't deal directly with the eventloop (the underlying XRL library does that for you). > eventloop and have a callback. Am I allowed to chain events using > callbacks (i.e., have a callback schedule an event)? > > I changed the open/bind/listening to go like this: > > int XrlBpsfNode::startup() { > const IPv4 localIP("146.169.3.2"); > const uint32_t localPort(1337); > XLOG_INFO("%s\n", "Starting up XrlBpsfNode"); > XrlSocket4V0p1Client cl(this); > if(!cl.send_tcp_open_and_bind("socket4/0.1/tcp_open_and_bind", > xrl_router().instance_name(), > localIP, localPort, > callback(this, &XrlBpsfNode::bind_cb))) { > XLOG_ERROR("%s\n", "Error opening and binding socket"); > return(XORP_ERROR); > } > return (XORP_OK); > } The first argument to send_tcp_open_and_bind() must be the recepient target name of that XRL, which typically is the FEA with targetname of "fea". > and then the bind_cb function schedules the function that calls > send_tcp_listen, but I'm not sure if this is how I'm supposed to > schedule things: > > void XrlBpsfNode::bind_cb(const XrlError& e, const string* psockid) { > if (e != XrlError::OKAY()) { > XLOG_ERROR("Xrl Error: %s\n", e.str().c_str()); > return; > } > server_sockid = *psockid; > const TimeVal b(1, 0); > bind_timer = event_loop.new_oneoff_after( > b, callback(this, &XrlBpsfNode::listen)); > } You don't need to schedule a timer to call XrlBpsfNode::listen(); you can call XrlBpsfNode::listen() directly from within the bind_cb callback. Also, the TimeVal b() timer is allocated on the stack and will be destroyed when bind_cb() returns; i.e., the scheduled callback for that timer will never be called. > > void XrlBpsfNode::listen() { > XrlSocket4V0p1Client cl(this); > cl.send_tcp_listen("socket4/0.1/tcp_listen", server_sockid, 100, > callback(this, &XrlBpsfNode::listen_cb)); > } Here again the first argument of send_tcp_listen() must be "fea". > void XrlBpsfNode::listen_cb(const XrlError& e) { > if (e != XrlError::OKAY()) > XLOG_INFO("%s\n", "Error when listening on socket"); > } > When I run xorp_rtrmgr I get an error regarding socket4: > > > [ 2009/02/03 16:51:18 INFO xorp_rtrmgr:4034 RTRMGR +249 > master_conf_tree.cc execute ] Changed modules: bpsf, interfaces, > firewall, fea > [ 2009/02/03 16:51:18 INFO xorp_rtrmgr:4034 RTRMGR +101 > module_manager.cc execute ] Executing module: bpsf (bpsf/xorp_bpsf) > [ 2009/02/03 16:51:18 INFO xorp_bpsf XrlBpsfTarget ] creating XrlBpsfNode > [ 2009/02/03 16:51:18 INFO xorp_bpsf XrlBpsfTarget ] Starting up XrlBpsfNode > [ 2009/02/03 16:51:18 WARNING xorp_rtrmgr:4034 XrlFinderTarget +407 > ../xrl/targets/finder_base.cc handle_finder_0_2_resolve_xrl ] Handling > method for finder/0.2/resolve_xrl failed: XrlCmdError 102 Command > failed Target "socket4" does not exist or is not enabled. After you use target name of "fea" this error should go away. > [ 2009/02/03 16:51:18 ERROR xorp_bpsf:4035 XrlBpsfTarget +275 > xrl_bpsf_node.cc bind_cb ] Xrl Error: 201 Resolve failed > [ 2009/02/03 16:51:20 INFO xorp_rtrmgr:4034 RTRMGR +101 > module_manager.cc execute ] Executing module: interfaces > (fea/xorp_fea) > [ 2009/02/03 16:51:21 INFO xorp_fea MFEA ] MFEA enabled > [ 2009/02/03 16:51:21 INFO xorp_fea MFEA ] CLI enabled > [ 2009/02/03 16:51:21 INFO xorp_fea MFEA ] CLI started > [ 2009/02/03 16:51:21 INFO xorp_fea MFEA ] MFEA enabled > [ 2009/02/03 16:51:21 INFO xorp_fea MFEA ] CLI enabled > [ 2009/02/03 16:51:21 INFO xorp_fea MFEA ] CLI started > [ 2009/02/03 16:51:22 INFO xorp_rtrmgr:4034 RTRMGR +101 > module_manager.cc execute ] Executing module: firewall (fea/xorp_fea) > [ 2009/02/03 16:51:26 INFO xorp_rtrmgr:4034 RTRMGR +101 > module_manager.cc execute ] Executing module: fea (fea/xorp_fea) > [ 2009/02/03 16:51:32 INFO xorp_rtrmgr:4034 RTRMGR +2233 task.cc > run_task ] No more tasks to run > > > I'm not sure what you meant before when you said that I should > register with the FEA to send/receive TCP. Does this mean calling > something like send_register_class_event_interest? Many thanks for the > help! The registration is done when you send XRLs like tcp_open_and_bind. Pavlin From vfaion at gmail.com Tue Feb 3 10:46:10 2009 From: vfaion at gmail.com (Victor Faion) Date: Tue, 3 Feb 2009 18:46:10 +0000 Subject: [Xorp-hackers] Events and sockets in XORP In-Reply-To: <200902031745.n13Hjx51005146@fruitcake.ICSI.Berkeley.EDU> References: <38f1dbe80901300924i20661ac3uf649aa66af8b2267@mail.gmail.com> <200901311258.n0VCwQ9a025468@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902011310k27edf622xae316df6f6f95a16@mail.gmail.com> <200902020951.n129pjUe004725@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902021037t7c85a3aen662fe94727e6a9ad@mail.gmail.com> <200902021948.n12Jm8BQ008341@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902030906q2ef8de48o631f87c9ff1b3012@mail.gmail.com> <200902031745.n13Hjx51005146@fruitcake.ICSI.Berkeley.EDU> Message-ID: <38f1dbe80902031046k6f72eda6w35753354cac4d228@mail.gmail.com> On Tue, Feb 3, 2009 at 17:45, Pavlin Radoslavov wrote: > Victor Faion wrote: > >> I think I understand the way the eventloop is supposed to be used a >> little better, basically every function needs to be scheduled on the > ~~~~~~~~~~~~~~ > > Small wording clarification: the above should read "every event > processing". > The functions/methods in the rest of your code are basically called > directly or indirectly by the callbacks. > > The XRL related callbacks are are also event handling, except that > you don't deal directly with the eventloop (the underlying XRL > library does that for you). > >> eventloop and have a callback. Am I allowed to chain events using >> callbacks (i.e., have a callback schedule an event)? >> >> I changed the open/bind/listening to go like this: >> >> int XrlBpsfNode::startup() { >> const IPv4 localIP("146.169.3.2"); >> const uint32_t localPort(1337); >> XLOG_INFO("%s\n", "Starting up XrlBpsfNode"); >> XrlSocket4V0p1Client cl(this); >> if(!cl.send_tcp_open_and_bind("socket4/0.1/tcp_open_and_bind", >> xrl_router().instance_name(), >> localIP, localPort, >> callback(this, &XrlBpsfNode::bind_cb))) { >> XLOG_ERROR("%s\n", "Error opening and binding socket"); >> return(XORP_ERROR); >> } >> return (XORP_OK); >> } > > The first argument to send_tcp_open_and_bind() must be the recepient > target name of that XRL, which typically is the FEA with targetname > of "fea". > >> and then the bind_cb function schedules the function that calls >> send_tcp_listen, but I'm not sure if this is how I'm supposed to >> schedule things: >> >> void XrlBpsfNode::bind_cb(const XrlError& e, const string* psockid) { >> if (e != XrlError::OKAY()) { >> XLOG_ERROR("Xrl Error: %s\n", e.str().c_str()); >> return; >> } >> server_sockid = *psockid; >> const TimeVal b(1, 0); >> bind_timer = event_loop.new_oneoff_after( >> b, callback(this, &XrlBpsfNode::listen)); >> } > > You don't need to schedule a timer to call XrlBpsfNode::listen(); > you can call XrlBpsfNode::listen() directly from within the bind_cb > callback. > > Also, the TimeVal b() timer is allocated on the stack and will be > destroyed when bind_cb() returns; i.e., the scheduled callback for > that timer will never be called. > >> >> void XrlBpsfNode::listen() { >> XrlSocket4V0p1Client cl(this); >> cl.send_tcp_listen("socket4/0.1/tcp_listen", server_sockid, 100, >> callback(this, &XrlBpsfNode::listen_cb)); >> } > > Here again the first argument of send_tcp_listen() must be "fea". > >> void XrlBpsfNode::listen_cb(const XrlError& e) { >> if (e != XrlError::OKAY()) >> XLOG_INFO("%s\n", "Error when listening on socket"); >> } > >> When I run xorp_rtrmgr I get an error regarding socket4: >> >> >> [ 2009/02/03 16:51:18 INFO xorp_rtrmgr:4034 RTRMGR +249 >> master_conf_tree.cc execute ] Changed modules: bpsf, interfaces, >> firewall, fea >> [ 2009/02/03 16:51:18 INFO xorp_rtrmgr:4034 RTRMGR +101 >> module_manager.cc execute ] Executing module: bpsf (bpsf/xorp_bpsf) >> [ 2009/02/03 16:51:18 INFO xorp_bpsf XrlBpsfTarget ] creating XrlBpsfNode >> [ 2009/02/03 16:51:18 INFO xorp_bpsf XrlBpsfTarget ] Starting up XrlBpsfNode >> [ 2009/02/03 16:51:18 WARNING xorp_rtrmgr:4034 XrlFinderTarget +407 >> ../xrl/targets/finder_base.cc handle_finder_0_2_resolve_xrl ] Handling >> method for finder/0.2/resolve_xrl failed: XrlCmdError 102 Command >> failed Target "socket4" does not exist or is not enabled. > > After you use target name of "fea" this error should go away. > >> [ 2009/02/03 16:51:18 ERROR xorp_bpsf:4035 XrlBpsfTarget +275 >> xrl_bpsf_node.cc bind_cb ] Xrl Error: 201 Resolve failed >> [ 2009/02/03 16:51:20 INFO xorp_rtrmgr:4034 RTRMGR +101 >> module_manager.cc execute ] Executing module: interfaces >> (fea/xorp_fea) >> [ 2009/02/03 16:51:21 INFO xorp_fea MFEA ] MFEA enabled >> [ 2009/02/03 16:51:21 INFO xorp_fea MFEA ] CLI enabled >> [ 2009/02/03 16:51:21 INFO xorp_fea MFEA ] CLI started >> [ 2009/02/03 16:51:21 INFO xorp_fea MFEA ] MFEA enabled >> [ 2009/02/03 16:51:21 INFO xorp_fea MFEA ] CLI enabled >> [ 2009/02/03 16:51:21 INFO xorp_fea MFEA ] CLI started >> [ 2009/02/03 16:51:22 INFO xorp_rtrmgr:4034 RTRMGR +101 >> module_manager.cc execute ] Executing module: firewall (fea/xorp_fea) >> [ 2009/02/03 16:51:26 INFO xorp_rtrmgr:4034 RTRMGR +101 >> module_manager.cc execute ] Executing module: fea (fea/xorp_fea) >> [ 2009/02/03 16:51:32 INFO xorp_rtrmgr:4034 RTRMGR +2233 task.cc >> run_task ] No more tasks to run >> >> >> I'm not sure what you meant before when you said that I should >> register with the FEA to send/receive TCP. Does this mean calling >> something like send_register_class_event_interest? Many thanks for the >> help! > > The registration is done when you send XRLs like tcp_open_and_bind. > > Pavlin > Hmm, when I changed the first parameter to be "fea" I get pretty much the same error, even though xorp_fea seems to startup: [ 2009/02/03 18:29:02 INFO xorp_rtrmgr:8229 RTRMGR +249 master_conf_tree.cc execute ] Changed modules: bpsf, interfaces, firewall, fea [ 2009/02/03 18:29:02 INFO xorp_rtrmgr:8229 RTRMGR +101 module_manager.cc execute ] Executing module: bpsf (bpsf/xorp_bpsf) [ 2009/02/03 18:29:02 INFO xorp_bpsf XrlBpsfTarget ] creating XrlBpsfNode [ 2009/02/03 18:29:02 INFO xorp_bpsf XrlBpsfTarget ] Starting up XrlBpsfNode [ 2009/02/03 18:29:02 WARNING xorp_rtrmgr:8229 XrlFinderTarget +407 ../xrl/targets/finder_base.cc handle_finder_0_2_resolve_xrl ] Handling method for finder/0.2/resolve_xrl failed: XrlCmdError 102 Command failed Target "fea" does not exist or is not enabled. [ 2009/02/03 18:29:02 ERROR xorp_bpsf:8230 XrlBpsfTarget +277 xrl_bpsf_node.cc bind_cb ] Xrl Error: 201 Resolve failed [ 2009/02/03 18:29:04 INFO xorp_rtrmgr:8229 RTRMGR +101 module_manager.cc execute ] Executing module: interfaces (fea/xorp_fea) [ 2009/02/03 18:29:05 INFO xorp_fea MFEA ] MFEA enabled [ 2009/02/03 18:29:05 INFO xorp_fea MFEA ] CLI enabled [ 2009/02/03 18:29:05 INFO xorp_fea MFEA ] CLI started [ 2009/02/03 18:29:05 INFO xorp_fea MFEA ] MFEA enabled [ 2009/02/03 18:29:05 INFO xorp_fea MFEA ] CLI enabled [ 2009/02/03 18:29:05 INFO xorp_fea MFEA ] CLI started [ 2009/02/03 18:29:06 INFO xorp_rtrmgr:8229 RTRMGR +101 module_manager.cc execute ] Executing module: firewall (fea/xorp_fea) [ 2009/02/03 18:29:10 INFO xorp_rtrmgr:8229 RTRMGR +101 module_manager.cc execute ] Executing module: fea (fea/xorp_fea) [ 2009/02/03 18:29:16 INFO xorp_rtrmgr:8229 RTRMGR +2233 task.cc run_task ] No more tasks to run Not sure how to control the order of the process startups, seems the fea is starting after my process. I changed bind_cb to call listen directly. Does it matter that I call send_tcp_open_and_bind and send_tcp_listen on two different instances of XrlSocket4V0p1Client? I tried to declare XrlSocket4V0p1Client in the header and initialize it in the constructor but I got an error: "XrlSocket4V0p1Client does not name a type" Also, I was passing in the instance of the eventloop to the constructor, but I guess I don't need to do this. Do I need to do anything directly with it besides call its run function in my main function? Victor From pavlin at ICSI.Berkeley.EDU Tue Feb 3 11:23:04 2009 From: pavlin at ICSI.Berkeley.EDU (Pavlin Radoslavov) Date: Tue, 03 Feb 2009 11:23:04 -0800 Subject: [Xorp-hackers] Events and sockets in XORP In-Reply-To: <38f1dbe80902031046k6f72eda6w35753354cac4d228@mail.gmail.com> References: <38f1dbe80901300924i20661ac3uf649aa66af8b2267@mail.gmail.com> <200901311258.n0VCwQ9a025468@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902011310k27edf622xae316df6f6f95a16@mail.gmail.com> <200902020951.n129pjUe004725@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902021037t7c85a3aen662fe94727e6a9ad@mail.gmail.com> <200902021948.n12Jm8BQ008341@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902030906q2ef8de48o631f87c9ff1b3012@mail.gmail.com> <200902031745.n13Hjx51005146@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902031046k6f72eda6w35753354cac4d228@mail.gmail.com> Message-ID: <200902031923.n13JN41L018841@fruitcake.ICSI.Berkeley.EDU> Victor Faion wrote: > Hmm, when I changed the first parameter to be "fea" I get pretty much > the same error, even though xorp_fea seems to startup: > > [ 2009/02/03 18:29:02 INFO xorp_rtrmgr:8229 RTRMGR +249 > master_conf_tree.cc execute ] Changed modules: bpsf, interfaces, > firewall, fea > [ 2009/02/03 18:29:02 INFO xorp_rtrmgr:8229 RTRMGR +101 > module_manager.cc execute ] Executing module: bpsf (bpsf/xorp_bpsf) > [ 2009/02/03 18:29:02 INFO xorp_bpsf XrlBpsfTarget ] creating XrlBpsfNode > [ 2009/02/03 18:29:02 INFO xorp_bpsf XrlBpsfTarget ] Starting up XrlBpsfNode > [ 2009/02/03 18:29:02 WARNING xorp_rtrmgr:8229 XrlFinderTarget +407 > ../xrl/targets/finder_base.cc handle_finder_0_2_resolve_xrl ] Handling > method for finder/0.2/resolve_xrl failed: XrlCmdError 102 Command > failed Target "fea" does not exist or is not enabled. > [ 2009/02/03 18:29:02 ERROR xorp_bpsf:8230 XrlBpsfTarget +277 > xrl_bpsf_node.cc bind_cb ] Xrl Error: 201 Resolve failed > [ 2009/02/03 18:29:04 INFO xorp_rtrmgr:8229 RTRMGR +101 > module_manager.cc execute ] Executing module: interfaces > (fea/xorp_fea) > [ 2009/02/03 18:29:05 INFO xorp_fea MFEA ] MFEA enabled > [ 2009/02/03 18:29:05 INFO xorp_fea MFEA ] CLI enabled > [ 2009/02/03 18:29:05 INFO xorp_fea MFEA ] CLI started > [ 2009/02/03 18:29:05 INFO xorp_fea MFEA ] MFEA enabled > [ 2009/02/03 18:29:05 INFO xorp_fea MFEA ] CLI enabled > [ 2009/02/03 18:29:05 INFO xorp_fea MFEA ] CLI started > [ 2009/02/03 18:29:06 INFO xorp_rtrmgr:8229 RTRMGR +101 > module_manager.cc execute ] Executing module: firewall (fea/xorp_fea) > [ 2009/02/03 18:29:10 INFO xorp_rtrmgr:8229 RTRMGR +101 > module_manager.cc execute ] Executing module: fea (fea/xorp_fea) > [ 2009/02/03 18:29:16 INFO xorp_rtrmgr:8229 RTRMGR +2233 task.cc > run_task ] No more tasks to run > > Not sure how to control the order of the process startups, seems the > fea is starting after my process. You must add the following line in your bpfs.tp template file: %modinfo: depends fea; See some of the other protocol templates if in doubt about the details. > I changed bind_cb to call listen directly. Does it matter that I call > send_tcp_open_and_bind and send_tcp_listen on two different instances > of XrlSocket4V0p1Client? I tried to declare XrlSocket4V0p1Client in > the header and initialize it in the constructor but I got an error: > "XrlSocket4V0p1Client does not name a type" No, it shouldn't matter even if you use two different instances. For performance reasons though you might have a single instance in the corresponding class so you can avoid the create/destroy overhead. In the header file for your class you must include the corresponding xrl/interfaces/*.hh header file that declares class XrlSocket4V0p1Client. > Also, I was passing in the instance of the eventloop to the > constructor, but I guess I don't need to do this. Do I need to do > anything directly with it besides call its run function in my main > function? If you don't use the eventloop directly, then you don't need to pass it. If you pass it, make sure you pass it by reference, because the process cannot have more than one eventloop instances. Pavlin From vfaion at gmail.com Tue Feb 3 11:58:30 2009 From: vfaion at gmail.com (Victor Faion) Date: Tue, 3 Feb 2009 19:58:30 +0000 Subject: [Xorp-hackers] Events and sockets in XORP In-Reply-To: <200902031923.n13JN41L018841@fruitcake.ICSI.Berkeley.EDU> References: <38f1dbe80901300924i20661ac3uf649aa66af8b2267@mail.gmail.com> <200901311258.n0VCwQ9a025468@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902011310k27edf622xae316df6f6f95a16@mail.gmail.com> <200902020951.n129pjUe004725@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902021037t7c85a3aen662fe94727e6a9ad@mail.gmail.com> <200902021948.n12Jm8BQ008341@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902030906q2ef8de48o631f87c9ff1b3012@mail.gmail.com> <200902031745.n13Hjx51005146@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902031046k6f72eda6w35753354cac4d228@mail.gmail.com> <200902031923.n13JN41L018841@fruitcake.ICSI.Berkeley.EDU> Message-ID: <38f1dbe80902031158v717a4bf6xafd6f2ca971048fd@mail.gmail.com> On Tue, Feb 3, 2009 at 19:23, Pavlin Radoslavov wrote: > Victor Faion wrote: > >> Hmm, when I changed the first parameter to be "fea" I get pretty much >> the same error, even though xorp_fea seems to startup: >> >> [ 2009/02/03 18:29:02 INFO xorp_rtrmgr:8229 RTRMGR +249 >> master_conf_tree.cc execute ] Changed modules: bpsf, interfaces, >> firewall, fea >> [ 2009/02/03 18:29:02 INFO xorp_rtrmgr:8229 RTRMGR +101 >> module_manager.cc execute ] Executing module: bpsf (bpsf/xorp_bpsf) >> [ 2009/02/03 18:29:02 INFO xorp_bpsf XrlBpsfTarget ] creating XrlBpsfNode >> [ 2009/02/03 18:29:02 INFO xorp_bpsf XrlBpsfTarget ] Starting up XrlBpsfNode >> [ 2009/02/03 18:29:02 WARNING xorp_rtrmgr:8229 XrlFinderTarget +407 >> ../xrl/targets/finder_base.cc handle_finder_0_2_resolve_xrl ] Handling >> method for finder/0.2/resolve_xrl failed: XrlCmdError 102 Command >> failed Target "fea" does not exist or is not enabled. >> [ 2009/02/03 18:29:02 ERROR xorp_bpsf:8230 XrlBpsfTarget +277 >> xrl_bpsf_node.cc bind_cb ] Xrl Error: 201 Resolve failed >> [ 2009/02/03 18:29:04 INFO xorp_rtrmgr:8229 RTRMGR +101 >> module_manager.cc execute ] Executing module: interfaces >> (fea/xorp_fea) >> [ 2009/02/03 18:29:05 INFO xorp_fea MFEA ] MFEA enabled >> [ 2009/02/03 18:29:05 INFO xorp_fea MFEA ] CLI enabled >> [ 2009/02/03 18:29:05 INFO xorp_fea MFEA ] CLI started >> [ 2009/02/03 18:29:05 INFO xorp_fea MFEA ] MFEA enabled >> [ 2009/02/03 18:29:05 INFO xorp_fea MFEA ] CLI enabled >> [ 2009/02/03 18:29:05 INFO xorp_fea MFEA ] CLI started >> [ 2009/02/03 18:29:06 INFO xorp_rtrmgr:8229 RTRMGR +101 >> module_manager.cc execute ] Executing module: firewall (fea/xorp_fea) >> [ 2009/02/03 18:29:10 INFO xorp_rtrmgr:8229 RTRMGR +101 >> module_manager.cc execute ] Executing module: fea (fea/xorp_fea) >> [ 2009/02/03 18:29:16 INFO xorp_rtrmgr:8229 RTRMGR +2233 task.cc >> run_task ] No more tasks to run >> >> Not sure how to control the order of the process startups, seems the >> fea is starting after my process. > > You must add the following line in your bpfs.tp template file: > > %modinfo: depends fea; > > See some of the other protocol templates if in doubt about the > details. > >> I changed bind_cb to call listen directly. Does it matter that I call >> send_tcp_open_and_bind and send_tcp_listen on two different instances >> of XrlSocket4V0p1Client? I tried to declare XrlSocket4V0p1Client in >> the header and initialize it in the constructor but I got an error: >> "XrlSocket4V0p1Client does not name a type" > > No, it shouldn't matter even if you use two different instances. > For performance reasons though you might have a single instance in > the corresponding class so you can avoid the create/destroy > overhead. > In the header file for your class you must include the corresponding > xrl/interfaces/*.hh header file that declares class > XrlSocket4V0p1Client. > >> Also, I was passing in the instance of the eventloop to the >> constructor, but I guess I don't need to do this. Do I need to do >> anything directly with it besides call its run function in my main >> function? > > If you don't use the eventloop directly, then you don't need to pass > it. If you pass it, make sure you pass it by reference, because the > process cannot have more than one eventloop instances. > > Pavlin > Sorry, I forgot about the template file. My little experiment is working, I should start making the protocol now. Many thanks once again! Victor From vfaion at gmail.com Fri Feb 6 15:09:04 2009 From: vfaion at gmail.com (Victor Faion) Date: Fri, 6 Feb 2009 23:09:04 +0000 Subject: [Xorp-hackers] XRL Template Message-ID: <38f1dbe80902061509g5ff87f37g14ef7afdd83559f7@mail.gmail.com> Hello, I was trying to make an XRL that would get called when my XORP process starts which would set all the neighbours of the router. I wanted to be able to list all the neighbours' IP addresses in the XORP configuration file that is read when xorp_rtrmgr starts and have them passed to my process in an XrlAtomList. In my interface file I have this: set_neighbours ? neighbours:list and in my template file I have this: %activate: xrl "$(bpsf.targetname)/bpsf/0.1/set_neighbours?neighbours:list=$(@)"; I generated the functions from the interface and implemented them in my process, but XORP doesn't like the template file (the only thing I changed in it to make it stop working was adding the line above): [ 2009/02/06 22:59:03 ERROR xorp_rtrmgr:8107 RTRMGR +369 main_rtrmgr.cc run ] rtrmgr shutting down due to an init error: PARSE ERROR [Config File /root/project/xorp1.6/install/config.boot, line 54]: syntax error; Last symbol parsed was "neighbours" Is it possible to list the neighbours this way or should I be doing something else? Victor From pavlin at ICSI.Berkeley.EDU Sat Feb 7 21:58:17 2009 From: pavlin at ICSI.Berkeley.EDU (Pavlin Radoslavov) Date: Sat, 07 Feb 2009 21:58:17 -0800 Subject: [Xorp-hackers] XRL Template In-Reply-To: <38f1dbe80902061509g5ff87f37g14ef7afdd83559f7@mail.gmail.com> References: <38f1dbe80902061509g5ff87f37g14ef7afdd83559f7@mail.gmail.com> Message-ID: <200902080558.n185wH6f014398@fruitcake.ICSI.Berkeley.EDU> Victor Faion wrote: > Hello, > > I was trying to make an XRL that would get called when my XORP process > starts which would set all the neighbours of the router. I wanted to > be able to list all the neighbours' IP addresses in the XORP > configuration file that is read when xorp_rtrmgr starts and have them > passed to my process in an XrlAtomList. > > In my interface file I have this: > > set_neighbours ? neighbours:list > > and in my template file I have this: > > %activate: xrl "$(bpsf.targetname)/bpsf/0.1/set_neighbours?neighbours:list=$(@)"; > > I generated the functions from the interface and implemented them in > my process, but XORP doesn't like the template file (the only thing I > changed in it to make it stop working was adding the line above): > > [ 2009/02/06 22:59:03 ERROR xorp_rtrmgr:8107 RTRMGR +369 > main_rtrmgr.cc run ] rtrmgr shutting down due to an init error: PARSE > ERROR [Config File /root/project/xorp1.6/install/config.boot, line > 54]: syntax error; Last symbol parsed was "neighbours" > > Is it possible to list the neighbours this way or should I be doing > something else? I believe you can't use attribute of type "list", because XRL values of type "list" can be encoded/decoded only within C++. One simple workaround that comes to mind is to define "neighbours" of type "txt", and encode/decode the string in the form you like; e.g., names separated by comma. Hope that helps, Pavlin > > Victor > > _______________________________________________ > Xorp-hackers mailing list > Xorp-hackers at icir.org > http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/xorp-hackers From vfaion at gmail.com Sun Feb 8 09:12:44 2009 From: vfaion at gmail.com (Victor Faion) Date: Sun, 8 Feb 2009 17:12:44 +0000 Subject: [Xorp-hackers] XRL Template In-Reply-To: <200902080558.n185wH6f014398@fruitcake.ICSI.Berkeley.EDU> References: <38f1dbe80902061509g5ff87f37g14ef7afdd83559f7@mail.gmail.com> <200902080558.n185wH6f014398@fruitcake.ICSI.Berkeley.EDU> Message-ID: <38f1dbe80902080912l35c62414wf2e5e9e06732fcf0@mail.gmail.com> On Sun, Feb 8, 2009 at 05:58, Pavlin Radoslavov wrote: > Victor Faion wrote: > >> Hello, >> >> I was trying to make an XRL that would get called when my XORP process >> starts which would set all the neighbours of the router. I wanted to >> be able to list all the neighbours' IP addresses in the XORP >> configuration file that is read when xorp_rtrmgr starts and have them >> passed to my process in an XrlAtomList. >> >> In my interface file I have this: >> >> set_neighbours ? neighbours:list >> >> and in my template file I have this: >> >> %activate: xrl "$(bpsf.targetname)/bpsf/0.1/set_neighbours?neighbours:list=$(@)"; >> >> I generated the functions from the interface and implemented them in >> my process, but XORP doesn't like the template file (the only thing I >> changed in it to make it stop working was adding the line above): >> >> [ 2009/02/06 22:59:03 ERROR xorp_rtrmgr:8107 RTRMGR +369 >> main_rtrmgr.cc run ] rtrmgr shutting down due to an init error: PARSE >> ERROR [Config File /root/project/xorp1.6/install/config.boot, line >> 54]: syntax error; Last symbol parsed was "neighbours" >> >> Is it possible to list the neighbours this way or should I be doing >> something else? > > I believe you can't use attribute of type "list", because XRL values > of type "list" can be encoded/decoded only within C++. > One simple workaround that comes to mind is to define "neighbours" > of type "txt", and encode/decode the string in the form you like; > e.g., names separated by comma. > > Hope that helps, > Pavlin > >> >> Victor >> >> _______________________________________________ >> Xorp-hackers mailing list >> Xorp-hackers at icir.org >> http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/xorp-hackers > Thanks for the help, that works for me. I'll parse the string into an XrlAtomList. Victor From vfaion at gmail.com Mon Feb 9 17:34:48 2009 From: vfaion at gmail.com (Victor Faion) Date: Tue, 10 Feb 2009 01:34:48 +0000 Subject: [Xorp-hackers] XRL Timing Message-ID: <38f1dbe80902091734x43e5b7a3xdc4fd81e39197df4@mail.gmail.com> Hello, In my XORP process I have a few parameters that are set in config.boot and these send XRLs to set some fields in my process. These seem to be getting sent when the eventloop's run function is called and I was wondering if/how it's possible to send these XRLs before this? Victor From pavlin at ICSI.Berkeley.EDU Tue Feb 10 09:45:13 2009 From: pavlin at ICSI.Berkeley.EDU (Pavlin Radoslavov) Date: Tue, 10 Feb 2009 09:45:13 -0800 Subject: [Xorp-hackers] XRL Timing In-Reply-To: <38f1dbe80902091734x43e5b7a3xdc4fd81e39197df4@mail.gmail.com> References: <38f1dbe80902091734x43e5b7a3xdc4fd81e39197df4@mail.gmail.com> Message-ID: <200902101745.n1AHjDqI003476@fruitcake.ICSI.Berkeley.EDU> Victor Faion wrote: > Hello, > > In my XORP process I have a few parameters that are set in config.boot > and these send XRLs to set some fields in my process. These seem to be > getting sent when the eventloop's run function is called and I was > wondering if/how it's possible to send these XRLs before this? You can't. Sending an XRL is an event and all events are handled by the eventloop (when its run() function is executed). Regards, Pavlin > Victor > > _______________________________________________ > Xorp-hackers mailing list > Xorp-hackers at icir.org > http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/xorp-hackers From vfaion at gmail.com Tue Feb 10 09:58:18 2009 From: vfaion at gmail.com (Victor Faion) Date: Tue, 10 Feb 2009 17:58:18 +0000 Subject: [Xorp-hackers] XRL Timing In-Reply-To: <200902101745.n1AHjDqI003476@fruitcake.ICSI.Berkeley.EDU> References: <38f1dbe80902091734x43e5b7a3xdc4fd81e39197df4@mail.gmail.com> <200902101745.n1AHjDqI003476@fruitcake.ICSI.Berkeley.EDU> Message-ID: <38f1dbe80902100958h5c46c575ta4b4613dff74c3cb@mail.gmail.com> On Tue, Feb 10, 2009 at 17:45, Pavlin Radoslavov wrote: > Victor Faion wrote: > >> Hello, >> >> In my XORP process I have a few parameters that are set in config.boot >> and these send XRLs to set some fields in my process. These seem to be >> getting sent when the eventloop's run function is called and I was >> wondering if/how it's possible to send these XRLs before this? > > You can't. Sending an XRL is an event and all events are handled by > the eventloop (when its run() function is executed). > > Regards, > Pavlin > >> Victor >> >> _______________________________________________ >> Xorp-hackers mailing list >> Xorp-hackers at icir.org >> http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/xorp-hackers > Is there a way to set the order in which the XRLs called from config.boot are called? I just want to insure some of the state is set before performing further functions. So for example I can have the callback of the last XRL call these functions, but is there a way to guarantee which XRL will return last? Victor From pavlin at ICSI.Berkeley.EDU Tue Feb 10 10:23:52 2009 From: pavlin at ICSI.Berkeley.EDU (Pavlin Radoslavov) Date: Tue, 10 Feb 2009 10:23:52 -0800 Subject: [Xorp-hackers] XRL Timing In-Reply-To: <38f1dbe80902100958h5c46c575ta4b4613dff74c3cb@mail.gmail.com> References: <38f1dbe80902091734x43e5b7a3xdc4fd81e39197df4@mail.gmail.com> <200902101745.n1AHjDqI003476@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902100958h5c46c575ta4b4613dff74c3cb@mail.gmail.com> Message-ID: <200902101823.n1AINqEZ009775@fruitcake.ICSI.Berkeley.EDU> Victor Faion wrote: > On Tue, Feb 10, 2009 at 17:45, Pavlin Radoslavov > wrote: > > Victor Faion wrote: > > > >> Hello, > >> > >> In my XORP process I have a few parameters that are set in config.boot > >> and these send XRLs to set some fields in my process. These seem to be > >> getting sent when the eventloop's run function is called and I was > >> wondering if/how it's possible to send these XRLs before this? > > > > You can't. Sending an XRL is an event and all events are handled by > > the eventloop (when its run() function is executed). > > > > Regards, > > Pavlin > > > >> Victor > >> > >> _______________________________________________ > >> Xorp-hackers mailing list > >> Xorp-hackers at icir.org > >> http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/xorp-hackers > > > > > Is there a way to set the order in which the XRLs called from > config.boot are called? I just want to insure some of the state is set > before performing further functions. So for example I can have the > callback of the last XRL call these functions, but is there a way to > guarantee which XRL will return last? Try to reorder the corresponding blocks in the *.tp template file. Also, try to use %create, %update, %activate as appropriate (see the rtrmgr design document for description). Pavlin From bms at ICSI.Berkeley.EDU Tue Feb 10 10:45:57 2009 From: bms at ICSI.Berkeley.EDU (Bruce M. Simpson) Date: Tue, 10 Feb 2009 18:45:57 +0000 Subject: [Xorp-hackers] XRL Timing In-Reply-To: <38f1dbe80902100958h5c46c575ta4b4613dff74c3cb@mail.gmail.com> References: <38f1dbe80902091734x43e5b7a3xdc4fd81e39197df4@mail.gmail.com> <200902101745.n1AHjDqI003476@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902100958h5c46c575ta4b4613dff74c3cb@mail.gmail.com> Message-ID: <4991CB65.2070507@icsi.berkeley.edu> Victor Faion wrote: > > Is there a way to set the order in which the XRLs called from > config.boot are called? I just want to insure some of the state is set > before performing further functions. So for example I can have the > callback of the last XRL call these functions, but is there a way to > guarantee which XRL will return last? > I can't speak for the config.boot mechanism at the moment in detail. Off the top of my head, the following would explain why we generally implement such config operations from the Router Manager to use single XRLs. If you are implementing such things in your own code, there are things to be aware of. You can't rely on the order of execution of multiple XRLs fired off in the same flow-of-control. XRLs are implemented to be completely asynchronous. The API provides no such guarantee, although you may see effects in implementation where they *are* processed in the order in which you queue them. You can't rely on this behaviour, as the mechanism for delivering the XRL may well change to use "true" asynchronous I/O primitives in future. For example, during the Windows port, we ruled out the use of I/O completion ports as they were too intrusive to the whole XRL event framework, although as AIO matures and evolves within other systems (it still very much has a role and NTOSKRNL.EXE is built on that foundation), that may change. If you need a guarantee of XRLs being processed in a known order in the time domain, then you need to re-enter the EventLoop every time you send the XRL and run that loop to completion. You can do this in-line in the same flow of control, by simply re-entering EventLoop::run() in a while loop until the XRL callback routine is dispatched. It stems from the design trade-off we made in using explicit co-routines rather than threads. In the XORP architecture, the XRLs are effectively the only synchronization point between XORP processes; we rely on the serialization mechanisms inherent in the base operating system. Most of the time, that serialization ends up happening in the host's socket buffers, as the XRL layer will try to use TCP sockets by default as the IPC mechanism. An example of code which sends multiple XRLs in the same flow of control would be RIP's socket initialization. The OLSR implementation did this too, before the semantics of "give me a broadcast-capable IPv4 socket bound to an interface" were pushed into the FEA. Because some of the operations to construct such a socket are mutually dependent, and platform specific, adding a single XRL to the FEA process was more expedient, and avoids the "ping-pong" effect of XRLs being fired between the OLSR and FEA process during OLSR startup, which can be unnecessarily time consuming, as well as difficult to read and debug. If you look at RIP's socket initialization, upon which this part of the OLSR code was based, you will see a "waterfall" style flow of control, where each successive XRL triggers another to be sent. It is tricky to read for folk not familiar with it! If you need to dispatch events of your own whilst XRLs are in flight, without limiting the flow of control to the scope in which you send the XRLs, you may need to construct state machines around those events. [i.e. we didn't roll UML collaboration diagrams for this, we were busy building a protocol stack and all the developers were sharing the same semantic map of how the system worked :-) now that XORP is going out to the wider world, we need to explain why these things exist.] cheers BMS From vfaion at gmail.com Tue Feb 10 11:45:22 2009 From: vfaion at gmail.com (Victor Faion) Date: Tue, 10 Feb 2009 19:45:22 +0000 Subject: [Xorp-hackers] XRL Timing In-Reply-To: <4991CB65.2070507@icsi.berkeley.edu> References: <38f1dbe80902091734x43e5b7a3xdc4fd81e39197df4@mail.gmail.com> <200902101745.n1AHjDqI003476@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902100958h5c46c575ta4b4613dff74c3cb@mail.gmail.com> <4991CB65.2070507@icsi.berkeley.edu> Message-ID: <38f1dbe80902101145p5b407d54p365c21f026677d56@mail.gmail.com> On Tue, Feb 10, 2009 at 18:45, Bruce M. Simpson wrote: > Victor Faion wrote: >> >> Is there a way to set the order in which the XRLs called from >> config.boot are called? I just want to insure some of the state is set >> before performing further functions. So for example I can have the >> callback of the last XRL call these functions, but is there a way to >> guarantee which XRL will return last? >> > > I can't speak for the config.boot mechanism at the moment in detail. > > Off the top of my head, the following would explain why we generally > implement such config operations from the Router Manager to use single XRLs. > If you are implementing such things in your own code, there are things to > be aware of. > > You can't rely on the order of execution of multiple XRLs fired off in the > same flow-of-control. XRLs are implemented to be completely asynchronous. > The API provides no such guarantee, although you may see effects in > implementation where they *are* processed in the order in which you queue > them. > > You can't rely on this behaviour, as the mechanism for delivering the XRL > may well change to use "true" asynchronous I/O primitives in future. > For example, during the Windows port, we ruled out the use of I/O > completion ports as they were too intrusive to the whole XRL event > framework, although as AIO matures and evolves within other systems (it > still very much has a role and NTOSKRNL.EXE is built on that foundation), > that may change. > > If you need a guarantee of XRLs being processed in a known order in the > time domain, then you need to re-enter the EventLoop every time you send the > XRL and run that loop to completion. > You can do this in-line in the same flow of control, by simply re-entering > EventLoop::run() in a while loop until the XRL callback routine is > dispatched. > > It stems from the design trade-off we made in using explicit co-routines > rather than threads. > In the XORP architecture, the XRLs are effectively the only > synchronization point between XORP processes; we rely on the serialization > mechanisms inherent in the base operating system. > Most of the time, that serialization ends up happening in the host's > socket buffers, as the XRL layer will try to use TCP sockets by default as > the IPC mechanism. > > An example of code which sends multiple XRLs in the same flow of control > would be RIP's socket initialization. > The OLSR implementation did this too, before the semantics of "give me a > broadcast-capable IPv4 socket bound to an interface" were pushed into the > FEA. > > Because some of the operations to construct such a socket are mutually > dependent, and platform specific, adding a single XRL to the FEA process was > more expedient, and avoids the "ping-pong" effect of XRLs being fired > between the OLSR and FEA process during OLSR startup, which can be > unnecessarily time consuming, as well as difficult to read and debug. > > If you look at RIP's socket initialization, upon which this part of the > OLSR code was based, you will see a "waterfall" style flow of control, where > each successive XRL triggers another to be sent. > It is tricky to read for folk not familiar with it! > > If you need to dispatch events of your own whilst XRLs are in flight, > without limiting the flow of control to the scope in which you send the > XRLs, you may need to construct state machines around those events. > > [i.e. we didn't roll UML collaboration diagrams for this, we were busy > building a protocol stack and all the developers were sharing the same > semantic map of how the system worked :-) now that XORP is going out to the > wider world, we need to explain why these things exist.] > > cheers > BMS > Thank you for the explanation, I've looked at the chain of events in the startup_socket() function in the RIP implementation. I need to do something similar but simpler. I tried changing the order in the template file but this didn't have an effect on the order of the XRL calls. I will make the state one big string and then use split to parse out the various bits. Once they're all set the callback will call the functions that use them. I think this is the simplest and safest way. Cheers, Victor From vfaion at gmail.com Wed Feb 11 12:37:56 2009 From: vfaion at gmail.com (Victor Faion) Date: Wed, 11 Feb 2009 20:37:56 +0000 Subject: [Xorp-hackers] Socket polling Message-ID: <38f1dbe80902111237u32ca2f99wc32ad2e5e8be779a@mail.gmail.com> Hello, I was trying to setup a process that tries connect to its neighbours over TCP and basically I wanted it to keep trying to connect to its neighbours until it can, but I was having some trouble as the process basically stops trying to connect when it can't connect the first time. I iterate over all the neighbour objects calling their connect function which calls send_tcp_open_bind_connect. The callback given to send_tcp_open_bind_connect just checks if there was an error and if there was it calls connectRetry() which pretty much does the same thing as connect (calls send_tcp_open_bind_connect and passes it the same callback as connect). The problem is the first time when it calls connect and fails, it just calls the socket4_user_0_1_error_event function (saying ``Transport endpoint is not connected'' which is expected) but then it doesn't go back into connectRetry() and no connection is made when its neighbours are actually listening for this connection. Is there a better/easier way of doing this polling or am I just doing the recursing with the callback the wrong way? Thanks, Victor From pavlin at ICSI.Berkeley.EDU Thu Feb 12 10:55:15 2009 From: pavlin at ICSI.Berkeley.EDU (Pavlin Radoslavov) Date: Thu, 12 Feb 2009 10:55:15 -0800 Subject: [Xorp-hackers] Socket polling In-Reply-To: <38f1dbe80902111237u32ca2f99wc32ad2e5e8be779a@mail.gmail.com> References: <38f1dbe80902111237u32ca2f99wc32ad2e5e8be779a@mail.gmail.com> Message-ID: <200902121855.n1CItFLU017089@fruitcake.ICSI.Berkeley.EDU> Victor Faion wrote: > Hello, > > I was trying to setup a process that tries connect to its neighbours > over TCP and basically I wanted it to keep trying to connect to its > neighbours until it can, but I was having some trouble as the process > basically stops trying to connect when it can't connect the first > time. > > I iterate over all the neighbour objects calling their connect > function which calls send_tcp_open_bind_connect. The callback given to > send_tcp_open_bind_connect just checks if there was an error and if > there was it calls connectRetry() which pretty much does the same > thing as connect (calls send_tcp_open_bind_connect and passes it the > same callback as connect). The problem is the first time when it calls > connect and fails, it just calls the socket4_user_0_1_error_event > function (saying ``Transport endpoint is not connected'' which is > expected) but then it doesn't go back into connectRetry() and no > connection is made when its neighbours are actually listening for this > connection. Is there a better/easier way of doing this polling or am I > just doing the recursing with the callback the wrong way? Is connectRetry() a method in your protocol? In your event handler for socket4_user_0_1_error_event you need to handle the error conditions (e.g., schedule a call to connectRetry()). Also, are you saying that the first time you call send_tcp_open_bind_connect() and it fails, the callback for that XRL is not called at all? I would guess the callback might be called after socket4_user_0_1_error_event is received, but I wouldn't bet on the ordering. Pavlin From vfaion at gmail.com Fri Feb 13 08:28:09 2009 From: vfaion at gmail.com (Victor Faion) Date: Fri, 13 Feb 2009 16:28:09 +0000 Subject: [Xorp-hackers] Socket polling In-Reply-To: <200902121855.n1CItFLU017089@fruitcake.ICSI.Berkeley.EDU> References: <38f1dbe80902111237u32ca2f99wc32ad2e5e8be779a@mail.gmail.com> <200902121855.n1CItFLU017089@fruitcake.ICSI.Berkeley.EDU> Message-ID: <38f1dbe80902130828u7b56a096sba44892a79aeec4e@mail.gmail.com> On Thu, Feb 12, 2009 at 18:55, Pavlin Radoslavov wrote: > Victor Faion wrote: > >> Hello, >> >> I was trying to setup a process that tries connect to its neighbours >> over TCP and basically I wanted it to keep trying to connect to its >> neighbours until it can, but I was having some trouble as the process >> basically stops trying to connect when it can't connect the first >> time. >> >> I iterate over all the neighbour objects calling their connect >> function which calls send_tcp_open_bind_connect. The callback given to >> send_tcp_open_bind_connect just checks if there was an error and if >> there was it calls connectRetry() which pretty much does the same >> thing as connect (calls send_tcp_open_bind_connect and passes it the >> same callback as connect). The problem is the first time when it calls >> connect and fails, it just calls the socket4_user_0_1_error_event >> function (saying ``Transport endpoint is not connected'' which is >> expected) but then it doesn't go back into connectRetry() and no >> connection is made when its neighbours are actually listening for this >> connection. Is there a better/easier way of doing this polling or am I >> just doing the recursing with the callback the wrong way? > > Is connectRetry() a method in your protocol? > Yeah, connect() takes in the parameters needed to call send_tcp_open_bind_connect() and saves them into the Neighbour object. Then connectRetry() uses the cached values to call send_tcp_open_bind_connect() if it fails the first time. > In your event handler for socket4_user_0_1_error_event you need to > handle the error conditions (e.g., schedule a call to > connectRetry()). > I tried to avoid this as this means iterating over all the neighbours again, checking each sockid and matching against the sockid received in socket4_user_0_1_error_event to figure out which neighbour's connect function to call again. Anyway I tried doing it like this but it still doesn't repeatedly try to connect to a neighbour. It goes in this order: 1. Try to connect normally using the neighbour's conect() (shouldn't be able to) 2. Callback for send_tcp_open_bind_connect gets called (and the XrlError object received is XrlError::OKAY() for some reason) 3. socketx_user_0_1_error_event gets called and says ``Transport endpoint is not connected fatal'' 4. Then socketx_user_0_1_error_event iterates over the neighbours, when it matches the one which has the sockid that socketx_user_0_1_error_event received it calls connect() again. 5. Then I get a warning that says ``Handling method for socket4_user/0.1/error_event failed: XrlCmdError 102 Command failed socket error'' 6. Then the same thing as step 2 happens. The cycle ends there, connect() only gets called twice because socketx_user_0_1_error_event only gets called once. Not sure why this happens, something to do with that warning. Why does that happen though? > Also, are you saying that the first time you call > send_tcp_open_bind_connect() and it fails, the callback for that XRL > is not called at all? I would guess the callback might be called > after socket4_user_0_1_error_event is received, but I wouldn't bet > on the ordering. > > Pavlin > Well the callback gets called but the problem is that I'm not sure which of the callback and the error event handler get called last in order to reschedule the connecting. Victor From vfaion at gmail.com Fri Feb 13 11:56:16 2009 From: vfaion at gmail.com (Victor Faion) Date: Fri, 13 Feb 2009 19:56:16 +0000 Subject: [Xorp-hackers] Socket polling In-Reply-To: <38f1dbe80902130828u7b56a096sba44892a79aeec4e@mail.gmail.com> References: <38f1dbe80902111237u32ca2f99wc32ad2e5e8be779a@mail.gmail.com> <200902121855.n1CItFLU017089@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902130828u7b56a096sba44892a79aeec4e@mail.gmail.com> Message-ID: <38f1dbe80902131156l69d6c683nbf415b838563fef5@mail.gmail.com> On Fri, Feb 13, 2009 at 16:28, Victor Faion wrote: > On Thu, Feb 12, 2009 at 18:55, Pavlin Radoslavov > wrote: >> Victor Faion wrote: >> >>> Hello, >>> >>> I was trying to setup a process that tries connect to its neighbours >>> over TCP and basically I wanted it to keep trying to connect to its >>> neighbours until it can, but I was having some trouble as the process >>> basically stops trying to connect when it can't connect the first >>> time. >>> >>> I iterate over all the neighbour objects calling their connect >>> function which calls send_tcp_open_bind_connect. The callback given to >>> send_tcp_open_bind_connect just checks if there was an error and if >>> there was it calls connectRetry() which pretty much does the same >>> thing as connect (calls send_tcp_open_bind_connect and passes it the >>> same callback as connect). The problem is the first time when it calls >>> connect and fails, it just calls the socket4_user_0_1_error_event >>> function (saying ``Transport endpoint is not connected'' which is >>> expected) but then it doesn't go back into connectRetry() and no >>> connection is made when its neighbours are actually listening for this >>> connection. Is there a better/easier way of doing this polling or am I >>> just doing the recursing with the callback the wrong way? >> >> Is connectRetry() a method in your protocol? >> > > > Yeah, connect() takes in the parameters needed to call > send_tcp_open_bind_connect() and saves them into the Neighbour object. > Then connectRetry() uses the cached values to call > send_tcp_open_bind_connect() if it fails the first time. > > >> In your event handler for socket4_user_0_1_error_event you need to >> handle the error conditions (e.g., schedule a call to >> connectRetry()). >> > > > I tried to avoid this as this means iterating over all the neighbours > again, checking each sockid and matching against the sockid received > in socket4_user_0_1_error_event to figure out which neighbour's > connect function to call again. Anyway I tried doing it like this but > it still doesn't repeatedly try to connect to a neighbour. It goes in > this order: > > 1. Try to connect normally using the neighbour's conect() (shouldn't be able to) > > 2. Callback for send_tcp_open_bind_connect gets called (and the > XrlError object received is XrlError::OKAY() for some reason) > > 3. socketx_user_0_1_error_event gets called and says ``Transport > endpoint is not connected fatal'' > > 4. Then socketx_user_0_1_error_event iterates over the neighbours, > when it matches the one which has the sockid that > socketx_user_0_1_error_event received it calls connect() again. > > 5. Then I get a warning that says ``Handling method for > socket4_user/0.1/error_event failed: XrlCmdError 102 Command failed > socket error'' > > 6. Then the same thing as step 2 happens. > > The cycle ends there, connect() only gets called twice because > socketx_user_0_1_error_event only gets called once. Not sure why this > happens, something to do with that warning. Why does that happen > though? > > >> Also, are you saying that the first time you call >> send_tcp_open_bind_connect() and it fails, the callback for that XRL >> is not called at all? I would guess the callback might be called >> after socket4_user_0_1_error_event is received, but I wouldn't bet >> on the ordering. >> >> Pavlin >> > > > Well the callback gets called but the problem is that I'm not sure > which of the callback and the error event handler get called last in > order to reschedule the connecting. > > Victor > Sorry the reason for step 5 above was because my socket4_user_0_1_error_event was returning XrlCmdError::COMMAND_FAILED("socket error"). However when I changed it to return XrlCmdError::OKAY() basically it goes through steps 1-4 from above except sometimes, it doesn't happen in the order above but in the order 1, 3, 4, 2. When this happens it ends in step 2 and a connection is not made. This happens because the callback sets the sockid of the neighbour when a connection attempt is made, and the error handler uses this sockid to know which neighbour to connect to. So when the new sockid doesn't get set, the error handler doesn't find the neighbour. Not sure how to get the new sockid into the event handler when it doesn't get set into the callback. From illidan at lineway.net Mon Feb 16 04:34:34 2009 From: illidan at lineway.net (illidan) Date: Mon, 16 Feb 2009 13:34:34 +0100 Subject: [Xorp-hackers] Socket error Message-ID: <49995D5A.3020003@lineway.net> Hello, I was trying to open a socket using socket4 library. I used function send_tcp_open_and_bind : create_socket.cc : void SocketServer::get_create_socket() { XorpCallback2::RefPtr cb; IPv4 localIP("10.10.10.10"); int localPort = 100; cb = callback(this,&SocketServer::get_socket_id); send_tcp_open_and_bind("fea",_rtr.instance_name(),localIP,localPort,cb); } void SocketServer::get_socket_id(const XrlError& e,const string* id) { if(e==XrlCmdError::OKAY()) { fprintf(stderr,"I receive the response : %s\n",id->c_str()); _socket_id = id->c_str(); listen(); return; } } When I run this program, I receive correctly the socket_id, but I get an error in rtrmgr process : "[ 2009/02/16 13:11:01 WARNING xorp_rtrmgr:32679 XrlFinderTarget +721 ../xrl/targets/finder_base.cc handle_finder_event_notifier_0_1_register_instance_event_interest ] Handling method for finder_event_notifier/0.1/register_instance_event_interest failed: XrlCmdError 102 Command failed failed to add watch [ 2009/02/16 13:11:01 ERROR xorp_fea:32681 FEA +128 xrl_fea_io.cc register_instance_event_interest_cb ] Failed to register event interest in instance create_socket: 102 Command failed failed to add watch" What could be the problem? Did I do something wrong?? Thanks Michael From vfaion at gmail.com Mon Feb 16 10:55:20 2009 From: vfaion at gmail.com (Victor Faion) Date: Mon, 16 Feb 2009 18:55:20 +0000 Subject: [Xorp-hackers] Socket polling In-Reply-To: <38f1dbe80902131156l69d6c683nbf415b838563fef5@mail.gmail.com> References: <38f1dbe80902111237u32ca2f99wc32ad2e5e8be779a@mail.gmail.com> <200902121855.n1CItFLU017089@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902130828u7b56a096sba44892a79aeec4e@mail.gmail.com> <38f1dbe80902131156l69d6c683nbf415b838563fef5@mail.gmail.com> Message-ID: <38f1dbe80902161055r7aa33cabm14d73d5a1356c5e0@mail.gmail.com> On Fri, Feb 13, 2009 at 19:56, Victor Faion wrote: > On Fri, Feb 13, 2009 at 16:28, Victor Faion wrote: >> On Thu, Feb 12, 2009 at 18:55, Pavlin Radoslavov >> wrote: >>> Victor Faion wrote: >>> >>>> Hello, >>>> >>>> I was trying to setup a process that tries connect to its neighbours >>>> over TCP and basically I wanted it to keep trying to connect to its >>>> neighbours until it can, but I was having some trouble as the process >>>> basically stops trying to connect when it can't connect the first >>>> time. >>>> >>>> I iterate over all the neighbour objects calling their connect >>>> function which calls send_tcp_open_bind_connect. The callback given to >>>> send_tcp_open_bind_connect just checks if there was an error and if >>>> there was it calls connectRetry() which pretty much does the same >>>> thing as connect (calls send_tcp_open_bind_connect and passes it the >>>> same callback as connect). The problem is the first time when it calls >>>> connect and fails, it just calls the socket4_user_0_1_error_event >>>> function (saying ``Transport endpoint is not connected'' which is >>>> expected) but then it doesn't go back into connectRetry() and no >>>> connection is made when its neighbours are actually listening for this >>>> connection. Is there a better/easier way of doing this polling or am I >>>> just doing the recursing with the callback the wrong way? >>> >>> Is connectRetry() a method in your protocol? >>> >> >> >> Yeah, connect() takes in the parameters needed to call >> send_tcp_open_bind_connect() and saves them into the Neighbour object. >> Then connectRetry() uses the cached values to call >> send_tcp_open_bind_connect() if it fails the first time. >> >> >>> In your event handler for socket4_user_0_1_error_event you need to >>> handle the error conditions (e.g., schedule a call to >>> connectRetry()). >>> >> >> >> I tried to avoid this as this means iterating over all the neighbours >> again, checking each sockid and matching against the sockid received >> in socket4_user_0_1_error_event to figure out which neighbour's >> connect function to call again. Anyway I tried doing it like this but >> it still doesn't repeatedly try to connect to a neighbour. It goes in >> this order: >> >> 1. Try to connect normally using the neighbour's conect() (shouldn't be able to) >> >> 2. Callback for send_tcp_open_bind_connect gets called (and the >> XrlError object received is XrlError::OKAY() for some reason) >> >> 3. socketx_user_0_1_error_event gets called and says ``Transport >> endpoint is not connected fatal'' >> >> 4. Then socketx_user_0_1_error_event iterates over the neighbours, >> when it matches the one which has the sockid that >> socketx_user_0_1_error_event received it calls connect() again. >> >> 5. Then I get a warning that says ``Handling method for >> socket4_user/0.1/error_event failed: XrlCmdError 102 Command failed >> socket error'' >> >> 6. Then the same thing as step 2 happens. >> >> The cycle ends there, connect() only gets called twice because >> socketx_user_0_1_error_event only gets called once. Not sure why this >> happens, something to do with that warning. Why does that happen >> though? >> >> >>> Also, are you saying that the first time you call >>> send_tcp_open_bind_connect() and it fails, the callback for that XRL >>> is not called at all? I would guess the callback might be called >>> after socket4_user_0_1_error_event is received, but I wouldn't bet >>> on the ordering. >>> >>> Pavlin >>> >> >> >> Well the callback gets called but the problem is that I'm not sure >> which of the callback and the error event handler get called last in >> order to reschedule the connecting. >> >> Victor >> > > > Sorry the reason for step 5 above was because my > socket4_user_0_1_error_event was returning > XrlCmdError::COMMAND_FAILED("socket error"). However when I changed it > to return XrlCmdError::OKAY() basically it goes through steps 1-4 from > above except sometimes, it doesn't happen in the order above but in > the order 1, 3, 4, 2. When this happens it ends in step 2 and a > connection is not made. This happens because the callback sets the > sockid of the neighbour when a connection attempt is made, and the > error handler uses this sockid to know which neighbour to connect to. > So when the new sockid doesn't get set, the error handler doesn't find > the neighbour. Not sure how to get the new sockid into the event > handler when it doesn't get set into the callback. > Hello, Sorry to restart this thread, I'm not sure how to handle the case when a router cannot connect to another router. I don't understand why when I call send_tcp_open_bind_connect to another router (which isn't even online) the callback to send_tcp_open_bind_connect receives XrlError::OKAY(). I wanted to handle this error in the callback as I don't have enough information to handle it in the socket4_user_0_1_error_event function. I couldn't find any code in XORP that does this sort of thing. Where do the errors that get passed into the callback for send_tcp_open_bind_connect get set? Victor From pavlin at ICSI.Berkeley.EDU Mon Feb 16 11:12:51 2009 From: pavlin at ICSI.Berkeley.EDU (Pavlin Radoslavov) Date: Mon, 16 Feb 2009 11:12:51 -0800 Subject: [Xorp-hackers] Socket polling In-Reply-To: <38f1dbe80902161055r7aa33cabm14d73d5a1356c5e0@mail.gmail.com> References: <38f1dbe80902111237u32ca2f99wc32ad2e5e8be779a@mail.gmail.com> <200902121855.n1CItFLU017089@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902130828u7b56a096sba44892a79aeec4e@mail.gmail.com> <38f1dbe80902131156l69d6c683nbf415b838563fef5@mail.gmail.com> <38f1dbe80902161055r7aa33cabm14d73d5a1356c5e0@mail.gmail.com> Message-ID: <200902161912.n1GJCpJ1011427@fruitcake.ICSI.Berkeley.EDU> Victor Faion wrote: > On Fri, Feb 13, 2009 at 19:56, Victor Faion wrote: > > On Fri, Feb 13, 2009 at 16:28, Victor Faion wrote: > >> On Thu, Feb 12, 2009 at 18:55, Pavlin Radoslavov > >> wrote: > >>> Victor Faion wrote: > >>> > >>>> Hello, > >>>> > >>>> I was trying to setup a process that tries connect to its neighbours > >>>> over TCP and basically I wanted it to keep trying to connect to its > >>>> neighbours until it can, but I was having some trouble as the process > >>>> basically stops trying to connect when it can't connect the first > >>>> time. > >>>> > >>>> I iterate over all the neighbour objects calling their connect > >>>> function which calls send_tcp_open_bind_connect. The callback given to > >>>> send_tcp_open_bind_connect just checks if there was an error and if > >>>> there was it calls connectRetry() which pretty much does the same > >>>> thing as connect (calls send_tcp_open_bind_connect and passes it the > >>>> same callback as connect). The problem is the first time when it calls > >>>> connect and fails, it just calls the socket4_user_0_1_error_event > >>>> function (saying ``Transport endpoint is not connected'' which is > >>>> expected) but then it doesn't go back into connectRetry() and no > >>>> connection is made when its neighbours are actually listening for this > >>>> connection. Is there a better/easier way of doing this polling or am I > >>>> just doing the recursing with the callback the wrong way? > >>> > >>> Is connectRetry() a method in your protocol? > >>> > >> > >> > >> Yeah, connect() takes in the parameters needed to call > >> send_tcp_open_bind_connect() and saves them into the Neighbour object. > >> Then connectRetry() uses the cached values to call > >> send_tcp_open_bind_connect() if it fails the first time. > >> > >> > >>> In your event handler for socket4_user_0_1_error_event you need to > >>> handle the error conditions (e.g., schedule a call to > >>> connectRetry()). > >>> > >> > >> > >> I tried to avoid this as this means iterating over all the neighbours > >> again, checking each sockid and matching against the sockid received > >> in socket4_user_0_1_error_event to figure out which neighbour's > >> connect function to call again. Anyway I tried doing it like this but > >> it still doesn't repeatedly try to connect to a neighbour. It goes in > >> this order: > >> > >> 1. Try to connect normally using the neighbour's conect() (shouldn't be able to) > >> > >> 2. Callback for send_tcp_open_bind_connect gets called (and the > >> XrlError object received is XrlError::OKAY() for some reason) > >> > >> 3. socketx_user_0_1_error_event gets called and says ``Transport > >> endpoint is not connected fatal'' > >> > >> 4. Then socketx_user_0_1_error_event iterates over the neighbours, > >> when it matches the one which has the sockid that > >> socketx_user_0_1_error_event received it calls connect() again. > >> > >> 5. Then I get a warning that says ``Handling method for > >> socket4_user/0.1/error_event failed: XrlCmdError 102 Command failed > >> socket error'' > >> > >> 6. Then the same thing as step 2 happens. > >> > >> The cycle ends there, connect() only gets called twice because > >> socketx_user_0_1_error_event only gets called once. Not sure why this > >> happens, something to do with that warning. Why does that happen > >> though? > >> > >> > >>> Also, are you saying that the first time you call > >>> send_tcp_open_bind_connect() and it fails, the callback for that XRL > >>> is not called at all? I would guess the callback might be called > >>> after socket4_user_0_1_error_event is received, but I wouldn't bet > >>> on the ordering. > >>> > >>> Pavlin > >>> > >> > >> > >> Well the callback gets called but the problem is that I'm not sure > >> which of the callback and the error event handler get called last in > >> order to reschedule the connecting. > >> > >> Victor > >> > > > > > > Sorry the reason for step 5 above was because my > > socket4_user_0_1_error_event was returning > > XrlCmdError::COMMAND_FAILED("socket error"). However when I changed it > > to return XrlCmdError::OKAY() basically it goes through steps 1-4 from > > above except sometimes, it doesn't happen in the order above but in > > the order 1, 3, 4, 2. When this happens it ends in step 2 and a > > connection is not made. This happens because the callback sets the > > sockid of the neighbour when a connection attempt is made, and the > > error handler uses this sockid to know which neighbour to connect to. > > So when the new sockid doesn't get set, the error handler doesn't find > > the neighbour. Not sure how to get the new sockid into the event > > handler when it doesn't get set into the callback. > > > > > Hello, > > Sorry to restart this thread, I'm not sure how to handle the case when > a router cannot connect to another router. I don't understand why when > I call send_tcp_open_bind_connect to another router (which isn't even > online) the callback to send_tcp_open_bind_connect receives > XrlError::OKAY(). I wanted to handle this error in the callback as I > don't have enough information to handle it in the > socket4_user_0_1_error_event function. I couldn't find any code in > XORP that does this sort of thing. Where do the errors that get passed > into the callback for send_tcp_open_bind_connect get set? For a reason that is unclear to me without further investigation, the order of the send_tcp_open_bind_connect callback and the socket4_user_0_1_error_event upcall are reversed (always/occasionally?). I had a quick look in the FEA, and the callback should be received first, but obviously from your description this doesn't seem to be the case. The correct solution should be to investigate the issue and fix it. This might require understanding of the FEA I/O internals and some XRL-related knowledge. Unfortunately, I can't give you an estimate how soon I/we can allocate the resources to fix that, so your best bet would be to submit a Bugzilla entry. For your own purpose you need to move forward by using some workaround. One possible solution that comes to mind is to have a map of states per sockid that can be populated/updated regardless of the order of the callbacks and the upcalls. E.g., if an upcall is received before the sockid is known, a new entry is created for that sockid and the state is set according to the upcall error. Then, after the send_tcp_open_bind_connect callback is invoked, at that time the sockid entry can be used for its intended purpose (and the error condition is already filled-in). On the other hand, if the upcall is inbound_connect_event or outbound_connect_event (instead of error_event), then only after the send_tcp_open_bind_connect callback is called, then you take the appropriate actions. Hope that helps, Pavlin From pavlin at ICSI.Berkeley.EDU Mon Feb 16 11:24:26 2009 From: pavlin at ICSI.Berkeley.EDU (Pavlin Radoslavov) Date: Mon, 16 Feb 2009 11:24:26 -0800 Subject: [Xorp-hackers] Socket error In-Reply-To: <49995D5A.3020003@lineway.net> References: <49995D5A.3020003@lineway.net> Message-ID: <200902161924.n1GJOQvX012498@fruitcake.ICSI.Berkeley.EDU> illidan wrote: > Hello, > > I was trying to open a socket using socket4 library. > I used function send_tcp_open_and_bind : > > create_socket.cc : > void SocketServer::get_create_socket() { > XorpCallback2::RefPtr cb; > IPv4 localIP("10.10.10.10"); > int localPort = 100; > cb = callback(this,&SocketServer::get_socket_id); > send_tcp_open_and_bind("fea",_rtr.instance_name(),localIP,localPort,cb); > } > void SocketServer::get_socket_id(const XrlError& e,const string* id) { > if(e==XrlCmdError::OKAY()) { > fprintf(stderr,"I receive the response : %s\n",id->c_str()); > _socket_id = id->c_str(); > listen(); > return; > } > } > > When I run this program, I receive correctly the socket_id, but I get an > error in rtrmgr process : > > "[ 2009/02/16 13:11:01 WARNING xorp_rtrmgr:32679 XrlFinderTarget +721 > ../xrl/targets/finder_base.cc > handle_finder_event_notifier_0_1_register_instance_event_interest ] > Handling method for > finder_event_notifier/0.1/register_instance_event_interest failed: > XrlCmdError 102 Command failed failed to add watch > [ 2009/02/16 13:11:01 ERROR xorp_fea:32681 FEA +128 xrl_fea_io.cc > register_instance_event_interest_cb ] Failed to register event interest > in instance create_socket: 102 Command failed failed to add watch" > > What could be the problem? Did I do something wrong?? Was your create_socket program still running, and in READY state? You can verify both by using the following XRL by hand (you need to replace "fea" with the target name of your module): libxipc/call_xrl finder://fea/common/0.1/get_status If everything is normal you should see the following output: status:u32=3&reason:txt= FYI, the values for the static codes are listed in libxorp/status_codes.h and the value for PROC_READY is 3. Regards, Pavlin > Thanks > > Michael > > _______________________________________________ > Xorp-hackers mailing list > Xorp-hackers at icir.org > http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/xorp-hackers From illidan at lineway.net Mon Feb 16 14:08:31 2009 From: illidan at lineway.net (illidan) Date: Mon, 16 Feb 2009 23:08:31 +0100 Subject: [Xorp-hackers] Socket error Message-ID: <4999E3DF.6010906@lineway.net> Pavlin Radoslavov wrote: > illidan wrote: > > >> Hello, >> >> I was trying to open a socket using socket4 library. >> I used function send_tcp_open_and_bind : >> >> create_socket.cc : >> void SocketServer::get_create_socket() { >> XorpCallback2::RefPtr cb; >> IPv4 localIP("10.10.10.10"); >> int localPort = 100; >> cb = callback(this,&SocketServer::get_socket_id); >> >> send_tcp_open_and_bind("fea",_rtr.instance_name(),localIP,localPort,cb); >> } >> void SocketServer::get_socket_id(const XrlError& e,const string* id) { >> if(e==XrlCmdError::OKAY()) { >> fprintf(stderr,"I receive the response : %s\n",id->c_str()); >> _socket_id = id->c_str(); >> listen(); >> return; >> } >> } >> >> When I run this program, I receive correctly the socket_id, but I get >> an error in rtrmgr process : >> >> "[ 2009/02/16 13:11:01 WARNING xorp_rtrmgr:32679 XrlFinderTarget +721 >> ../xrl/targets/finder_base.cc >> handle_finder_event_notifier_0_1_register_instance_event_interest ] >> Handling method for >> finder_event_notifier/0.1/register_instance_event_interest failed: >> XrlCmdError 102 Command failed failed to add watch >> [ 2009/02/16 13:11:01 ERROR xorp_fea:32681 FEA +128 xrl_fea_io.cc >> register_instance_event_interest_cb ] Failed to register event >> interest in instance create_socket: 102 Command failed failed to add >> watch" >> >> What could be the problem? Did I do something wrong?? >> > > Was your create_socket program still running, and in READY state? > > You can verify both by using the following XRL by hand (you need to > replace "fea" with the target name of your module): > libxipc/call_xrl finder://fea/common/0.1/get_status > > If everything is normal you should see the following output: > status:u32=3&reason:txt= > In fact, create_socket was not a process but a tool. I did it like bgp/tools/xorpsh_print_peers. I have my own process (call consensus), but I don't really know when to start the tcp socket. So I did this tool to try to open a socket (like a tester). I just try to create my socket in consensus XrlCmdError ConsensusTarget::consensus_0_1_add_ip(const string& ip) { _ip = ip; // I try to create my socket XLOG_INFO("%s\n", "Starting up CONSENSUS"); SocketServer socket(_rtr,_eventloop); socket.get_create_socket(); return XrlCmdError::OKAY(); } I run rtrmgr with the config file "static.boot and I add a consensus IP with CLI. When I add the IP and "commit" it makes an error and kill my process : Starting consensus protocol [ 2009/02/16 23:00:34 TRACE xorp_rtrmgr RTRMGR ] Validating with XRL: >finder://consensus/common/0.1/get_status< [ 2009/02/16 23:00:34 TRACE xorp_rtrmgr RTRMGR ] Expanding xrl $(consensus.targetname)/consensus/0.1/add_ip?ip:txt=$(@) [ 2009/02/16 23:00:34 TRACE xorp_rtrmgr RTRMGR ] Executing XRL: >finder://consensus/consensus/0.1/add_ip?ip:txt=10.10.10.1< [ 2009/02/16 23:00:34 INFO xorp_consensus CONSENSUS ] Starting up CONSENSUS [ 2009/02/16 23:00:34 INFO xorp_consensus CONSENSUS ] Starting up CONSENSUS [ 2009/02/16 23:00:34 TRACE xorp_rtrmgr RTRMGR ] Validating with XRL: >finder://consensus/common/0.1/get_status< [ 2009/02/16 23:00:34 INFO xorp_rtrmgr:13806 RTRMGR +2233 task.cc run_task ] No more tasks to run [ 2009/02/16 23:00:34 TRACE xorp_rtrmgr RTRMGR ] apply_config_change_done: status: 1 response: target: xorpsh-13811-my_computer [ 2009/02/16 23:00:34 ERROR xorp_rtrmgr:13806 RTRMGR +754 module_manager.cc done_cb ] Command "path_to_xorp/consensus/xorp_consensus": terminated with signal 11. [ 2009/02/16 23:00:34 INFO xorp_rtrmgr:13806 RTRMGR +299 module_manager.cc module_exited ] Module abnormally killed: consensus And apparently the process has not been started : #./call_xrl finder://consensus/common/0.1/get_status [ 2009/02/16 23:03:05 ERROR call_xrl:13896 XRL +57 call_xrl.cc response_handler ] Failed. Reason: 201 Resolve failed ("finder://consensus/common/0.1/get_status") [ 2009/02/16 23:03:06 WARNING call_xrl XRL ] request: finder://consensus/common/0.1/get_status resolve failed [ 2009/02/16 23:03:06 WARNING call_xrl XRL ] request: finder://consensus/common/0.1/get_status failed after 0 retries [ 2009/02/16 23:03:06 ERROR call_xrl:13896 XRL +231 call_xrl.cc input_cmds ] No callback: finder://consensus/common/0.1/get_status Stopping. What did I do wrong?? Thanks for your help! Michael > FYI, the values for the static codes are listed in > libxorp/status_codes.h and the value for PROC_READY is 3. > > Regards, > Pavlin > > >> Thanks >> >> Michael >> >> _______________________________________________ >> Xorp-hackers mailing list >> Xorp-hackers at icir.org >> http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/xorp-hackers >> From pavlin at ICSI.Berkeley.EDU Mon Feb 16 20:29:54 2009 From: pavlin at ICSI.Berkeley.EDU (Pavlin Radoslavov) Date: Mon, 16 Feb 2009 20:29:54 -0800 Subject: [Xorp-hackers] Socket error In-Reply-To: <4999E3DF.6010906@lineway.net> References: <4999E3DF.6010906@lineway.net> Message-ID: <200902170429.n1H4TsdT021798@fruitcake.ICSI.Berkeley.EDU> illidan wrote: > Pavlin Radoslavov wrote: > > illidan wrote: > > > > > >> Hello, > >> > >> I was trying to open a socket using socket4 library. > >> I used function send_tcp_open_and_bind : > >> > >> create_socket.cc : > >> void SocketServer::get_create_socket() { > >> XorpCallback2::RefPtr cb; > >> IPv4 localIP("10.10.10.10"); > >> int localPort = 100; > >> cb = callback(this,&SocketServer::get_socket_id); > >> > >> send_tcp_open_and_bind("fea",_rtr.instance_name(),localIP,localPort,cb); > >> } > >> void SocketServer::get_socket_id(const XrlError& e,const string* id) { > >> if(e==XrlCmdError::OKAY()) { > >> fprintf(stderr,"I receive the response : %s\n",id->c_str()); > >> _socket_id = id->c_str(); > >> listen(); > >> return; > >> } > >> } > >> > >> When I run this program, I receive correctly the socket_id, but I get > >> an error in rtrmgr process : > >> > >> "[ 2009/02/16 13:11:01 WARNING xorp_rtrmgr:32679 XrlFinderTarget +721 > >> ../xrl/targets/finder_base.cc > >> handle_finder_event_notifier_0_1_register_instance_event_interest ] > >> Handling method for > >> finder_event_notifier/0.1/register_instance_event_interest failed: > >> XrlCmdError 102 Command failed failed to add watch > >> [ 2009/02/16 13:11:01 ERROR xorp_fea:32681 FEA +128 xrl_fea_io.cc > >> register_instance_event_interest_cb ] Failed to register event > >> interest in instance create_socket: 102 Command failed failed to add > >> watch" > >> > >> What could be the problem? Did I do something wrong?? > >> > > > > Was your create_socket program still running, and in READY state? > > > > You can verify both by using the following XRL by hand (you need to > > replace "fea" with the target name of your module): > > libxipc/call_xrl finder://fea/common/0.1/get_status > > > > If everything is normal you should see the following output: > > status:u32=3&reason:txt= > > > In fact, create_socket was not a process but a tool. > I did it like bgp/tools/xorpsh_print_peers. > I have my own process (call consensus), but I don't really know when > to start the tcp socket. So I did this tool to try to open a socket > (like a tester). > > I just try to create my socket in consensus > > XrlCmdError > ConsensusTarget::consensus_0_1_add_ip(const string& ip) { > _ip = ip; > // I try to create my socket > XLOG_INFO("%s\n", "Starting up CONSENSUS"); > SocketServer socket(_rtr,_eventloop); > socket.get_create_socket(); > return XrlCmdError::OKAY(); > } The issue seems to be that the SocketServer instance is created on the stack so it will be destroyed when you return from the above consensus_0_1_add_ip() method. You should make it a member of class ConsensusTarget. Regards, Pavlin > I run rtrmgr with the config file "static.boot and I add a consensus IP > with CLI. When I add the IP and "commit" it makes an error and kill my > process : > > Starting consensus protocol > [ 2009/02/16 23:00:34 TRACE xorp_rtrmgr RTRMGR ] Validating with XRL: > >finder://consensus/common/0.1/get_status< > [ 2009/02/16 23:00:34 TRACE xorp_rtrmgr RTRMGR ] Expanding xrl > $(consensus.targetname)/consensus/0.1/add_ip?ip:txt=$(@) > [ 2009/02/16 23:00:34 TRACE xorp_rtrmgr RTRMGR ] Executing XRL: > >finder://consensus/consensus/0.1/add_ip?ip:txt=10.10.10.1< > [ 2009/02/16 23:00:34 INFO xorp_consensus CONSENSUS ] Starting up CONSENSUS > [ 2009/02/16 23:00:34 INFO xorp_consensus CONSENSUS ] Starting up CONSENSUS > [ 2009/02/16 23:00:34 TRACE xorp_rtrmgr RTRMGR ] Validating with XRL: > >finder://consensus/common/0.1/get_status< > [ 2009/02/16 23:00:34 INFO xorp_rtrmgr:13806 RTRMGR +2233 task.cc > run_task ] No more tasks to run > [ 2009/02/16 23:00:34 TRACE xorp_rtrmgr RTRMGR ] > apply_config_change_done: status: 1 response: target: > xorpsh-13811-my_computer > [ 2009/02/16 23:00:34 ERROR xorp_rtrmgr:13806 RTRMGR +754 > module_manager.cc done_cb ] Command > "path_to_xorp/consensus/xorp_consensus": terminated with signal 11. > [ 2009/02/16 23:00:34 INFO xorp_rtrmgr:13806 RTRMGR +299 > module_manager.cc module_exited ] Module abnormally killed: consensus > > And apparently the process has not been started : > #./call_xrl finder://consensus/common/0.1/get_status > [ 2009/02/16 23:03:05 ERROR call_xrl:13896 XRL +57 call_xrl.cc > response_handler ] Failed. Reason: 201 Resolve failed > ("finder://consensus/common/0.1/get_status") > [ 2009/02/16 23:03:06 WARNING call_xrl XRL ] request: > finder://consensus/common/0.1/get_status resolve failed > [ 2009/02/16 23:03:06 WARNING call_xrl XRL ] request: > finder://consensus/common/0.1/get_status failed after 0 retries > [ 2009/02/16 23:03:06 ERROR call_xrl:13896 XRL +231 call_xrl.cc > input_cmds ] No callback: finder://consensus/common/0.1/get_status > Stopping. > > What did I do wrong?? > > Thanks for your help! > > Michael > > FYI, the values for the static codes are listed in > > libxorp/status_codes.h and the value for PROC_READY is 3. > > > > Regards, > > Pavlin > > > > > >> Thanks > >> > >> Michael > >> > >> _______________________________________________ > >> Xorp-hackers mailing list > >> Xorp-hackers at icir.org > >> http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/xorp-hackers > >> > > > _______________________________________________ > Xorp-hackers mailing list > Xorp-hackers at icir.org > http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/xorp-hackers From illidan at lineway.net Tue Feb 17 02:35:16 2009 From: illidan at lineway.net (illidan) Date: Tue, 17 Feb 2009 11:35:16 +0100 Subject: [Xorp-hackers] Socket error Message-ID: <499A92E4.7070607@lineway.net> Pavlin Radoslavov wrote: > illidan wrote: > > >> Pavlin Radoslavov wrote: >> >>> illidan wrote: >>> >>> >>> >>>> Hello, >>>> >>>> I was trying to open a socket using socket4 library. >>>> I used function send_tcp_open_and_bind : >>>> >>>> create_socket.cc : >>>> void SocketServer::get_create_socket() { >>>> XorpCallback2::RefPtr cb; >>>> IPv4 localIP("10.10.10.10"); >>>> int localPort = 100; >>>> cb = callback(this,&SocketServer::get_socket_id); >>>> >>>> send_tcp_open_and_bind("fea",_rtr.instance_name(),localIP,localPort,cb); >>>> >>>> } >>>> void SocketServer::get_socket_id(const XrlError& e,const string* id) { >>>> if(e==XrlCmdError::OKAY()) { >>>> fprintf(stderr,"I receive the response : %s\n",id->c_str()); >>>> _socket_id = id->c_str(); >>>> listen(); >>>> return; >>>> } >>>> } >>>> >>>> When I run this program, I receive correctly the socket_id, but I >>>> get an error in rtrmgr process : >>>> >>>> "[ 2009/02/16 13:11:01 WARNING xorp_rtrmgr:32679 XrlFinderTarget >>>> +721 ../xrl/targets/finder_base.cc >>>> handle_finder_event_notifier_0_1_register_instance_event_interest ] >>>> Handling method for >>>> finder_event_notifier/0.1/register_instance_event_interest failed: >>>> XrlCmdError 102 Command failed failed to add watch >>>> [ 2009/02/16 13:11:01 ERROR xorp_fea:32681 FEA +128 xrl_fea_io.cc >>>> register_instance_event_interest_cb ] Failed to register event >>>> interest in instance create_socket: 102 Command failed failed to >>>> add watch" >>>> >>>> What could be the problem? Did I do something wrong?? >>>> >>> Was your create_socket program still running, and in READY state? >>> >>> You can verify both by using the following XRL by hand (you need to >>> replace "fea" with the target name of your module): >>> libxipc/call_xrl finder://fea/common/0.1/get_status >>> >>> If everything is normal you should see the following output: >>> status:u32=3&reason:txt= >>> >> In fact, create_socket was not a process but a tool. >> I did it like bgp/tools/xorpsh_print_peers. >> I have my own process (call consensus), but I don't really know >> when to start the tcp socket. So I did this tool to try to open a >> socket (like a tester). >> >> I just try to create my socket in consensus >> >> XrlCmdError >> ConsensusTarget::consensus_0_1_add_ip(const string& ip) { >> _ip = ip; >> // I try to create my socket >> XLOG_INFO("%s\n", "Starting up CONSENSUS"); >> SocketServer socket(_rtr,_eventloop); >> socket.get_create_socket(); >> return XrlCmdError::OKAY(); >> } >> > > The issue seems to be that the SocketServer instance is created on > the stack so it will be destroyed when you return from the above > consensus_0_1_add_ip() method. You should make it a member of class > ConsensusTarget. > > Regards, > Pavlin > > Thanks It works! What is the difference between open a socket with fea or open a socket with libcomm? Thanks for your help! >> I run rtrmgr with the config file "static.boot and I add a consensus >> IP with CLI. When I add the IP and "commit" it makes an error and >> kill my process : >> >> Starting consensus protocol >> [ 2009/02/16 23:00:34 TRACE xorp_rtrmgr RTRMGR ] Validating with XRL: >> >finder://consensus/common/0.1/get_status< >> [ 2009/02/16 23:00:34 TRACE xorp_rtrmgr RTRMGR ] Expanding xrl >> $(consensus.targetname)/consensus/0.1/add_ip?ip:txt=$(@) >> [ 2009/02/16 23:00:34 TRACE xorp_rtrmgr RTRMGR ] Executing XRL: >> >finder://consensus/consensus/0.1/add_ip?ip:txt=10.10.10.1< >> [ 2009/02/16 23:00:34 INFO xorp_consensus CONSENSUS ] Starting up >> CONSENSUS >> [ 2009/02/16 23:00:34 INFO xorp_consensus CONSENSUS ] Starting up >> CONSENSUS >> [ 2009/02/16 23:00:34 TRACE xorp_rtrmgr RTRMGR ] Validating with XRL: >> >finder://consensus/common/0.1/get_status< >> [ 2009/02/16 23:00:34 INFO xorp_rtrmgr:13806 RTRMGR +2233 task.cc >> run_task ] No more tasks to run >> [ 2009/02/16 23:00:34 TRACE xorp_rtrmgr RTRMGR ] >> apply_config_change_done: status: 1 response: target: >> xorpsh-13811-my_computer >> [ 2009/02/16 23:00:34 ERROR xorp_rtrmgr:13806 RTRMGR +754 >> module_manager.cc done_cb ] Command >> "path_to_xorp/consensus/xorp_consensus": terminated with signal 11. >> [ 2009/02/16 23:00:34 INFO xorp_rtrmgr:13806 RTRMGR +299 >> module_manager.cc module_exited ] Module abnormally killed: consensus >> >> And apparently the process has not been started : >> #./call_xrl finder://consensus/common/0.1/get_status >> [ 2009/02/16 23:03:05 ERROR call_xrl:13896 XRL +57 call_xrl.cc >> response_handler ] Failed. Reason: 201 Resolve failed >> ("finder://consensus/common/0.1/get_status") >> [ 2009/02/16 23:03:06 WARNING call_xrl XRL ] request: >> finder://consensus/common/0.1/get_status resolve failed >> [ 2009/02/16 23:03:06 WARNING call_xrl XRL ] request: >> finder://consensus/common/0.1/get_status failed after 0 retries >> [ 2009/02/16 23:03:06 ERROR call_xrl:13896 XRL +231 call_xrl.cc >> input_cmds ] No callback: finder://consensus/common/0.1/get_status >> Stopping. >> >> What did I do wrong?? >> >> Thanks for your help! >> >> Michael >> >>> FYI, the values for the static codes are listed in >>> libxorp/status_codes.h and the value for PROC_READY is 3. >>> >>> Regards, >>> Pavlin >>> >>> >>> >>>> Thanks >>>> >>>> Michael >>>> >>>> _______________________________________________ >>>> Xorp-hackers mailing list >>>> Xorp-hackers at icir.org >>>> http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/xorp-hackers >>>> >> _______________________________________________ >> Xorp-hackers mailing list >> Xorp-hackers at icir.org >> http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/xorp-hackers >> From vfaion at gmail.com Tue Feb 17 04:35:30 2009 From: vfaion at gmail.com (Victor Faion) Date: Tue, 17 Feb 2009 12:35:30 +0000 Subject: [Xorp-hackers] Socket polling In-Reply-To: <200902161912.n1GJCpJ1011427@fruitcake.ICSI.Berkeley.EDU> References: <38f1dbe80902111237u32ca2f99wc32ad2e5e8be779a@mail.gmail.com> <200902121855.n1CItFLU017089@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902130828u7b56a096sba44892a79aeec4e@mail.gmail.com> <38f1dbe80902131156l69d6c683nbf415b838563fef5@mail.gmail.com> <38f1dbe80902161055r7aa33cabm14d73d5a1356c5e0@mail.gmail.com> <200902161912.n1GJCpJ1011427@fruitcake.ICSI.Berkeley.EDU> Message-ID: <38f1dbe80902170435ya972bebraf8537c39e5637a3@mail.gmail.com> On Mon, Feb 16, 2009 at 19:12, Pavlin Radoslavov wrote: > Victor Faion wrote: > >> On Fri, Feb 13, 2009 at 19:56, Victor Faion wrote: >> > On Fri, Feb 13, 2009 at 16:28, Victor Faion wrote: >> >> On Thu, Feb 12, 2009 at 18:55, Pavlin Radoslavov >> >> wrote: >> >>> Victor Faion wrote: >> >>> >> >>>> Hello, >> >>>> >> >>>> I was trying to setup a process that tries connect to its neighbours >> >>>> over TCP and basically I wanted it to keep trying to connect to its >> >>>> neighbours until it can, but I was having some trouble as the process >> >>>> basically stops trying to connect when it can't connect the first >> >>>> time. >> >>>> >> >>>> I iterate over all the neighbour objects calling their connect >> >>>> function which calls send_tcp_open_bind_connect. The callback given to >> >>>> send_tcp_open_bind_connect just checks if there was an error and if >> >>>> there was it calls connectRetry() which pretty much does the same >> >>>> thing as connect (calls send_tcp_open_bind_connect and passes it the >> >>>> same callback as connect). The problem is the first time when it calls >> >>>> connect and fails, it just calls the socket4_user_0_1_error_event >> >>>> function (saying ``Transport endpoint is not connected'' which is >> >>>> expected) but then it doesn't go back into connectRetry() and no >> >>>> connection is made when its neighbours are actually listening for this >> >>>> connection. Is there a better/easier way of doing this polling or am I >> >>>> just doing the recursing with the callback the wrong way? >> >>> >> >>> Is connectRetry() a method in your protocol? >> >>> >> >> >> >> >> >> Yeah, connect() takes in the parameters needed to call >> >> send_tcp_open_bind_connect() and saves them into the Neighbour object. >> >> Then connectRetry() uses the cached values to call >> >> send_tcp_open_bind_connect() if it fails the first time. >> >> >> >> >> >>> In your event handler for socket4_user_0_1_error_event you need to >> >>> handle the error conditions (e.g., schedule a call to >> >>> connectRetry()). >> >>> >> >> >> >> >> >> I tried to avoid this as this means iterating over all the neighbours >> >> again, checking each sockid and matching against the sockid received >> >> in socket4_user_0_1_error_event to figure out which neighbour's >> >> connect function to call again. Anyway I tried doing it like this but >> >> it still doesn't repeatedly try to connect to a neighbour. It goes in >> >> this order: >> >> >> >> 1. Try to connect normally using the neighbour's conect() (shouldn't be able to) >> >> >> >> 2. Callback for send_tcp_open_bind_connect gets called (and the >> >> XrlError object received is XrlError::OKAY() for some reason) >> >> >> >> 3. socketx_user_0_1_error_event gets called and says ``Transport >> >> endpoint is not connected fatal'' >> >> >> >> 4. Then socketx_user_0_1_error_event iterates over the neighbours, >> >> when it matches the one which has the sockid that >> >> socketx_user_0_1_error_event received it calls connect() again. >> >> >> >> 5. Then I get a warning that says ``Handling method for >> >> socket4_user/0.1/error_event failed: XrlCmdError 102 Command failed >> >> socket error'' >> >> >> >> 6. Then the same thing as step 2 happens. >> >> >> >> The cycle ends there, connect() only gets called twice because >> >> socketx_user_0_1_error_event only gets called once. Not sure why this >> >> happens, something to do with that warning. Why does that happen >> >> though? >> >> >> >> >> >>> Also, are you saying that the first time you call >> >>> send_tcp_open_bind_connect() and it fails, the callback for that XRL >> >>> is not called at all? I would guess the callback might be called >> >>> after socket4_user_0_1_error_event is received, but I wouldn't bet >> >>> on the ordering. >> >>> >> >>> Pavlin >> >>> >> >> >> >> >> >> Well the callback gets called but the problem is that I'm not sure >> >> which of the callback and the error event handler get called last in >> >> order to reschedule the connecting. >> >> >> >> Victor >> >> >> > >> > >> > Sorry the reason for step 5 above was because my >> > socket4_user_0_1_error_event was returning >> > XrlCmdError::COMMAND_FAILED("socket error"). However when I changed it >> > to return XrlCmdError::OKAY() basically it goes through steps 1-4 from >> > above except sometimes, it doesn't happen in the order above but in >> > the order 1, 3, 4, 2. When this happens it ends in step 2 and a >> > connection is not made. This happens because the callback sets the >> > sockid of the neighbour when a connection attempt is made, and the >> > error handler uses this sockid to know which neighbour to connect to. >> > So when the new sockid doesn't get set, the error handler doesn't find >> > the neighbour. Not sure how to get the new sockid into the event >> > handler when it doesn't get set into the callback. >> > >> >> >> Hello, >> >> Sorry to restart this thread, I'm not sure how to handle the case when >> a router cannot connect to another router. I don't understand why when >> I call send_tcp_open_bind_connect to another router (which isn't even >> online) the callback to send_tcp_open_bind_connect receives >> XrlError::OKAY(). I wanted to handle this error in the callback as I >> don't have enough information to handle it in the >> socket4_user_0_1_error_event function. I couldn't find any code in >> XORP that does this sort of thing. Where do the errors that get passed >> into the callback for send_tcp_open_bind_connect get set? > > For a reason that is unclear to me without further investigation, > the order of the send_tcp_open_bind_connect callback and the > socket4_user_0_1_error_event upcall are reversed > (always/occasionally?). I had a quick look in the FEA, and the > callback should be received first, but obviously from your > description this doesn't seem to be the case. > The correct solution should be to investigate the issue and fix it. > This might require understanding of the FEA I/O internals and some > XRL-related knowledge. Unfortunately, I can't give you an estimate > how soon I/we can allocate the resources to fix that, so your best > bet would be to submit a Bugzilla entry. > Yeah they are reversed, I think it only happens when I reschedule send_tcp_open_bind_connect from socket4_user_0_1_error_event. In that case, it calls socket4_user_0_1_error_event before the callback. I can submit a bug report, what sort of information should I include? Here's the relevant output from when I start xorp_rtrmgr. At first it attempts to connect normally, then goes to the callback, then socket4_user_0_1_error_event, matches the sockid because it has been set in the callback then attempts to reconnect to that IP. However after this is goes back to socket4_user_0_1_error_event before the callback (and so the new sockid is not set and there is no match and no reconnection attempt). [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] Connecting to 146.169.3.10 [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] CB for 92a9030b-02ba706b-0006c2a9-3c670000 [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] socketx_user_0_1_error_event 92a9030b-02ba706b-0006c2a9-3c670000 Transport endpoint is not connected fatal [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] sockid match: 146.169.3.10 [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] connect retry [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] socketx_user_0_1_error_event 92a9030b-02ba706b-0006d31d-3c670000 Transport endpoint is not connected fatal [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] CB for 92a9030b-02ba706b-0006d31d-3c670000 > For your own purpose you need to move forward by using some > workaround. One possible solution that comes to mind is to have a > map of states per sockid that can be populated/updated regardless of > the order of the callbacks and the upcalls. E.g., if an upcall is > received before the sockid is known, a new entry is created for that > sockid and the state is set according to the upcall error. Then, > after the send_tcp_open_bind_connect callback is invoked, at that > time the sockid entry can be used for its intended purpose (and the > error condition is already filled-in). Sounds good I will try to implement this :-) > On the other hand, if the upcall is inbound_connect_event or > outbound_connect_event (instead of error_event), then only after the > send_tcp_open_bind_connect callback is called, then you take the > appropriate actions. > Doesn't this also assume that inbound_connect_event/outbound_connect_event get called after the callback? (Not sure if this is what actually happens). > Hope that helps, > Pavlin > Thanks for the help, I'll try to use your suggestion and see how that goes. Victor From pavlin at ICSI.Berkeley.EDU Tue Feb 17 09:28:11 2009 From: pavlin at ICSI.Berkeley.EDU (Pavlin Radoslavov) Date: Tue, 17 Feb 2009 09:28:11 -0800 Subject: [Xorp-hackers] Socket error In-Reply-To: <499A92E4.7070607@lineway.net> References: <499A92E4.7070607@lineway.net> Message-ID: <200902171728.n1HHSBue028984@fruitcake.ICSI.Berkeley.EDU> > Thanks It works! Great! > What is the difference between open a socket with fea or open a socket > with libcomm? libcomm is a shim library that sits on top of regular socket calls (for TCP and UDP purpose). FEA is an abstraction layer above the hardware/forwarding plane that deals with interface configuration, adding/deleting routes to/from the FIB, I/O (TCP/UDP/raw IP), etc. For TCP/UDP I/O purpose the FEA actually uses libcomm. If a protocol process uses the FEA, then you can have much greater flexibility: e.g., you can have that process running on a remote host, and the FEA acting as a proxy on the host with the forwarding plane. Regards, Pavlin From pavlin at ICSI.Berkeley.EDU Tue Feb 17 09:54:47 2009 From: pavlin at ICSI.Berkeley.EDU (Pavlin Radoslavov) Date: Tue, 17 Feb 2009 09:54:47 -0800 Subject: [Xorp-hackers] Socket polling In-Reply-To: <38f1dbe80902170435ya972bebraf8537c39e5637a3@mail.gmail.com> References: <38f1dbe80902111237u32ca2f99wc32ad2e5e8be779a@mail.gmail.com> <200902121855.n1CItFLU017089@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902130828u7b56a096sba44892a79aeec4e@mail.gmail.com> <38f1dbe80902131156l69d6c683nbf415b838563fef5@mail.gmail.com> <38f1dbe80902161055r7aa33cabm14d73d5a1356c5e0@mail.gmail.com> <200902161912.n1GJCpJ1011427@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902170435ya972bebraf8537c39e5637a3@mail.gmail.com> Message-ID: <200902171754.n1HHslxM002910@fruitcake.ICSI.Berkeley.EDU> Victor Faion wrote: > >> Sorry to restart this thread, I'm not sure how to handle the case when > >> a router cannot connect to another router. I don't understand why when > >> I call send_tcp_open_bind_connect to another router (which isn't even > >> online) the callback to send_tcp_open_bind_connect receives > >> XrlError::OKAY(). I wanted to handle this error in the callback as I > >> don't have enough information to handle it in the > >> socket4_user_0_1_error_event function. I couldn't find any code in > >> XORP that does this sort of thing. Where do the errors that get passed > >> into the callback for send_tcp_open_bind_connect get set? > > > > For a reason that is unclear to me without further investigation, > > the order of the send_tcp_open_bind_connect callback and the > > socket4_user_0_1_error_event upcall are reversed > > (always/occasionally?). I had a quick look in the FEA, and the > > callback should be received first, but obviously from your > > description this doesn't seem to be the case. > > The correct solution should be to investigate the issue and fix it. > > This might require understanding of the FEA I/O internals and some > > XRL-related knowledge. Unfortunately, I can't give you an estimate > > how soon I/we can allocate the resources to fix that, so your best > > bet would be to submit a Bugzilla entry. > > > > Yeah they are reversed, I think it only happens when I reschedule > send_tcp_open_bind_connect from socket4_user_0_1_error_event. In that > case, it calls socket4_user_0_1_error_event before the callback. > I can submit a bug report, what sort of information should I include? A sample of the relevant code (pseudo-code is OK if the original code is too long), a brief description of what you think the expected behavior should be, description of what the actual behavior is, log output that might be relevant to the issue, and anything else that you think might help. > Here's the relevant output from when I start xorp_rtrmgr. At first it > attempts to connect normally, then goes to the callback, then > socket4_user_0_1_error_event, matches the sockid because it has been > set in the callback then attempts to reconnect to that IP. However > after this is goes back to socket4_user_0_1_error_event before the > callback (and so the new sockid is not set and there is no match and > no reconnection attempt). > > [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] Connecting to 146.169.3.10 > [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] CB for > 92a9030b-02ba706b-0006c2a9-3c670000 > [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] > socketx_user_0_1_error_event 92a9030b-02ba706b-0006c2a9-3c670000 > Transport endpoint is not connected fatal > [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] sockid match: 146.169.3.10 > [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] connect retry > [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] > socketx_user_0_1_error_event 92a9030b-02ba706b-0006d31d-3c670000 > Transport endpoint is not connected fatal > [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] CB for > 92a9030b-02ba706b-0006d31d-3c670000 A question that just came to mind trying to analyze the above log. if the original tcp_open_bind_connect call fails, are you sending again same XRL for same destination? This shouldn't be necessary, and I wonder whether this is relevant to the behavior you are seeing. If the connect failed, the FEA should send you either inbound_connect_event or outgoing_connect_event if the connection succeeded later. Note that this is what _should_ happen, but I don't know whether the FEA actually does the right thing. > > For your own purpose you need to move forward by using some > > workaround. One possible solution that comes to mind is to have a > > map of states per sockid that can be populated/updated regardless of > > the order of the callbacks and the upcalls. E.g., if an upcall is > > received before the sockid is known, a new entry is created for that > > sockid and the state is set according to the upcall error. Then, > > after the send_tcp_open_bind_connect callback is invoked, at that > > time the sockid entry can be used for its intended purpose (and the > > error condition is already filled-in). > > Sounds good I will try to implement this :-) > > > On the other hand, if the upcall is inbound_connect_event or > > outbound_connect_event (instead of error_event), then only after the > > send_tcp_open_bind_connect callback is called, then you take the > > appropriate actions. > > > > Doesn't this also assume that > inbound_connect_event/outbound_connect_event get called after the > callback? (Not sure if this is what actually happens). I believe they should be called after the callback, but I am not sure this is what actually happens, so you would have to try it. If you see another case of reordered events, then you need to utilize the above workaround. Regards, Pavlin > > Thanks for the help, I'll try to use your suggestion and see how that goes. > > Victor > > _______________________________________________ > Xorp-hackers mailing list > Xorp-hackers at icir.org > http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/xorp-hackers From vfaion at gmail.com Tue Feb 17 11:18:05 2009 From: vfaion at gmail.com (Victor Faion) Date: Tue, 17 Feb 2009 19:18:05 +0000 Subject: [Xorp-hackers] Socket polling In-Reply-To: <200902171754.n1HHslxM002910@fruitcake.ICSI.Berkeley.EDU> References: <38f1dbe80902111237u32ca2f99wc32ad2e5e8be779a@mail.gmail.com> <200902121855.n1CItFLU017089@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902130828u7b56a096sba44892a79aeec4e@mail.gmail.com> <38f1dbe80902131156l69d6c683nbf415b838563fef5@mail.gmail.com> <38f1dbe80902161055r7aa33cabm14d73d5a1356c5e0@mail.gmail.com> <200902161912.n1GJCpJ1011427@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902170435ya972bebraf8537c39e5637a3@mail.gmail.com> <200902171754.n1HHslxM002910@fruitcake.ICSI.Berkeley.EDU> Message-ID: <38f1dbe80902171118j67889a5bjd74f6f7b6b4c5421@mail.gmail.com> On Tue, Feb 17, 2009 at 17:54, Pavlin Radoslavov wrote: > Victor Faion wrote: > >> >> Sorry to restart this thread, I'm not sure how to handle the case when >> >> a router cannot connect to another router. I don't understand why when >> >> I call send_tcp_open_bind_connect to another router (which isn't even >> >> online) the callback to send_tcp_open_bind_connect receives >> >> XrlError::OKAY(). I wanted to handle this error in the callback as I >> >> don't have enough information to handle it in the >> >> socket4_user_0_1_error_event function. I couldn't find any code in >> >> XORP that does this sort of thing. Where do the errors that get passed >> >> into the callback for send_tcp_open_bind_connect get set? >> > >> > For a reason that is unclear to me without further investigation, >> > the order of the send_tcp_open_bind_connect callback and the >> > socket4_user_0_1_error_event upcall are reversed >> > (always/occasionally?). I had a quick look in the FEA, and the >> > callback should be received first, but obviously from your >> > description this doesn't seem to be the case. >> > The correct solution should be to investigate the issue and fix it. >> > This might require understanding of the FEA I/O internals and some >> > XRL-related knowledge. Unfortunately, I can't give you an estimate >> > how soon I/we can allocate the resources to fix that, so your best >> > bet would be to submit a Bugzilla entry. >> > >> >> Yeah they are reversed, I think it only happens when I reschedule >> send_tcp_open_bind_connect from socket4_user_0_1_error_event. In that >> case, it calls socket4_user_0_1_error_event before the callback. >> I can submit a bug report, what sort of information should I include? > > A sample of the relevant code (pseudo-code is OK if the original > code is too long), a brief description of what you think the > expected behavior should be, description of what the actual behavior > is, log output that might be relevant to the issue, and anything > else that you think might help. > >> Here's the relevant output from when I start xorp_rtrmgr. At first it >> attempts to connect normally, then goes to the callback, then >> socket4_user_0_1_error_event, matches the sockid because it has been >> set in the callback then attempts to reconnect to that IP. However >> after this is goes back to socket4_user_0_1_error_event before the >> callback (and so the new sockid is not set and there is no match and >> no reconnection attempt). >> OK, I'm still not 100% sure it's a bug or that I'm just doing something wrong. >> [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] Connecting to 146.169.3.10 >> [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] CB for >> 92a9030b-02ba706b-0006c2a9-3c670000 >> [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] >> socketx_user_0_1_error_event 92a9030b-02ba706b-0006c2a9-3c670000 >> Transport endpoint is not connected fatal >> [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] sockid match: 146.169.3.10 >> [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] connect retry >> [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] >> socketx_user_0_1_error_event 92a9030b-02ba706b-0006d31d-3c670000 >> Transport endpoint is not connected fatal >> [ 2009/02/17 12:06:07 INFO xorp_bpsf XrlBpsfTarget ] CB for >> 92a9030b-02ba706b-0006d31d-3c670000 > > A question that just came to mind trying to analyze the above log. > if the original tcp_open_bind_connect call fails, are you sending > again same XRL for same destination? > This shouldn't be necessary, and I wonder whether this is relevant > to the behavior you are seeing. > > If the connect failed, the FEA should send you either > inbound_connect_event or outgoing_connect_event if the connection > succeeded later. Note that this is what _should_ happen, but I don't > know whether the FEA actually does the right thing. > I'm using instance_name() so for both calls the destination is something like this: bpsf-2c2e48eee1a7c19f0b55332900581229 at 127.0.0.1 Yep, both times it sends the send_tcp_open_bind_connect XRL. If I don't resend the XRL it just ends in the error event handler function and when the other router comes online, it doesn't receive an inbound connection event. Are you saying the FEA should keep retrying automatically? That would make things a lot simpler :-) > >> > For your own purpose you need to move forward by using some >> > workaround. One possible solution that comes to mind is to have a >> > map of states per sockid that can be populated/updated regardless of >> > the order of the callbacks and the upcalls. E.g., if an upcall is >> > received before the sockid is known, a new entry is created for that >> > sockid and the state is set according to the upcall error. Then, >> > after the send_tcp_open_bind_connect callback is invoked, at that >> > time the sockid entry can be used for its intended purpose (and the >> > error condition is already filled-in). >> >> Sounds good I will try to implement this :-) >> >> > On the other hand, if the upcall is inbound_connect_event or >> > outbound_connect_event (instead of error_event), then only after the >> > send_tcp_open_bind_connect callback is called, then you take the >> > appropriate actions. >> > >> >> Doesn't this also assume that >> inbound_connect_event/outbound_connect_event get called after the >> callback? (Not sure if this is what actually happens). > > I believe they should be called after the callback, but I am not > sure this is what actually happens, so you would have to try it. If > you see another case of reordered events, then you need to utilize the > above workaround. > > Regards, > Pavlin > OK, I will take a look at this. Cheers, Victor > >> >> Thanks for the help, I'll try to use your suggestion and see how that goes. >> >> Victor >> >> _______________________________________________ >> Xorp-hackers mailing list >> Xorp-hackers at icir.org >> http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/xorp-hackers > From pavlin at ICSI.Berkeley.EDU Tue Feb 17 13:56:06 2009 From: pavlin at ICSI.Berkeley.EDU (Pavlin Radoslavov) Date: Tue, 17 Feb 2009 13:56:06 -0800 Subject: [Xorp-hackers] Socket polling In-Reply-To: <38f1dbe80902171118j67889a5bjd74f6f7b6b4c5421@mail.gmail.com> References: <38f1dbe80902111237u32ca2f99wc32ad2e5e8be779a@mail.gmail.com> <200902121855.n1CItFLU017089@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902130828u7b56a096sba44892a79aeec4e@mail.gmail.com> <38f1dbe80902131156l69d6c683nbf415b838563fef5@mail.gmail.com> <38f1dbe80902161055r7aa33cabm14d73d5a1356c5e0@mail.gmail.com> <200902161912.n1GJCpJ1011427@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902170435ya972bebraf8537c39e5637a3@mail.gmail.com> <200902171754.n1HHslxM002910@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902171118j67889a5bjd74f6f7b6b4c5421@mail.gmail.com> Message-ID: <200902172156.n1HLu77t006553@fruitcake.ICSI.Berkeley.EDU> > If I don't resend the XRL it just ends in the error event handler > function and when the other router comes online, it doesn't receive an > inbound connection event. Are you saying the FEA should keep retrying > automatically? That would make things a lot simpler :-) Yes. This is the purpose of the inbound_connect_event/outbound_connect_event upcalls to notify you when the connect succeeded. Whether it actually does that properly is different question. Pavlin From vfaion at gmail.com Tue Feb 17 16:02:40 2009 From: vfaion at gmail.com (Victor Faion) Date: Wed, 18 Feb 2009 00:02:40 +0000 Subject: [Xorp-hackers] Socket polling In-Reply-To: <200902172156.n1HLu77t006553@fruitcake.ICSI.Berkeley.EDU> References: <38f1dbe80902111237u32ca2f99wc32ad2e5e8be779a@mail.gmail.com> <200902121855.n1CItFLU017089@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902130828u7b56a096sba44892a79aeec4e@mail.gmail.com> <38f1dbe80902131156l69d6c683nbf415b838563fef5@mail.gmail.com> <38f1dbe80902161055r7aa33cabm14d73d5a1356c5e0@mail.gmail.com> <200902161912.n1GJCpJ1011427@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902170435ya972bebraf8537c39e5637a3@mail.gmail.com> <200902171754.n1HHslxM002910@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902171118j67889a5bjd74f6f7b6b4c5421@mail.gmail.com> <200902172156.n1HLu77t006553@fruitcake.ICSI.Berkeley.EDU> Message-ID: <38f1dbe80902171602g53efb920pac425688d670985f@mail.gmail.com> On Tue, Feb 17, 2009 at 21:56, Pavlin Radoslavov wrote: >> If I don't resend the XRL it just ends in the error event handler >> function and when the other router comes online, it doesn't receive an >> inbound connection event. Are you saying the FEA should keep retrying >> automatically? That would make things a lot simpler :-) > > Yes. > This is the purpose of the > inbound_connect_event/outbound_connect_event upcalls to notify you > when the connect succeeded. Whether it actually does that properly > is different question. > > Pavlin > Hmm, well this doesn't happen, I'll try to use the workaround. I think I'll file a bug report. Victor From vfaion at gmail.com Thu Feb 19 09:34:06 2009 From: vfaion at gmail.com (Victor Faion) Date: Thu, 19 Feb 2009 17:34:06 +0000 Subject: [Xorp-hackers] Constructing packets Message-ID: <38f1dbe80902190934o5cdde4dcq49d04d048fae6266@mail.gmail.com> I was trying to construct a simple packet and send it over a socket. I defined the header like this: typedef struct bpsfhdr { uint8_t type; uint32_t src; } bpsfhdr; Then to construct it and send it I did this just as a test: vector data; data.reserve(sizeof(bpsfhdr)); bpsfhdr hdr; hdr.type = 42; hdr.src = ip.addr(); memcpy(&data[0], &hdr, sizeof(bpsfhdr)); socketCl.send_send(dst, sockid, data, callback(this, &Neighbour::send_cb)); I didn't really know how to put the data inside the vector. For example if I use the copy_out() function of the IPv4 class I thought the IP address would overflow if I just had a uint8_t field in the struct. Is there a higher level way of adding data into the packets passed into send_send, for example, adding a variable length string? Can I have for example a field of type string inside the struct? I think this is where I am going wrong, but I looked at a few examples in other XORP processes and it was done in a similar way. To receive/umarshall the packet in socket4_user_0_1_recv_event I used the AlignData class: AlignData aligned(pdata); const struct bpsfhdr* pkt = aligned.payload(); uint8_t type = pkt->type; IPv4 src(pkt->src); XLOG_INFO("type = %u src = %s", type, src.str().c_str()); But when I run this I get the following error: xorp_fea: asyncio.cc:450: void AsyncFileWriter::add_data(const std::vector >&, const ref_ptr >&): Assertion `data.size() != 0' failed. [ 2009/02/19 17:15:58 ERROR xorp_rtrmgr:30765 RTRMGR +754 module_manager.cc done_cb ] Command "/root/project/xorp1.6/install/fea/xorp_fea": terminated with signal 6; aborted with a core dump. Cheers, Victor From pavlin at ICSI.Berkeley.EDU Fri Feb 20 11:51:25 2009 From: pavlin at ICSI.Berkeley.EDU (Pavlin Radoslavov) Date: Fri, 20 Feb 2009 11:51:25 -0800 Subject: [Xorp-hackers] Constructing packets In-Reply-To: <38f1dbe80902190934o5cdde4dcq49d04d048fae6266@mail.gmail.com> References: <38f1dbe80902190934o5cdde4dcq49d04d048fae6266@mail.gmail.com> Message-ID: <200902201951.n1KJpPSr027004@fruitcake.ICSI.Berkeley.EDU> Victor Faion wrote: > I was trying to construct a simple packet and send it over a socket. I > defined the header like this: > > typedef struct bpsfhdr { > uint8_t type; > uint32_t src; > } bpsfhdr; > > Then to construct it and send it I did this just as a test: > > vector data; > data.reserve(sizeof(bpsfhdr)); > bpsfhdr hdr; > hdr.type = 42; > hdr.src = ip.addr(); > memcpy(&data[0], &hdr, sizeof(bpsfhdr)); > socketCl.send_send(dst, sockid, data, > callback(this, &Neighbour::send_cb)); You shouldn't be using method vector<>::reserve() because all it does is helping avoiding re-allocation (e.g., if you call vector<>::resize()). E.g., if you print data.size() right resize(), you will get 0. Instead, you should use data.resize(...) or even better just specify the size when you declare the vector variable: vector data(sizeof(bpsfhdr)); > I didn't really know how to put the data inside the vector. For > example if I use the copy_out() function of the IPv4 class I thought > the IP address would overflow if I just had a uint8_t field in the > struct. Is there a higher level way of adding data into the packets You can use the above mechanism (write the data to a struct, and then copying it to the buffer), but you have to be careful with the host/network ordering of the values, and with the padding in the structure. Alternatively, you can use the embed_*() and extract_*() functions in libproto/packet.hh which allow you to write directly to the output buffer. By using this appropac you avoid the extra memory copy, and you don't have the host/network ordering and padding issues. > passed into send_send, for example, adding a variable length string? > Can I have for example a field of type string inside the struct? I > think this is where I am going wrong, but I looked at a few examples > in other XORP processes and it was done in a similar way. You can't just use the C++ string and just copy it on the wire. You must use C-style string (basically a variable length array with the string value). There are different ways to encode the string on the wire; one of the simplest is to define a fixed max-length for the string itself and reserve that space in your packet. Then have the string zero-terminated as in C to avoid the extra encoding of the length itself. > To receive/umarshall the packet in socket4_user_0_1_recv_event I used > the AlignData class: > > AlignData aligned(pdata); > const struct bpsfhdr* pkt = aligned.payload(); > uint8_t type = pkt->type; > IPv4 src(pkt->src); > XLOG_INFO("type = %u src = %s", type, src.str().c_str()); > > But when I run this I get the following error: > > xorp_fea: asyncio.cc:450: void AsyncFileWriter::add_data(const > std::vector >&, const > ref_ptr size_t, size_t> >&): Assertion `data.size() != 0' failed. > [ 2009/02/19 17:15:58 ERROR xorp_rtrmgr:30765 RTRMGR +754 > module_manager.cc done_cb ] Command > "/root/project/xorp1.6/install/fea/xorp_fea": terminated with signal > 6; aborted with a core dump. You get the above assert because the original data size was zero (because of the usage of reserve()). Regards, Pavlin From vfaion at gmail.com Mon Feb 23 15:39:52 2009 From: vfaion at gmail.com (Victor Faion) Date: Mon, 23 Feb 2009 23:39:52 +0000 Subject: [Xorp-hackers] Constructing packets In-Reply-To: <200902201951.n1KJpPSr027004@fruitcake.ICSI.Berkeley.EDU> References: <38f1dbe80902190934o5cdde4dcq49d04d048fae6266@mail.gmail.com> <200902201951.n1KJpPSr027004@fruitcake.ICSI.Berkeley.EDU> Message-ID: <38f1dbe80902231539p6f9b8417y7264c4fc4105030b@mail.gmail.com> On Fri, Feb 20, 2009 at 19:51, Pavlin Radoslavov wrote: > Victor Faion wrote: > >> I was trying to construct a simple packet and send it over a socket. I >> defined the header like this: >> >> typedef struct bpsfhdr { >> uint8_t type; >> uint32_t src; >> } bpsfhdr; >> >> Then to construct it and send it I did this just as a test: >> >> vector data; >> data.reserve(sizeof(bpsfhdr)); >> bpsfhdr hdr; >> hdr.type = 42; >> hdr.src = ip.addr(); >> memcpy(&data[0], &hdr, sizeof(bpsfhdr)); >> socketCl.send_send(dst, sockid, data, >> callback(this, &Neighbour::send_cb)); > > You shouldn't be using method vector<>::reserve() because all it > does is helping avoiding re-allocation (e.g., if you call > vector<>::resize()). > E.g., if you print data.size() right resize(), you will get 0. > > Instead, you should use data.resize(...) or even better just specify > the size when you declare the vector variable: > > vector data(sizeof(bpsfhdr)); > > >> I didn't really know how to put the data inside the vector. For >> example if I use the copy_out() function of the IPv4 class I thought >> the IP address would overflow if I just had a uint8_t field in the >> struct. Is there a higher level way of adding data into the packets > > You can use the above mechanism (write the data to a struct, and then > copying it to the buffer), but you have to be careful with the > host/network ordering of the values, and with the padding in the > structure. > > Alternatively, you can use the embed_*() and extract_*() functions > in libproto/packet.hh which allow you to write directly to the > output buffer. By using this appropac you avoid the extra memory > copy, and you don't have the host/network ordering and padding > issues. > >> passed into send_send, for example, adding a variable length string? >> Can I have for example a field of type string inside the struct? I >> think this is where I am going wrong, but I looked at a few examples >> in other XORP processes and it was done in a similar way. > > You can't just use the C++ string and just copy it on the wire. You > must use C-style string (basically a variable length array with the > string value). > There are different ways to encode the string on the wire; one of > the simplest is to define a fixed max-length for the string itself > and reserve that space in your packet. Then have the string > zero-terminated as in C to avoid the extra encoding of the length > itself. > >> To receive/umarshall the packet in socket4_user_0_1_recv_event I used >> the AlignData class: >> >> AlignData aligned(pdata); >> const struct bpsfhdr* pkt = aligned.payload(); >> uint8_t type = pkt->type; >> IPv4 src(pkt->src); >> XLOG_INFO("type = %u src = %s", type, src.str().c_str()); >> >> But when I run this I get the following error: >> >> xorp_fea: asyncio.cc:450: void AsyncFileWriter::add_data(const >> std::vector >&, const >> ref_ptr> size_t, size_t> >&): Assertion `data.size() != 0' failed. >> [ 2009/02/19 17:15:58 ERROR xorp_rtrmgr:30765 RTRMGR +754 >> module_manager.cc done_cb ] Command >> "/root/project/xorp1.6/install/fea/xorp_fea": terminated with signal >> 6; aborted with a core dump. > > You get the above assert because the original data size was zero > (because of the usage of reserve()). > > Regards, > Pavlin > Thank you for the help, the embed_*() and extract_*() functions are working. I use embed_8() on each character of the string. I don't understand when (or if) I need to use the alignment functions in AlignData. When I receive the packet now I just use the extract_*() functions and everything seems to be aligned. A sort of related question, I was trying to put a timestamp in a packet using TimeVal::sec(). To test the time functions I just did this: TimeVal now; TimerList::system_gettimeofday(&now); XLOG_INFO("Time is %s", now.pretty_print().c_str()); But when I run this I get something like this: Time is Thu Apr 6 08:23:07 1972 even though the system clock is set right and date gives the right time. Am I using these functions in the wrong way? Cheers, Victor From pavlin at ICSI.Berkeley.EDU Wed Feb 25 02:17:31 2009 From: pavlin at ICSI.Berkeley.EDU (Pavlin Radoslavov) Date: Wed, 25 Feb 2009 02:17:31 -0800 Subject: [Xorp-hackers] Constructing packets In-Reply-To: <38f1dbe80902231539p6f9b8417y7264c4fc4105030b@mail.gmail.com> References: <38f1dbe80902190934o5cdde4dcq49d04d048fae6266@mail.gmail.com> <200902201951.n1KJpPSr027004@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902231539p6f9b8417y7264c4fc4105030b@mail.gmail.com> Message-ID: <200902251017.n1PAHV23022468@fruitcake.ICSI.Berkeley.EDU> Victor Faion wrote: > Thank you for the help, the embed_*() and extract_*() functions are > working. I use embed_8() on each character of the string. I don't > understand when (or if) I need to use the alignment functions in > AlignData. When I receive the packet now I just use the extract_*() > functions and everything seems to be aligned. You don't need AlignData. That class is used only in the FEA when we need to deal with certain system struct types when they are aligned with data buffers. > A sort of related question, I was trying to put a timestamp in a > packet using TimeVal::sec(). To test the time functions I just did > this: > > TimeVal now; > TimerList::system_gettimeofday(&now); > XLOG_INFO("Time is %s", now.pretty_print().c_str()); > > But when I run this I get something like this: > > Time is Thu Apr 6 08:23:07 1972 > > even though the system clock is set right and date gives the right > time. Am I using these functions in the wrong way? You shouldn't use TimerList::system_gettimeofday() to print the current time. Depending on the OS, TimerList::system_gettimeofday() might call either clock_gettime(CLOCK_MONOTONIC) or gettimeofday(2) (the former is preferred). If it is the former, then you get the monotonic time since some unspecified starting point in the past. If you really want to print the current time then you can use xlog_localtime2string() function from libxorp (you must include header file "libxorp/xlog.h"). Regards, Pavlin From vfaion at gmail.com Wed Feb 25 09:15:40 2009 From: vfaion at gmail.com (Victor Faion) Date: Wed, 25 Feb 2009 17:15:40 +0000 Subject: [Xorp-hackers] Constructing packets In-Reply-To: <200902251017.n1PAHV23022468@fruitcake.ICSI.Berkeley.EDU> References: <38f1dbe80902190934o5cdde4dcq49d04d048fae6266@mail.gmail.com> <200902201951.n1KJpPSr027004@fruitcake.ICSI.Berkeley.EDU> <38f1dbe80902231539p6f9b8417y7264c4fc4105030b@mail.gmail.com> <200902251017.n1PAHV23022468@fruitcake.ICSI.Berkeley.EDU> Message-ID: <38f1dbe80902250915g1ea2682o25e1e61fb8b2fb63@mail.gmail.com> On Wed, Feb 25, 2009 at 10:17, Pavlin Radoslavov wrote: > Victor Faion wrote: > >> Thank you for the help, the embed_*() and extract_*() functions are >> working. I use embed_8() on each character of the string. I don't >> understand when (or if) I need to use the alignment functions in >> AlignData. When I receive the packet now I just use the extract_*() >> functions and everything seems to be aligned. > > You don't need AlignData. That class is used only in the FEA when we > need to deal with certain system struct types when they are aligned > with data buffers. > >> A sort of related question, I was trying to put a timestamp in a >> packet using TimeVal::sec(). To test the time functions I just did >> this: >> >> TimeVal now; >> TimerList::system_gettimeofday(&now); >> XLOG_INFO("Time is %s", now.pretty_print().c_str()); >> >> But when I run this I get something like this: >> >> Time is Thu Apr ?6 08:23:07 1972 >> >> even though the system clock is set right and date gives the right >> time. Am I using these functions in the wrong way? > > You shouldn't use TimerList::system_gettimeofday() to print > the current time. > Depending on the OS, TimerList::system_gettimeofday() might call > either clock_gettime(CLOCK_MONOTONIC) or gettimeofday(2) > (the former is preferred). > If it is the former, then you get the monotonic time since some > unspecified starting point in the past. > > If you really want to print the current time then you can use > xlog_localtime2string() function from libxorp (you must include > header file "libxorp/xlog.h"). > > Regards, > Pavlin > Cheers, that works for me :-) Victor From vfaion at gmail.com Thu Feb 26 15:07:14 2009 From: vfaion at gmail.com (Victor Faion) Date: Thu, 26 Feb 2009 23:07:14 +0000 Subject: [Xorp-hackers] Computing shortest path trees Message-ID: <38f1dbe80902261507g17ae73dfl9775980a21fed7df@mail.gmail.com> Hello, I was trying to compute a shortest path tree starting at each router in my network using the Spt class from libproto. I made the nodes of type IPv4 and the cost associated with an edge is the RTT between those routers. I don't understand how to use the result given by Spt::compute (a list of RouteCmd). Are these operations that must be performed on the whole graph (i.e. everything I've added to the Spt object on which I call the compute function), and if so is there a function that does this? Or does the compute function itself prune the graph? Thanks, Victor From bms at incunabulum.net Thu Feb 26 16:12:52 2009 From: bms at incunabulum.net (Bruce Simpson) Date: Fri, 27 Feb 2009 00:12:52 +0000 Subject: [Xorp-hackers] Computing shortest path trees In-Reply-To: <38f1dbe80902261507g17ae73dfl9775980a21fed7df@mail.gmail.com> References: <38f1dbe80902261507g17ae73dfl9775980a21fed7df@mail.gmail.com> Message-ID: <49A73004.6080101@incunabulum.net> Victor Faion wrote: ... > I don't understand how to use the result given by > Spt::compute (a list of RouteCmd). > Are these operations that > must be performed on the whole graph (i.e. everything I've added to > the Spt object on which I call the compute function), and if so is > there a function that does this? Or does the compute function itself > prune the graph? Spt::compute() yields a collection of RouteCmd objects. These are just an abstraction of 'given the shortest paths in this graph, here are some abstract route commands to populate a flat FIB-style forwarding table'. It doesn't perform any operations which would modify the Spt itself, and it doesn't compute any deltas as such. It's entirely up to the developer to compute deltas. The XORP consumers of Spt just repopulate the Spt every time at the moment for this very reason. I did look at Boost's BGL for doing this, and quite frankly, the performance sucked. Have a look at OLSR's RouteManager::recompute_all_routes() method, for another consumer of Spt::compute(). See RouteManager::begin() and RouteManager::end() for a transaction-based approach to deriving deltas from running Dijkstra's algorithm on the graph, and only pushing those to the RIB. When I implemented OLSR last year for XORP, I found and fixed some memory leaks in Spt itself. It could no doubt do with further attention. A potential win for something such as OLSR or DYMO where the topology varies more dynamically than OSPF, and may contain hundreds of nodes, would be to refactor Spt to support Incremental SPT. thanks BMS From vfaion at gmail.com Fri Feb 27 14:17:34 2009 From: vfaion at gmail.com (Victor Faion) Date: Fri, 27 Feb 2009 22:17:34 +0000 Subject: [Xorp-hackers] Computing shortest path trees In-Reply-To: <9a09c93f0902271034j183d7340m41126df7f194bee@mail.gmail.com> References: <38f1dbe80902261507g17ae73dfl9775980a21fed7df@mail.gmail.com> <49A73004.6080101@incunabulum.net> <9a09c93f0902271034j183d7340m41126df7f194bee@mail.gmail.com> Message-ID: <38f1dbe80902271417k3808d39bk32068a1c8f8df34a@mail.gmail.com> On Fri, Feb 27, 2009 at 18:34, Atanu Ghosh wrote: > Hi, > > The Spt interface was designed to support incremental updates. You > should be able to create a single Spt instance and every time the > topology changes apply the deltas then call compute which should > generate just operations required. This requires the caller to track > the topology changes and apply them to the Spt interface. > > Behind the scenes the Spt interface does not perform an incremental > computation but the code is structured to support this. If we see a > performance issue we can add it without changing the interface. > > Currently the code that uses the Spt interface does not use its > incremental feature. For correctness it is simpler to compute the > whole graph and "diff" the results. > > ? ? ?Atanu. > > On Thu, Feb 26, 2009 at 4:12 PM, Bruce Simpson wrote: >> Victor Faion wrote: >> ... >>> ?I don't understand how to use the result given by >>> Spt::compute (a list of RouteCmd). >>> ?Are these operations that >>> must be performed on the whole graph (i.e. everything I've added to >>> the Spt object on which I call the compute function), and if so is >>> there a function that does this? Or does the compute function itself >>> prune the graph? >> >> Spt::compute() yields a collection of RouteCmd objects. These are just >> an abstraction of ?'given the shortest paths in this graph, here are >> some abstract route commands to populate a flat FIB-style forwarding table'. >> It doesn't perform any operations which would modify the Spt itself, and >> it doesn't compute any deltas as such. It's entirely up to the developer >> to compute deltas. >> >> The XORP consumers of Spt just repopulate the Spt every time at the >> moment for this very reason. I did look at Boost's BGL for doing this, >> and quite frankly, the performance sucked. >> >> Have a look at OLSR's RouteManager::recompute_all_routes() method, for >> another consumer of Spt::compute(). See RouteManager::begin() and >> RouteManager::end() for a transaction-based approach to deriving deltas >> from running Dijkstra's algorithm on the graph, and only pushing those >> to the RIB. >> >> When I implemented OLSR last year for XORP, I found and fixed some >> memory leaks in Spt itself. It could no doubt do with further attention. >> A potential win for something such as OLSR or DYMO where the topology >> varies more dynamically than OSPF, and may contain hundreds of nodes, >> would be to refactor Spt to support Incremental SPT. >> >> thanks >> BMS >> >> _______________________________________________ >> Xorp-hackers mailing list >> Xorp-hackers at icir.org >> http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/xorp-hackers >> > Thank you for the help. If I understand correctly, is the Spt class just a container for the shortest path tree as computed by the developer and Spt::compute() just produces a list of RouteCmds which can be used to populate a forwarding table? I thought the deltas would be computed by Spt::dijkstra(). I'm not too worried about the incremental feature, recomputing the whole graph on a topology change is fine. I just don't understand how to use the implementation of Dijksta's algorithm; does it give you a shortest path tree or should I be computing this myself and adding it into my Spt object? Victor