users@grizzly.java.net

Re: JSVC and Grizzly

From: Scott McClure <mccluresc_at_gmail.com>
Date: Thu, 11 Jul 2013 13:29:34 -0400

Hi Alexey/Ryan,

Here is a simple example. Below is the code for TestDaemon. If you compile
that, install jsvc (should be a package on most platforms), and run the
command as follows:

sudo jsvc -cp "PATH_TO_JAKARTKA_COMMONS_JAR:PATH_TO_TEST_DAEMON" -user
SOME_USER -outfile /tmp/out.log -errfile /tmp/err.log TestDaemon

then maybe try telnetting, then:

sudo jsvc -cp "PATH_TO_JAKARTKA_COMMONS_JAR:PATH_TO_TEST_DAEMON" -user
SOME_USER -outfile /tmp/out.log -errfile /tmp/err.log -stop TestDaemon

and then you look at the output of out.log:
[init()]
Binding to 80...
[start()]
Tried to bind to to test port 81 from start(), but failed! - "Permission
denied"
Accepting connections on 80...
Stopping....
exiting thread...
Destroying...

You can see that the server was able to bind to a privileged port in init,
but not in start. What I didnt fully understand is that JSVC appears to be
using Linux capabilities to pull all this off (CAP_NET_BIND_SERVICE).
Therefore, the danger of starting something from init is less than I
thought (I cant open a file owned and only readable by root, for example).
This little experiment has suggested I should probably talk to the JSVC
guys a bit more before you make any changes... Once I hear back more lets
continue this discussion.

Thanks for the really quick response!


 - Scott

---------------------------------------------------------------------------------------

Source of TestDaemon.java:

import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class TestDaemon {

private final ServerSocket socket;
private int port = 80;
 private int testPort = 81;
 private Thread thread = new Thread() {
 @Override
public void run() {
while (true) {
 Socket connection = null;
OutputStream stream = null;
try {
 connection = socket.accept();
stream = connection.getOutputStream();
stream.write("Hello World!\r\n".getBytes());
 } catch (Exception e) {
e.printStackTrace();
} finally {
 try {
if (stream != null)
stream.close();
 if (connection != null)
connection.close();
} catch (Exception e) {
 e.printStackTrace();
}
}
if (Thread.interrupted())
 break;
}
System.out.println("exiting thread...");
 }
};
 public TestDaemon() throws Exception {
 //unbound
socket = new ServerSocket();
}

 public void init(String[] args) throws Exception {
System.out.println("[init()]");
System.out.println("Binding to " + port + "...");
 socket.bind(new InetSocketAddress(port));

}

public void start() throws Exception {
 System.out.println("[start()]");
try {
new ServerSocket(testPort);
 } catch (Exception e) {
System.out.println("Tried to bind to to test port " + testPort + " from
start(), but failed! - \"" + e.getMessage() + "\"");
 }
System.out.println("Accepting connections on " + port + "...");
thread.start();
 }


 public void stop() throws Exception {
 System.out.println("Stopping....");
//close socket first to get out of blocking on accept
 socket.close();
thread.interrupt();
thread.join();

}

public void destroy() {
System.out.println("Destroying...");
 }
}



On Wed, Jul 10, 2013 at 5:34 PM, Oleksiy Stashok <oleksiy.stashok_at_oracle.com
> wrote:

> Hi Scott,
>
> it's not possible at the moment, but if you can provide more details on
> JSVC (based on your question, it should have some programmatic API),
> specifically how you think it should work with Grizzly HttpServer, may be
> some *fake* code, which will demonstrate that (I see you spent some time
> learning Grizzly code, so probably you have some ideas :)). We can try to
> implement this feature and include it into the 2.3.4 release (we're
> planning 2.3.4 release this week).
>
> Thank you.
>
> WBR,
> Alexey.
>
>
> On 10.07.13 13:41, mccluresc_at_gmail.com wrote:
>
>> Hi all,
>>
>> I am trying to use JSVC to bind to a privileged port while root, than
>> run the application as a separate user. This would require that I bind
>> the port separate from starting the server (accepting connections /
>> creating a thread pool, etc)
>>
>> The issue I am facing is in NetworkListener.start() - this call
>> combines the TCPNIOTransport.bind and the TCPNIOTransport.start.
>>
>> Additionally, it appears that TCPNIOTransport.bind also listens on the
>> port as well.
>>
>> Any suggestions on how to separate binding to the port from the rest of
>> the operations? Or alternatively, any suggestions on how to bind to
>> Grizzly a privileged port? Specifically - has anyone used authbind with
>> Grizzly?
>>
>> Thanks!
>> - Scott
>>
>
>