diff --git a/core/dhcp.cc b/core/dhcp.cc index f39cc2085186a36b6e45f29b0775037690fe0713..77b5e6b2771dde6ff14713b5fac8e65f60be6ae9 100644 --- a/core/dhcp.cc +++ b/core/dhcp.cc @@ -40,10 +40,10 @@ extern "C" int dhcp_hook_rx(struct mbuf* m) return 1; } -extern "C" void dhcp_start() +void dhcp_start(bool wait) { // Initialize the global DHCP worker - net_dhcp_worker.init(); + net_dhcp_worker.init(wait); } namespace dhcp { @@ -503,7 +503,7 @@ namespace dhcp { /////////////////////////////////////////////////////////////////////////// dhcp_worker::dhcp_worker() - : _dhcp_thread(nullptr) + : _dhcp_thread(nullptr), _have_ip(false), _waiter(nullptr) { } @@ -517,7 +517,7 @@ namespace dhcp { // FIXME: free packets and states } - void dhcp_worker::init() + void dhcp_worker::init(bool wait) { struct ifnet *ifp = nullptr; @@ -542,6 +542,12 @@ namespace dhcp { // Create the worker thread _dhcp_thread = new sched::thread([&] { dhcp_worker_fn(); }); _dhcp_thread->start(); + + if (wait) { + dhcp_i("Waiting for IP..."); + _waiter = sched::thread::current(); + sched::thread::wait_until([&]{ return _have_ip; }); + } } void dhcp_worker::dhcp_worker_fn() @@ -565,6 +571,14 @@ namespace dhcp { } it->second->process_packet(m); + + // Check if we got an ip + if (it->second->is_acknowledged()) { + _have_ip = true; + if (_waiter) { + _waiter->wake(); + } + } } } diff --git a/include/dhcp.hh b/include/dhcp.hh index 6e1da5f192245ebb6a9220afc6ba54c76cc97ecf..cf5797497a82cb4c86a0e550b6be37a9ef837e08 100644 --- a/include/dhcp.hh +++ b/include/dhcp.hh @@ -11,6 +11,8 @@ #include <osv/mutex.h> #include <osv/debug.h> +extern "C" void dhcp_start(bool wait); + namespace dhcp { #define dhcp_tag "dhcp" @@ -195,6 +197,8 @@ namespace dhcp { void state_discover(dhcp_mbuf &dm); void state_request(dhcp_mbuf &dm); + bool is_acknowledged() { return (_state == DHCP_ACKNOWLEDGE); } + private: state _state; struct ifnet* _ifp; @@ -212,7 +216,7 @@ namespace dhcp { ~dhcp_worker(); // Initializing a state per interface, sends discover packets - void init(); + void init(bool wait); void dhcp_worker_fn(); void queue_packet(struct mbuf* m); @@ -223,6 +227,10 @@ namespace dhcp { mutex _lock; std::list<struct mbuf*> _rx_packets; std::map<struct ifnet*, dhcp_interface_state*> _universe; + + // Wait for IP + bool _have_ip; + sched::thread * _waiter; }; } // namespace dhcp diff --git a/java/jni/networking.cc b/java/jni/networking.cc index a695edbf000c26bf068a3f27e4f4ee707d6fa5d3..3e05147bc2658d43875032ca96207a6a3a184283 100644 --- a/java/jni/networking.cc +++ b/java/jni/networking.cc @@ -78,7 +78,7 @@ extern "C" JNIEXPORT void JNICALL Java_com_cloudius_net_Route_add_1default env->ReleaseStringUTFChars(gw, gw_c); } -extern "C" void dhcp_start(); +extern "C" void dhcp_start(bool wait); /* * Class: com_cloudius_net_DHCP @@ -88,6 +88,6 @@ extern "C" void dhcp_start(); extern "C" JNIEXPORT void JNICALL Java_com_cloudius_net_DHCP_dhcp_1start (JNIEnv *, jclass) { - dhcp_start(); + dhcp_start(true); }