Networking and Security • 1:03:52
Mac OS X offers the most powerful and flexible networking technology in the industry. Learn about networking APIs and protocols such as IPsec, IPv6, and PPPoE.
Speaker: Vincent Lubet
Unlisted on Apple Developer site
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
Good morning. My name is Tom Weier. I'm the Network and Communications Technology Manager in Developer Relations. I want to welcome you to Session 300. This is Networking Overview. As you heard yesterday, the networking in Mac OS X is pretty much the core of a variety of services that are layered on top of it. It's an extremely high-performance subsystem. With that, I'd like to introduce the manager of Mac OS X CoreOS Networking, Vincent Lubet.
Thank you. So here is what we are going to go through today. So obviously an overview of the different components of Mac OS X networking. We're going to talk also a great deal about APIs because they are, I guess some of you are more familiar with the Mac OS, classic Mac OS networking and we're going to talk more about some of the new stuff that you will discover on Mac OS X.
Vincent Lubet A number of hints and tips, especially for developers who come from Mac OS 9. The architecture of the system is quite different and there are many things that work well on Mac OS 9 that don't work or have severe impact on performance, for example. And we'll go over that. And we'll talk also briefly about future directions.
So maybe you've already seen this graph, this picture. So the core of the networking lies in the kernel. Its networking really is a subsystem of the BSD kernel. The Darwin kernel, if you will, has three main components. The BSD kernel, which provides a lot of the APIs for the core services and the upper layers. We have the I/O Kit, which provides access to the hardware. For example, that's where you will find the Ethernet drivers in the I/O Kit. And the Mac kernel is the basic core of the kernel that provides the basic services, like scheduling, memory management, and things like that.
So some of the features of Mac OS X. It comes with TCP and AppleTalk protocol stacks. It comes with also links layers, so PPP built in with serial support and PPPoE, especially important today for access DSL. And other type of link layers, of course, is Ethernet. So it's come built in with Ethernet support. Another important feature of Mac OS X is the dynamic configuration. And that's a core of the ease of use we want to bring to a Unix-based system.
Some of the problems that people see in BSD or Unix-like implementation is that people have to type a lot of commands. It's command-line oriented. With Mac OS X, we went away with that. It's dynamic. You don't need to restart to change the configuration. That's very important. Another thing, it also provides for an extensible architecture. So again, it ties into the ease of use, especially the kernel. And we have the ability to add functionality to the kernel without having to recompile, which is the kernel, which is usually the kind of the model that you have on BSD or many BSD systems.
So the ongoing goals we set for ourselves for the networking experience in Mac OS X, of course, is ease of use. Something that users are being, you know, when they come from the classic Mac OS, they really often don't think about configuring the network. And that's one of our goals also for Mac OS X, performance. And I think that because of the... Underlying networking stack, I think that we're pretty well off already today. So, better extensibility and standard compliance, of course, which means TCP/IP and we'll see that we have plans to get new protocols.
So it's best, the kernel especially part is based on FreeBSD 2.0. So it's a robust and proven implementation. It's used by Typically, it's used by large companies for servers, which shows that it can stand a lot of abuse and heavy loads. It has a popular API, which is the Sockets API. One of the important points is that it's easy to port Unix-like applications. There's a lot of code out there, and you can reuse available code and even learn by example by looking at open source. Some various open source implementations.
So we brought some enhancement to the 3BSD implementations. First of all, the kernel is multithreaded and MPCV. Multithreaded means that we can run-- We can take advantage, for example, of multiprocessor architecture that has That's a totally different model from Mac OS 9, especially for the networking. So we'll see that some of the assumptions that you could make on Mac OS 9 are no more true on 10. And it's not only for the kernel pieces, but also it has impact on the applications. So we have tuned also the network buffer allocation so that on the typical client system, we don't use too much way of memory, which is a very critical resource.
But of course, the buffer allocation can stretch and grow. For example, if you have your configuration like a server or something like that. So part of the announcement. We have a lot of information about the network buffer allocation. So part of the announcement. We bought to the FreeBSD kernel is this extensibility. That means that you don't need to recompile the kernel. The session in the session 304 will go in more detail and it's session 304. It's just after this one in room J, if I remember well, which is the opposite end.
Dynamic configuration is very important for us. That means that you don't need to restart when you reconfigure your system. But we went even further than that. It means that as the kernel supports multi-link, multi-homing, out-of-the-box, We came up with this idea of automatic configuration. So we don't use multi-homing really in the sense, by default, on a client system. We don't use multi-homing really to do routing or things like that. But one of the important features we have, for example, is that if you have the classic example we come up with, it's that you can have several network interfaces active at the same time.
And the typical use, you come to your office and you plug in the ethernet, the ethernet becomes your main interface. If you have airport and you unplug the ethernet cable, the airport interface will pick up automatically. And that's without any user interaction. So that's very, very important for us. I think that that's something that really shows the benefit of multi-homing. And this afternoon, there will be the session 303 that's going to talk a lot more about network configuration and mobility.
[Transcript missing]
So, I mean, the important thing is that Classic and Darwin share the same IP address. It's, again, something that Without that, it would be almost impossible if Classic, for example, had to add a separate address. It would become a nightmare. You couldn't, for example, usually connect to your ISP because usually you have only one address assigned by the server.
Mac OS X So that means that the TCP and UDP port space are shared between those two environments. And something we've done also, we took a great deal of effort to make sure that when you ping a system, we reply with only one ICMP reply. That was something that was brought to our attention a few years ago, one of the sessions.
So we took your feedback and made sure it's right. In Classic, there's no user configuration. The configuration of the TCP/IP in OpenTransport in Classic is done automatically behind the scene. So the TCP/IP control panel is read-only. One important thing to note is that Classic and Darwin do not share the Apple Talk address. And usually, that's not really a problem.
So one of the important core of the classic networking implementation is this global UDP and TCP port space. So basically how it works is that, for example, when a classic application does bind to grab a port, it does some special call into Darwin. And the same for Mac OS applications. When they bind, they call into this global port space. And it's in a way similar to NAT in some sense. But the thing is that the clients are on the same machine. It's not really NAT, but it's similar to NAT.
And of course, we have this component, kernel extension, maybe you've seen on your system, which is called shared IP, which handles, it's a filter really at the lower level of the stack that handles incoming and outgoing traffic. And for incoming packet, it calls into this global port space to see to which end to send the packet.
So now we're going to talk a little bit more about the APIs for the different application environments. I forgot to put Java there, but of course we support Java. But we think that for Mac OS X, really the primary, I mean, If you use classic, you don't have to do anything. If your application, if your plan is to continue to use classic, it works, you know, 100% fidelity. So going to talk more about Carbon and Cocoa.
And so we We see three different types of APIs in Mac OS X and we're going through all of them. The first kind are the URL-oriented APIs, easy to use. The other ones are the Open Transport APIs, really for Carbon. And the last one is the BSD Sockets API, which is the native APIs for networking on Mac OS X.
The URL-oriented APIs are for, what we say, norm-centric applications mainly. That means that one of the great benefits of those APIs is that it's easy to download. some URL so basically you you let's say you have a URL you pass it to the API and that's going to download it locally on the system and tells you when it's done so you don't have to know about the protocol it themselves you don't have to deal with ftp the details of ftp or HTTP it's all done for you and they are basically so three sets I mean three three kinds of API says an NSURL API for Cocoa application URL access for Carbon and classic of course and a new one that's kind of bridging those two application development that are the CFURL access for can be used both by Carbon and Cocoa application and you will learn more about about those if you go to the session 311. So I won't go into any more details, especially because I don't know them very well.
[Transcript missing]
The OT implementation of Mac OS X is layered on top of sockets. It's a framework, part of the core services framework. It uses threads to emulate asynchronous mode, which means also that Implementing OpenTransport can also take advantage of multiprocessors. It can do some of the background work that can be done on another processor while your application is accessing some APIs from another processor. Something very important to note is that OpenTransport 10 is layered on top of Socket. That means that you're going to incur overhead compared to similar code that uses straight sockets. It really depends. Roughly it's 5-10% overhead.
Depending on what the code is doing, it can be far worse. Sometimes it can be even better because sometimes you can take advantage of multiprocessors. You can take advantage of the fact that some of the worker threads in the background run on another CPU. But for a typical application, 10% is common. So here it starts to go into more details, but important gotchas.
When we designed Carbon, we didn't think that Carbon was just a compatibility layer. So the goal was not to be just compatible. We were thinking that developers bringing their application to Mac OS X and already moving the application from just the Mac OS toolbox to Carbon had already to... sometimes it's a big step. And we're not always thinking that, you know, then going the further steps, which would be to use Cocoa, would be always easy. So we were thinking that it was very important to provide for performance. The Carbon implementation on Mac OS X, the OT framework, was meant to perform well.
Which means that... So there's a flip side to that. It's that it's not a high-fidelity implementation. Especially because of the preemptive nature of Mac OS X and the multi-threading. So, for example, in Carbon, there's no interrupt level. A part of the... of Open Transport is using... notifiers and default tasks that on classic run in the background at the software interrupt level. That does not really exist on Mac OS X. You only have threads.
There's no interrupt level. And one of the things that we did is that we... I really decided that it was worth for the performance implication that, for example, a notifier run just as another thread. A notifier has no higher priority, if you want, than the main event loop or other cooperative threads.
The only solution that we could have done to work around this problem was to really have notifier being serialized with cooperative threads. That means notifiers would be just another cooperative thread. That would make a very easy port of application, but the performance would greatly suffer. Because you don't want the networking activity to be dependent on, for example, some UI.
Or some other lengthy task. So that means that it's very, very important when porting your application that you think about protecting your data. Making sure that if you're using asynchronous mode and notifiers, you have to be sure that you use the right primitive to ensure you to serialize the access from the cooperative threads and the notifier.
Luckily, in Open Transport API, there are already a bunch of primitives that can help that. The main ones are really OTEnterNotifier and OTLeaveNotifier that define really critical sections. When you call OTEnterNotifier from your main event, for example, that prevents the notifier to run until you call OTLeaveNotifier. That's really the most useful of the...
[Transcript missing]
For example, maybe from your notifier you can just set a flag to signal the main event loop to do something, that something happened at the networking. That's fine to use with OT atomic operations. And finally also... One primitive I really like are the LIFO. They are pretty powerful to handle a set of queries and queues. They are sometimes a little bit obscure, but can be very, very useful.
So other gotchas, if you want, or at least this one, are the recommendations. So if you bring your open transport application, What are the best ways to use Open Transport APIs? You're certainly aware there's a new kind of library that has been developed by DTS, Quinn especially, which was OTMP that provides some kind of framework or a library that allows to use open transport from MP threads. The only downside is that it's not available on Mac OS 8.
But otherwise, it's very powerful and it runs great on both 9 and 10. Otherwise, especially for Mac OS X, it's very important not to poll. The mod, if you're using synchronous endpoint, you should use a synchronous blocking mod with sync_idol event so that your cooperative threads can be called back.
And lastly, the asynchronous mode with Notifier is certainly the mode, the open transport mode, that is the most efficient. So if your application relies heavily on networking and gets a lot of data, or is a server kind of application, certainly it's... It's worth the effort of using asynchronous mode. And it's available. So if you're doing that online, it will run just great on 10, provided that you make sure that you serialize the access to the data that's shared between cooperative rights and the notifier.
So I will repeat that several times here. But what's important on Mac OS X is not to poll. If some of you went to the Darwin Overview yesterday, there was a demonstration of a simple Carbon application that was using different well-known pitfalls. One of them is to use, for example, wait next event with a timeout of value of 0.
And you could see with the tools that are available from the BSD layers, is that you could see that the CPU is used as 100%. If it's the only application and the only thread really that runs, you see, oh, what's the point? We will see that also it has also some implication about, for example, when the system can go to sleep, light sleep like those and now. And it uses more power.
It's important for power boost, for example, and battery life. Another thing is that there's open transport as this call called OT idle that's in the documentation, we say, shouldn't be used. And really, on 10, if you use OT idle in some way to-- you have a tight loop and you say, OK, I will be good. I will call OT idle. That's going to add a great deal of latency.
We took really great care on 10 to make it very, very-- Inefficient. So it will slow down your application and it will block it. So if you want to block, for example, if it's a way for you to block, it will block your application for a while and your thread at least for a while.
[Transcript missing]
The main reason for the surprise is that flow control is much more common on Mac OS X. The reason is mainly because on Mac OS X you have a split address space, so data has to be copied from the user space to the kernel. In the kernel, memory is very expensive. So it's a resource that we don't want to over-- to be abused because it impacts all the different subsystems in the kernel. Everything is shared.
So by default, the-- The socket buffer size, which are equivalent to the send buff and the receive buff in the streams, are really, on Mac OS 9, they are not really enforced. And on Mac OS X, the equivalent are strictly enforced. That means that if you set a socket buffer size of 4K, that's just the amount of data that you can copy at once.
That means that if you send data, you will, for example, an OTCend call will return much more frequently the OKOTflow error. And your application should be ready to handle that. A way to work around that is to use these XTI options and both, but it has an impact on the overall system.
Also, differences from the implementation of the Open Transport Framework content is that concern the timer and default task. So, again, there are In a way, it's to be performance sensitive. They are not implemented with the default task manager and the time manager that are provided by the Carbon the Carbon layer. And instead, they are serialized with the notifier. And we've done that because we noticed that many applications, that's what is important. Why they would use the Open Transport time manager and default task manager.
It's not because they were better than the time manager or the default task manager. It's just because they were relying on the fact that, online, they are serialized also with the notifier callbacks. So that's-- is the main reason, but it might have some subtle implications for some applications. So you should review that. Another thing is that for AppleTalk, Carbon is the only API that allows to access AppleTalk. It supports only a subset of AppleTalk. It supports those protocols, DDP, ZIP, and NBP.
We know that it's not for all the developers, it's not enough, but that's what we were able to do. And one of the things is that we got requests from, why for example, NBP is that many applications, many developers still use NBP to register services and to provide maybe for copy protection and things like that. And frankly, that was relatively easy to do, so that's why we've done. Providing, supporting higher level, we got a lot of requests, I mean a lot of requests, we got many requests to support higher level protocols and we still don't have that.
So now I'm going to talk briefly about the Socket API. That's the native API for Mac OS X. That means that that's the one where you're the closest to the system. And if you can, I would encourage you to use this API. One of the benefits is that there's a lot of publicly available code out there, open source. There's many codes to learn from. There's also a lot of books. One of my favorites is the Unix Network Programming by Richard Stevens. It's really kind of the Bible.
It's a great book. And something very important, especially if you're porting your application from Mac OS 9, is that Because you have sockets in Mac OS X, maybe you should also review your code and making sure that if you have If you have a layer that's sockets like layer in your application, maybe it would be time to get rid of it. You know, instead of having this socket like emulation layer on top of open transport, that's called open transport. If you go just through directly open transport, you will get you will see a lot of performance benefit.
And for example, one of the requests that we got from developers the past years were to include, to add socket API, socket support into open transport on Mac OS 9. So it's not going to happen, but I mean, now you have to, on Mac OS X, you have the socket API available.
So I'm going to talk briefly for the people who know the Open Transport API. I'm going to show that it's very easy. There's almost one-to-one correspondence between the Open Transport core and the Socket's core. So for example, for endpoints, the one that you use for your TCP, UDP-- So, they are called endpoint providers in the Open Transport documentation and they are sockets file descriptor in BSD.
And usually, so to make an active connection, like a client would do, what you do, you call OT bind with a queue length of zero and then you call OT connect to the distant site. And in BSD, the bind is really optional. You don't need to call bind, but you can bind to get an ephemeral port and then you can just call connect. Very simple. For passive connection, like for servers, With OpenTransport, you bind with a QLens greater than zero.
On 10, the queue length is called the back load and it's found in the listen call. So that's where there's a little mismatch. But usually those operations are done in series so it's really easy to do. So on 10 you call otlisten to set the endpoint in listening mode and when the incoming connection comes, you're notified and you call otxm.
On 10, you call otxm. BSD sockets, it's roughly the same except the accept call. So the backlog, the queue length become the backlog in the listen call. And accept returns a file descriptor. With otxm you pass the listener endpoint and the acceptor endpoint. But it's very, very similar. Sending and receiving data.
So for example, depending on the... For example, with OpenTransport, depending on the type of endpoint, whether it's connection oriented or datagram oriented, you have different APIs to send and receive data. So otxm would be for TCP, for example, and otxm-u-data would be for UDP to send datagrams. On BSD, it's a little bit different. There's no real strong affinity between the type of endpoint and the type of... the type of socket.
[Transcript missing]
So disconnecting and closing, so that's also on Open Transport, you have the send disconnect that for TCP is going to send a reset. If you have to do that on BSD, you use the linger option, specifying abort. For an orderly disconnect, you would send, if you're a client, depending on your protocol, the order may depend. But usually you call send orderly disconnect and then receive orderly disconnect.
If you want to wait until notification that the other side is disconnected. For BSD, pretty much the same. It's called shutdown write and shutdown read. And then finally, you call otcloseprovider when you're done with your endpoint. And when you're done with socket file descriptor, you just call close.
In many cases, if you see a simple sample code from Unix, you see that they don't call close, but it's because file descriptors are closed automatically when the process exits. Similar to what happens also on OpenTransport, but close is the one. So again, so if you bring an application from Open Transport you want to use Socket, you will have certainly to do some name to address resolution to use DNS. So the APIs we have in BSD are called get host by name for name to address resolution.
and getOSbyAddress adder for the reverse. One important thing to note is that those are non-reentrant APIs, so that's a well-known limitation of those APIs. That means that they return a pointer. So the information that the resolver library gets is-- So those APIs return a pointer to a structure that is in the library.
So that's why if you have two threads calling those APIs at once, you may end up with inconsistent results. And another limitation or things to know is that those are blocking codes, and they are not cancelable, quite different from maybe what you can use with OpenTransport, where you could cancel access to APIs to the internet service provider. That's not possible with BSD.
And which means also is that Open Transport on 10, we have similar limitations. I mean, we try to work around them, but...
[Transcript missing]
Here we're going to talk about the different ways to use the different tasking models. So that's the terminology that is used inside Macintosh networking.
If you move your application, you can use really the... So if you're using synchronous blocking endpoints in cooperative threads, for example, or MP task, it's very simple to convert that code to use the Socket's equivalent. We saw there's almost one-to-one matching. There are a few things to know, but it's very simple.
If you're using asynchronous endpoint, there's no callback in BSD, so you don't have notifiers. But still, what you do usually is that you use the select system call that allows you to multiplex, to wait for events on several endpoints at once. So usually you have a thread blocked on the select call that blocks on several endpoints. So it's not callback, it's more multiplexing, but it achieves the same results. For example, the Open Transport framework is using that to wait for events. And when the select call returns, that's what's going to trigger the call to the notifier.
So there are three kinds of events that the select call can handle. Read event, if a socket file descriptor is ready for read, means data is available. Write, so if you are in a situation of flow control, and you can put the file descriptor in the right file descriptor set, there are sets.
And when the flow control situation is lifted, you're going to select "will wake up" and the bit will be set for that file descriptor saying "now you can send data". And finally, exception is used for out-of-band data. That's how you can be, if your protocol is using TCP expedited data, you will be notified that expedited data is available if this bit is set.
The Stephen's book has a great deal of explanation. Vincent Lubet One important thing to know is that the BSD implementation of SELECT is used by many Unix derivatives. But with BSD-like systems, the SELECT handles non-blocking connect. So when you're making a connection, you don't have to block your thread until the connection is complete. You can just set the file descriptor to non-blocking.
And the SELECT will wake up when the connection is complete. That is not obvious because not all the Unix support that, but Darwin, we have that, and it's very useful. And again, the Open Transport Framework is using that. That means that while OT Connect is non-blocking in Carbon.
So now we're going to go through another list of the hints and the tips. Especially if you are performance conscious, and we would like you to be performance conscious, is that The most important thing that's going to kill performance on Mac OS X is polling. Polling makes use of 100% of the CPU.
So if you run the top command from a shell script, you can see if your process application is using 100% of the CPU, it means that it's polling. And it's very common to poll. So there are many different ways to poll. For example, using wait_next_event with a timeout of 0 is a way to poll because the thread is going to run constantly. But many, many times when you're doing I/O, you tend to poll. And something that you could get away with on Mac OS, the classic Mac OS, is not going to work well on 10. So it hurts other processors because it steals CPU cycle away.
And it uses more power. So we are energy conscious in California. So it's not only because it's going raw power, but also it's very important for notebooks. Many of you have because if you're blocking one of the, and if there's no activity in the CPU, a thread is going to run in the kernel that's the idle thread. And that's the one that's going to trigger the conservation mode of the CPU.
So the power piece is going to put the chip in doze or nap mode according to the level of inactivity. So that's not the real sleep, you know, that's not going to trigger the sleep like the sleep command. But still it's going to affect the battery life of notebooks. So the model for Mac OS X is blocking. So you block your threads and wait for an event.
Use blocking threads. If you use threads, what we've seen sometimes is that people tend to still use, for example, cooperative threads or MP threads, but they still have some polling loop. So they are just going, before calling, instead of blocking in an OT receive, they are going to have a little while loop there to check for some flag. And that's not going to do any good because if you're putting in an MP thread or in a regular P thread, you're going to use 100% of the CPU.
[Transcript missing]
Maybe it won't be good to use many many threads. Threads is a resource. It has a stack, it has a scheduling, it gets into the scheduler. So instead, if for your application you are using many many endpoints, like maybe a server, you should multiplex. So you should use the select routine if you are using BSD, and otherwise use notifier for Carbon.
So again, so buffer size. And that really applies both for Carbon and sockets. That's an important, very important aspect of the performance for networking application on Mac OS X. So there are-- For example, we saw that some Carbon applications that have been imported have one or the other of the Use buffer sizes that are wrong in opposite ends. Some of them are using too small buffers.
So the pathological case is to call OT receive for one character at a time. That's going to-- you're going to have a lot of switch between user space and the kernel. And that's an expensive operation. And so instead, you should-- and frankly, if you're doing something like a telnet-like and at very, very low throughput, you can get away with. But usually-- but that would be really the only-- and it would because it simplifies maybe your state machine.
But otherwise, I would really encourage you to use larger buffers. On the other end, if you pass too large buffers, you're going-- so not only are you going to get in flow control situation that are sometimes difficult to handle, but you're also going to start the VM for buffers.
So it's-- so you should pay attention to that. You should pay attention not only to the size of the buffer you pass to the send and receive codes, but also to get the right-- I mean, the appropriate size for the socket buffer, the size of the buffer that the kernel is going to use. So the question is, so what is the correct buffer size? Unfortunately, there's not-- Thank you, Vincent.
I think that was a very simple reply to that question. It really depends on many factors. It depends on the bandwidth to the destination. If your application is It's really going to be mainly used on the LAN. I would recommend that you increase, for example, the socket buffer size.
Because, for example, over gigabit, you have a lot of bandwidth and using large buffer size is going to to decrease the number of context switches and overall the Ethernet driver will be able to pump the data very, very fast. But if you're using large buffer size over a PPP link, for example, if your application, maybe you think it's going to be used over the Internet by a client using PPP, using two large socket buffers means that you're going to just have data sitting there in the kernel for no good use. So it's going to be a very, very difficult task. To steal some wired memory away from maybe other processes or application. And also it depends on the protocol.
So For bulk data transfer, normally, of course, larger is better. But for transaction, maybe you're more looking at responsiveness. And having too large buffers may hurt the interactivity there. It depends also on the number of clients. So if you're a server, again, and if you're serving a very large number of clients, I would recommend that you don't use too large second buffers.
Because, again, if you have many, many clients using large buffer size, you're going to increase the amount of wired memory use. And overall, there will be more paging and less-- and in the kernel, less wired memory to be used maybe for the drivers or other layers of the system.
So the important thing is that you have to analyze the need. It's not always easy. We all recognize that. But you have to analyze the need specific to your application. And still, there is many application what they do. For example, they download files. And they're going to set the file for a cache or on the disk.
Also, we've seen that with many networking applications that kind of feel sluggish on Mac OS X. And it's not because they don't use the right parameter on the networking side, but it's just because they write in too small chunks, too disk. And typically, we recommend that here it's also, I guess, if you talk to the file system guys, they will tell you, oh, it's more complicated than that. But a good rule of thumb is to use something like 32K to buffer in your application, 32K before calling the write to write to disk.
Also, an important aspect of Mac OS X is that it's multi-homing. So it has several implications. And it's kind of an FAQ from the Carbon list. The system does not have a single IP address. The presence of an IP address doesn't mean that you are able to connect to the internet or not.
It may be that TCP/IPs IP addresses change over time, so do not cache IP addresses over a long period of time. For example, for FTP clients, your application will be up most of the time, but the IP address may change. Don't cache the IP address, just call the available API, get_sock_name for BSD or get_prot_address for OpenTransport Carbon.
Multihoming means that if you bind to a specific address, you will be able to send and receive data only for that address. Certainly in a multihoming environment, many server configurations on purpose have several interfaces active at a time. For example, MultiPort, Ethernet, and Carb. They all have a different IP address.
And certainly you don't want to limit access to just one interface. So servers should bind to any IP address. They are both available, constant, in the BSD and Carbon OpenTransport. And usually for clients, they really should bind to nil. They are very, very little. There are a few exceptions.
It may depend on the protocol you're relying on. But usually the typical call for OpenTransport is you call otbind and it passes nil. For sockets, you just don't have to call bind. You can just write the connect. After you create your socket, you can just call connect. The connect call will automatically pick up an ephemeral port if you use TCP, IP, or UDP.
[Transcript missing]
So the idea is not to, if you're downloading and if you want to provide some feedback to the user about maybe the amount of data that is downloaded all the time, do not update the HI every time you get a packet. That's much too fast. Usually it's much too fast. So maybe it's okay, you know, if you only over PPP you will get data at a relatively low rate.
But if you start to run your application on a LAN with Ethernet, you will see that your application just spends time updating the amount of data or running a little icon or running a dog or something like that. So it's very costly. So instead you should use reasonable delays that are more based on the user perception. If you see numbers flashing over your eyes, it's not going to bring... It's not going to bring a lot of information.
What's a reasonable delay? I'm not an expert in human universe design, but if I remember well, something like something visible, you know, something at a rate higher than 50 or 60 hertz is too fast. So, and if you think of it, you know, updating an account, you know, at something higher than maybe two or three times a second is too much. And the same for the sliders, you know, they can, they may be more smoother if you choose, if you pass the rate of the HCI, of the update.
The list. So if you came the previous year, we had, especially for Mac OS, the classic Mac OS networking, we had a long list of all the things that we were working on. And here in Mac OS X, so we were starting the list from scratch. That means that we have an implementation, a product already out, but we have already some ideas, we got some feedback, and there are stuff we would like to do on our own. But really what we need and what we'd like to hear from you and from our user is the things we should add or improve. So the list is currently blank, and certainly next year it will be filled with a lot of neat stuff.
I'm going to briefly talk about the future, so what we have in the plan. If you came in the last two years and you've heard us talking about IPv6 and IPsec, and they are still in our plan, If you're familiar with Darwin, you can see that we have the Kame implementation of IPv6 and IPsec.
So that's what we're using. If you... You will see that it's... It's relatively easy. Last year we had a package that you could install on DP2, if I remember well, where you could install IPv6 and IPsec. But building a Darwin kernel became so easy that maybe that's, if you're really interested, that's something that you can tackle. What we're missing there is really the higher level. So the library, the HI is not there.
So that's one of the main reasons why we were not able to put that in Mac OS X 1.0. Another thing that we're working on is ZeroConf. So ZeroConf is an IETF... RFC Maybe Stuart That allows, provides to the TCP/IP some of the great benefits of Apple Talk which are automatic configuration.
It means that once we have zero conf in Mac OS X, you will be able to plug to PC and they will acquire address automatically and you will be able to exchange data with your peer without any interaction. We are also still, one of the ongoing goals is performance tuning. So we are just going to continue to work on that.
Better extensibility and also something very important is the replacement for the network setup API. And if you come to... to this afternoon session, 3:03, we will talk about that. Which platform do you appear in? It's called... So the session maybe is the next slide. So OK. It's called Network Configuration and Mobility.
So let me back up. We'll come back here. So we have a number of additional resources available on the web. So of course, the developer page for Mac OS X. A lot of information. For classic networking and Carbon, there's a lot of information in the open transport page. So if you're carbonizing, you will see a lot of link. It would be a good starting point to get a link of information. So, Darwin is a good source of information.
And there's a... An active community there and if you subscribe to the development list you will see that there's a lot of interest from developers, a lot of people contribute to Darwin. And finally because of the roots of the networking stacks, also in the FreeBSD site you will see a lot of information that maybe if you need to use some tools, some mind page or some how-tos, how to's, you will see a lot of information on the FreeBSD site.
Finally, the related sessions. So 300, that's this session. Networking in the Kernel, that's a session that we're going to have just after this in the room J2, the opposite side of the building. Network Configuration and Mobility, that's a very interesting session. And on Thursday at 10:30 we're going to have the feedback forum.
So for all the questions we couldn't answer today in the Q&A, please come back and talk to us there. Web Enabling Your Applications for high-level URL-oriented APIs Thursday at 5:00 pm Sound on Networking for Games J2 Friday If you are a game developer, you should attend this session. That's a wrap-up of this session.