opennap v0.20 (ALPHA)
the open source (TM) napster server
=====================
March 2, 2000

http://opennap.sourceforge.net
IRC: #opennap on irc.openprojects.net
Email: opennap-dev@lists.sourceforge.net

opennap is an Open Source(TM) server implementation of the popular
Napster protocol.  It is written in ANSI C and was designed to run on Unix
platforms and uses a MySQL (www.mysql.org) server to handle the search
requests.  So far this server has only been tested on:
	* Red Hat Linux 6.1 (i686) running MySQL 3.23.32
	* Red Hat Linux 6.0 (Alpha) running MySQL 3.23.32
	* BSDI 4.1
	* Windows 2000 (MS VC++)
Minimal porting should be required for compilation on other Unix variants
(if you do a port, please send patches to drscholl@users.sourceforge.net)

Since Napster is not an open specification, much of the internals of the
servers are specific to this implementation.  In particular, I don't expect
that this server will interoperate with the official Napster servers once they
are linked together.  Given that I can't run tcpdump between those servers,
I can't see how they are communicating.  I'm hoping that with the proliferation
of servers outside of napster.com, they might be willing to open up their
specification to make sure all the clients can interoperate.  However, this
server should be compliant with the several currently available Unix Napster
clients.

Main differences from the official napster servers:
* servers can be linked together
* normal users can create channels
* source code is freely available

What's included?
* opennap server
* metaserver for directing clients to server groups
* protocol specification
* SOURCE CODE!

There is also a mailing list opennap-admin@lists.sourceforge.net for people
running live servers to share information not directly related to the
development of the server.

* For a description of the napster protocol, please see the file 'napster.txt'
  included with this distribution.

* INSTALLATION

  1.  build and install mysqld plus the client libraries (libmysqlclient.a)
  2.  build and install opennap
  3.  create a user and database for opennap to use

	# mysql -u root -p < create_db.sql
	Enter password:

  4.  change the default password for the mp3 user

  	mysqladmin -u mp3 -p password 'newpass'

  5.  create at least one elite (server operator) nick to use on the server

	# mysql -u mp3 -p
        Enter password:

	mysql> use mp3;
	mysql> insert into accounts values('nick','pass','elite','email@here.com', 0, 0);
	mysql> quit;

      where 'nick' is the nick you want to use, 'pass' is the password for
      the nick.

  6.  edit the opennap config file and change at least the `db_pass' line to
      correspond to the password you selected above in step #4.  By default,
      the config file is located in /usr/local/share/opennap/config.

* Linking Servers

  1.  you need to add the dns name of the server you wish to allow to connect
      to your server in the MySQL database.  This needs to be done on both
      ends, as it does mutual authentication to prevent bogus servers from
      being able to join.

      # mysql -u mp3 -p
      Enter password:

      mysql> use mp3;
      mysql> insert into servers values('other.server.com','password');
      mysql> quit;

   2.  connect to your server and gain elite access, and execute the
       `server connect' command (currently only bx-nap has support for
       the opennap commands), specifying the host and port to connect to.

       In BWap, you would do:
       /admin connect <server> <port>

* Database descriptions

	The following tables are stored in the "mp3" database.

	* Accounts table

		CREATE TABLE accounts (nick VARCHAR(15), password VARCHAR(32),
			level VARCHAR(9), email VARCHAR(64), created INT,
			lastseen INT);

		Table used to keep track of user registration

	* Server table

		CREATE TABLE servers (name VARCHAR(32), password VARCHAR(32));

		This table keeps the passwords for its peer servers.  When
		a server requests linking, we look in this table for the
		password to expect.  In addition, the dns lookup for
		'name' MUST match the ip address for the connection to
		prevent others from using a sniffed password.

* Server to Server messages

There are many cases where client commands need to be passed to peer servers
in order to maintain database consistency across all servers.  However, most
of the commands that the clients use don't specify the user who performed
the action.  This implementation borrows from the IRC protcol and prefixes
client commands with
	:user
to indicate to peer servers which user issued the command.  Commands which
already specify the user name, such as the login request (2), are not
prefixed.  Each request handler should have a comment at the beginning
specifying what input it expects.

* Extensions to messages

200	search [CLIENT]

	SOUNDEX CONTAINS "..."

		soundex is a way of (loosely) hashing words to find words
		that "sound" similar.  opennap supports searching for files
		in this manner

	TYPE <mime-type>

		opennap supports other media types besides mp3.  by default,
		searches will only match mp3 files.  a client can however
		search for other media typs by specify either a full or
		partial MIME content-type, such as "video" or "image/jpeg"
		(see message 10300 for adding media to the database).  The
		special keyword `any' will match any media type in the
		database.

		The results of the search are returned as with mp3, except
		the fields for bitrate, sample frequency and length are
		meaningless (and are set to 0 in this implmentation).  The
		client can then download as they would any other mp3 file.

* Non-standard messages

The following messages are not present in the official napster servers, but
are implemented as additional functionality in the opennap server.

10000	client quit [SERVER]

	<nick>

	the message is sent to peer servers when a client connection has
	closed

10010	server login [SERVER]

	<server-name> <nonce> <compression>

	<server-name>	the dns name of the server wishing to connect
	<nonce>		a random string to use for authentication
	<compression>	the maximum zip (LZ77) compression level

	this message is sent when a connection wishes to identify itself as
	a peer server.  when a server receives this message, it will send its
	own login command to the peer to initial mutual authentication

10011	server login ack [SERVER]

	<hash-response>

	to authenticate itself, the server will hash the value
		<peer-nonce><nonce><server-pass>
	using the MD5 algorithm.  this allows the servers to mutually
	authenticate without the plaintext passwords traversing the network

10013	user ip [SERVER]

	<user> <ip> <port> <server>

	this message is used for a server to pass the ip address of a
	locally connected client to its peer servers, since that information
	is not available in the login message.  <ip> is an unsigned long
	integer specifying the ip address for <user>

10014	registration info [SERVER]

	<user> <pass> <level> <email> <created> <last-seen>

	<pass>		user's password
	<level>		user's default level
	<email>		user's email address
	<created>	time at which the account was created
	<last-seen>	last time the user logged into a server

	When a server detects that the user table is out of sync between
	servers, it will send its notion of what the entry should look like
	to all the other servers.  If a receiving server has a matching
	user, it checks the <created> time to see which is the oldest
	entry and updates accordingly.

10100	server connect [CLIENT]

	<server> <port> [ <remote_server> ]

	attempts to link the current server to <server>:<port>.  if
	<remote_server> is given, then that server attempts to make the
	link.  this command can be executed by admin level and higher.

10101	server disconnect [CLIENT]

	<server> <reason> [ <remote-server> ]

	delink current server from <server>.
	must be admin or high level to execute this command

10110	kill server [CLIENT]

	<server> <reason>

	cause the server to shutdown.  must be elite level to execute
	this command.

10111	remove server [CLIENT]

	<server> <reason>

	reqeusts that <server> be removed from the table of allowed links.
	must be elite to execute this command

10112	show server links [CLIENT, SERVER]

	server: <host> <port> <max buffer size> <buffer size> <consumed bytes>

	This command is used to show information about the links a
	server has to other servers.  The list is terminated by a 10112
	message with no data.

10115	show server stats [CLIENT, SERVER]

	server: <clients> <servers> <files> <gigs> <channels> <time> <uptime> <memory>

	This command is used by administrators to get information about the
	state of the server.

	<clients>	number of locally connected clients
	<servers>	number of locally connected servers
	<users>		total number of global users
	<files>		number of files in the db
	<gigs>		total size of all files shared
	<channels>	number of active channels
	<time>		time at which the server was started
	<uptime>	number of seconds of uptime
	<memory>	if debugging is enabled, this will show the memory
			currently in use, otherwise it will be -1

10200	compressed packet [SERVER]

	[note: this packet is deprecated as of opennap 0.11]

	<len><data>

	<len>	is the size of the uncompressed packet(s), specified as a 4
		byte value in little-endian format
	<data> is the compressed packet

	note: there is no whitespace between <len> and <data>, since the
	body of this message does not contain text

	this packet is used to transmit one or more packets together in
	compressed form.  since most of the messages are text, they should
	compress very well.  once uncompressed, the data should contain 1
	or more valid packets

10300	share generic media file [CLIENT]

	"<filename>" <size> <md5> <content-type>

	<content-type> is the MIME type defined for what the data is.  This
			should be of the form TYPE/SUBTYPE, where TYPE is
			one of: audio, video, text, image, application

	Examples:

	"C:\IMAGES\Grand Canyon.jpg" 54187 bc938fdc0ef63772bfbdbf57aabb0860-54187 image/jpeg
	"\home\drscholl\src\opennap-0.11.tar.gz" 102161 51c07734811a26853b1a2a87b67c68a1-102161 application/x-gunzip

10404	error message to remote user [SERVER]

	<user> <message>

	This message is used to send a 404 type message to a user that is on
	a remote server.  When the server that has the local connection to
	the client receives this message, it reformats it as a 404 message
	for delivery to the client.

* References

RFC1459, the IRC protocol was helpful in implementing many features.

http://www.onelist.com/community/napdev/ is a useful community (mailing list)
for discussion of the napster protocol.
