diff --git a/Makefile b/Makefile
index 7ab6ef1..5b21c74 100644
--- a/Makefile
+++ b/Makefile
@@ -12,9 +12,8 @@ dist:
 	rm -rf alcuin-$(VERSION)
 
 clean:
-	rm -rf genesis.diff alcuin-$(VERSION).diff.escaped alcuin-$(VERSION) 
+	rm -rf alcuin-$(VERSION).diff alcuin-$(VERSION).diff.escaped alcuin-$(VERSION) 
 	rm *.tar.gz
-	rm *.diff.escaped
 	find . -name "*.swp" -delete
 	find . -name "*.pyc" -delete
 
diff --git a/lib/client.py b/lib/client.py
index f3dc6ab..25ec4ab 100644
--- a/lib/client.py
+++ b/lib/client.py
@@ -30,6 +30,16 @@ class Client(object):
         else:
             self.__handle_command = self.__registration_handler
 
+    def is_addressed_to_me(self, message):
+        command = self.__parse_udp_message(message)
+        if command[0] == 'PRIVMSG':
+            if command[1][0][0] == '#' or command[1][0] == self.nickname:
+                return True
+            else:
+                return False
+        else:
+            return True
+
     def get_prefix(self):
         return "%s!%s@%s" % (self.nickname, self.user, self.host)
     prefix = property(get_prefix)
@@ -51,6 +61,30 @@ class Client(object):
     def write_queue_size(self):
         return len(self.__writebuffer)
 
+    def __parse_udp_message(self, message):
+        data = " ".join(message.split()[1:]) + "\r\n"
+        lines = self.__linesep_regexp.split(data)
+        lines = lines[:-1]
+        commands = []
+        for line in lines:
+            if not line:
+                # Empty line. Ignore.
+                continue
+            x = line.split(" ", 1)
+            command = x[0].upper()
+            if len(x) == 1:
+                arguments = []
+            else:
+                if len(x[1]) > 0 and x[1][0] == ":":
+                    arguments = [x[1][1:]]
+                else:
+                    y = string.split(x[1], " :", 1)
+                    arguments = string.split(y[0])
+                    if len(y) == 2:
+                        arguments.append(y[1])
+            commands.append([command, arguments])
+        return commands[0]
+
     def __parse_read_buffer(self):
         lines = self.__linesep_regexp.split(self.__readbuffer)
         self.__readbuffer = lines[-1]
@@ -294,21 +328,18 @@ class Client(object):
             targetname = arguments[0]
             message = arguments[1]
             client = server.get_client(targetname)
+            self.server.print_debug(self.server.nicknames)
 
-            if client:
-                formatted_message = ":%s %s %s :%s" % (self.prefix, command, targetname, message)
-                client.message(formatted_message)
-                self.server.peer_broadcast(formatted_message)
-            elif server.has_channel(targetname):
+            if server.has_channel(targetname):
                 channel = server.get_channel(targetname)
                 self.message_channel(
                     channel, command, "%s :%s" % (channel.name, message))
                 self.channel_log(channel, message)
             else:
-                # this isn't reliably true so let's not send the error
-                return
-                self.reply("401 %s %s :No such nick/channel"
-                           % (self.nickname, targetname))
+                formatted_message = ":%s %s %s :%s" % (self.prefix, command, targetname, message)
+                if(client):
+                    client.message(formatted_message)
+                self.server.peer_broadcast(formatted_message, False)
 
         def part_handler():
             if len(arguments) < 1:
diff --git a/lib/infosec.py b/lib/infosec.py
index a431c2f..b0c9c86 100644
--- a/lib/infosec.py
+++ b/lib/infosec.py
@@ -7,7 +7,7 @@ import time
 import struct
 import sys
 
-PACKET_SIZE = 580 
+PACKET_SIZE = 581 
 MAX_MESSAGE_SIZE = 512
 MAX_SECRET_SIZE = 24
 TS_ACCEPTABLE_SKEW = 60 * 15
@@ -16,7 +16,7 @@ class Infosec(object):
     def __init__(self, server=None):
         self.server = server
 
-    def pack(self, peer, message, timestamp=None):
+    def pack(self, peer, message, propagate, timestamp=None):
         # if we are rebroadcasting we need to use the original timestamp
         if(timestamp == None):
             int_ts = int(time.time())
@@ -34,39 +34,40 @@ class Infosec(object):
         self.server.print_debug("added %d to recent" % int_ts)
 
         # build the packet and return it
-        packet = struct.pack("!L64s512s", int_ts, digest_bytes, ciphertext_bytes)
+        packet = struct.pack("!L64s?512s", int_ts, digest_bytes, propagate, ciphertext_bytes)
         return packet 
     
     def unpack(self, peer, packet):
         try:
-            int_ts, digest, ciphertext_bytes = struct.unpack("!L64s512s", packet)
+            int_ts, digest, propagate, ciphertext_bytes = struct.unpack("!L64s?512s", packet)
         except: 
             self.server.print_error("Discarding malformed packet?")
-            return None, None
+            return None, None, None
 
         # Check the timestamp and digest
         digest_check = hashlib.sha512(peer.remote_secret + ciphertext_bytes).digest()
         
         if(int_ts not in self._ts_range()):
             self.server.print_debug("rejected message with timestamp out of range")
-            return None, None
+            return None, None, None
         elif(self.server.recent.has(int_ts)):
             self.server.print_debug("rejected known message: %d" % int_ts)
-            return None, None
+            return None, None, None
         elif(digest_check != digest):
             self.server.print_debug("name: %s" % peer.name)
             self.server.print_debug("remote_secret: %s" % peer.remote_secret)
             self.server.print_debug("ciphertext_bytes: %s" % binascii.hexlify(ciphertext_bytes))
             self.server.print_debug("digest_check: %s" % binascii.hexlify(digest_check))
             self.server.print_debug("rejected bad digest: %s" % binascii.hexlify(digest))
-            return None, None
+            return None, None, None
         else:
             # Return the cleartext
             serpent = Serpent(self._pad(peer.remote_secret, MAX_SECRET_SIZE))
             cleartext = serpent.decrypt(ciphertext_bytes).rstrip()
             self.server.print_debug("received, validated, and decrypted udp packet: %s" % cleartext)
             self.server.recent.insert(int_ts)
-            return cleartext, int_ts
+            # self.server.print_debug("%s %d %s") % cleartext, int_ts, propagate
+            return cleartext, int_ts, propagate
 
     def _pad(self, text, size):
         return text.ljust(size)
diff --git a/lib/peer.py b/lib/peer.py
index e108328..5c25d25 100644
--- a/lib/peer.py
+++ b/lib/peer.py
@@ -13,10 +13,10 @@ class Peer(object):
         self.socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
         self.infosec = Infosec(server)                                 
 
-    def send(self, msg, timestamp=None):
+    def send(self, msg, propagate, timestamp=None):
         try:
             full_message = str.encode(msg)                                        
             self.server.print_debug("sending message: %s" % full_message)
-            self.socket.sendto(self.infosec.pack(self, full_message, timestamp), (self.address, self.port))   
+            self.socket.sendto(self.infosec.pack(self, full_message, propagate, timestamp), (self.address, self.port))   
         except Exception as ex:
             print("Exception while attempting to encode message: %s" % ex)
diff --git a/lib/server.py b/lib/server.py
index 9e8cbe5..bdd44d5 100644
--- a/lib/server.py
+++ b/lib/server.py
@@ -1,4 +1,4 @@
-VERSION = "9996"
+VERSION = "9995"
 
 import os
 import select
@@ -141,20 +141,23 @@ class Server(object):
 
     def handle_udp_data(self, data):
        for peer in self.peers:
-           message, timestamp = self.infosec.unpack(peer, data)
+           message, timestamp, propagate = self.infosec.unpack(peer, data)
            if(message != None):
                self.print_debug("valid message from peer: %s" % peer.name)
                # send the message to all clients
                for c in self.clients:
-                    self.clients[c].message(message)
-               # send the message to all other peers
-               self.rebroadcast(peer, message, timestamp)           
+                    # self.clients[c].udp_socket_readable_notification(message)
+                    if (self.clients[c].is_addressed_to_me(message)):
+                        self.clients[c].message(message)
+               # send the message to all other peers if it should be propagated
+               if(propagate == True):
+                   self.rebroadcast(peer, message, timestamp)           
            else:
                self.print_debug("Unknown peer address: %s" % peer.address)
     
-    def peer_broadcast(self, message):
+    def peer_broadcast(self, message, propagate=True):
         for peer in self.peers:
-            peer.send(message)
+            peer.send(message, propagate)
 
     def rebroadcast(self, source_peer, message, timestamp):
         for peer in self.peers:
