Saturday April 28, 2007
Multicasting with NIO
A long standing issue for many developers is that the java.nio.channels package has lacked support for Internet Protocol (IP) multicasting. In the NIO.2 early review draft specification you will see that we have addressed this issue by adding multicast support to DatagramChannel. Here's a small example that opens a DatagramChannel, binds the channel's socket to a local port, sets the network interface for multicast datagrams sent via the channel, and then joins a multicast group on the same interface:
NetworkInterface interf = NetworkInterface.getByName("eth0");
InetAddress group = InetAddress.getByName("225.0.0.100");
DatagramChannel dc = DatagramChannel.open(ProtocolFamily.INET)
.setOption(SocketOption.SO_REUSEADDR, true)
.bind(new InetSocketAddress(5000))
.setOption(SocketOption.IP_MULTICAST_IF, interf);
MembershipKey key = dc.join(group, interf);
Once the channel has joined the group then it reads or receives multicast datagrams in the same manner that it reads or receives unicast datagrams.
The most significant thing in this example is the static factory method to open the channel specifies a protocol family. In this example, the channel is to an IPv4 socket. In the existing APIs, the protocol family is transparent and all sockets created by the java.net or java.nio.channels packages are either all IPv4 or all IPv6. For IP multicasting it is important that the protocol family corresponds to the address type of the multicast groups that the socket joins; otherwise it is highly operating system specific if the socket can join the group, configure options, or receive multicast datagrams. Legacy java.net.MulticastSocket has suffered greatly from problems in this area. Another interesting thing to point out is that the channel's socket is bound and socket options are configured directly. The awkward and counterintuitive socket adaptor isn't required so it isn't necessary to mix java.net socket APIs when configuring the channel's socket.
In the example, the MembershipKey that is returned by the join method is a token to represent membership of the group. It defines methods to query information about the membership and defines the "drop" method to drop membership of the group.
Developers tracking multicast standards will know that the RFCs in this area have been updated in recent years to add source filtering and this is now supported by almost all modern operating systems. In the NIO.2 draft specification we have included basic support for source filtering. The following code fragment shows a channel joining a multicast group to only receive multicast datagrams sent by a specific IP source address (otherwise known as "include-mode" filtering):
MembershipKey key = dc.join(group, interf, source);
"Exclusive-mode" filtering is where a group is joined to receive all multicast datagrams except those from specific IP source address:
MembershipKey key = dc.join(group, interf).block(source1).block(source2);
So that's a brief introduction to the multicast support that we propose to add to the java.nio.channels package. There's a lot more detail in the draft specification for those interested in this topic.
Posted at 01:46PM Apr 28, 2007 by alanb in Java | Comments[6]
Friday April 27, 2007
Accessing file permissions
One of the many issues addressed by NIO.2 is that the Java SE platform doesn't have a complete set of APIs to access file permissions and other security related file attributes. It's not rare to encounter code that has to resort to using Runtime.exec to execute a command such as chmod(1).
In the NIO.2 early review draft specification you will see that we address the issue of file attributes by organizing related attributes into groups. A FileAttributeView is then defined to provide a read-only or updatable view of the attributes in the group. The specification defines a number of attribute views, of which only BasicFileAttributeView is required to be supported by a file system implementation (BasicFileAttributeView provides access to a small set of attributes such as file size and last modified time - essentially the basic attributes that are common to many file systems).
Aside from BasicFileAttributeView, a file system implementation can support other file attribute views. The specification defines PosixFileAttributeView for access to file attribtues commonly found on platforms that implement the POSIX family of standards. Here's a small example that uses an instance of this attribute view to print the owners and permissions of a file called "foo". It then changes the permissions to deny others access to the file:
PosixFileAttributeView view = PathReference.from("foo")
.newFileAttributeView(PosixFileAttributeView.class);
// bulk read
PosixFileAttributes attrs = view.readAttributes();
int perms = attrs.getPermissions();
// prints "rw-r--r-- alice bandits"
System.out.format("%s\t%s\t%s%n",
PosixFilePermission.toString(perms),
attrs.getOwner(),
attrs.getGroup());
// deny others
perms &= ~OTHERS_READ & ~OTHERS_WRITE & ~OTHERS_EXECUTE;
view.updatePermissions(perms);
The only code that might need explanation here is the code that obtains an instance of PosixFileAttributeView. FileAttributeViews are selected by type-token and this code selects an instance of PosixFileAttributeView that is bound to the file "foo".
The comment hints that foo is owned by the "bandits" group and we can fix this by changing the group:
UserPrincipal cops = view.lookupPrincipalByGroupName("cops");
view.updateOwners(null, cops);
The other part to file permissions is that sometimes you need to create a file with initial permissions (umask applies of course). Here's an example that creates a new file called "securefile" with initial permissions, opening the file for random access:
PathReference file = PathReference.from("securefile");
PosixFileAttributeView view = ...
Attribute<Integer> attr = view.newPermissionsAttribute()
.setValue(OWNER_READ | OWNER_WRITE | GROUP_READ | GROUP_WRITE);
SeekableByteChannel sbc = file.newSeekableByteChannel(CREATE_NEW | READWRITE, attr);
So that's a brief tour of PosixFileAttributeView. The other file attribute view in the specification that provides access to security related attributes is AclFileAttributView. This provides access to Access Control Lists (ACLs) based on the NFSv4 ACL model. That will be interesting to those on file systems that support ACLs. When I get time I'll write up a few words on how this attribute view is used.
Posted at 07:52AM Apr 27, 2007 by alanb in Java | Comments[2]