P2P, Firewalls And Connection Splicing
dbarclay10 writes: "There's an interesting article over at Byte about what happens when nobody accepts incoming connections any more, like when more people start using firewalls or NAT. Specifically, it talks about peer-to-peer networking(a la Napster), and how it would be affected. Good read."
A----B----C
Relaying data from A through B to C for 23 million hosts is massive traffic, which requires massive bandwidth. B telling A what C's address is and C what A's address is requires less traffic/bandwidth.
Specifically the problem is 2 clients behind firewalls such that neither can be used as a server, so they cannot communicate with each other directly. They COULD have their traffic relayed through an indirect server that is open to the internet, but that means that the relay needs to be able to handle that bandwidth as well.
I'm not well versed on the internals of TCP/IP, but I believe that when a connection is established, the ip and port information are written to some type of internal table and used from then on for further data transfers across that socket.
Consider if both clients initiated a connection with the relay to open the connection. Once the connection is opened, the IP information in the internal table will be modified on both clients to the IP address/port of the NAT machine of the other client. At this point, both clients will be connected to each other but neither of them is a server. And the connecting relay only needs to pass enough traffic to initiate the connection, thereby keeping it readily available.
-Restil
Play with my webcams and lights here
ATM Machine
...language FORML
...distribution of BSD (not really, but should be) :)
...
PIN Number
DSL Line
KBPS per second (horrible confusing, because it can actually mean something..)
VDU unit
EBCDIC code
IBM machines (not really, but should be)
Microsoft software (not really, but should be)
DOS operating system
TOPS-20 operating system
ARPANET network
OSF Foundation
USG group
TECO editor
Yacc compiler (ouch.. think about it
EMACS editor (not really, but should be)
I'm pretty sure that repeating part of an abbreviation for clarity has become acceptable through overuse...
In this scenario, all traffic between many pairs of hosts wishing to communiate is 'relayed' through a common .. well.. relay! Figure it out...
It's like if during all file transfers on napster, all data was passed through the napster server.
The real issue, I think, is that, even if we start destroyign transparency with NAT (well, we already seem committed to that).. there will alwyas be *some way* of getting data to and from where we want, the question becomes 'how efficient is it'.
The real reason simply boils down to conserving available address space. The reason we need NAT, contraty to what everyone thinks, is not security... though it's commonly used that way, the reason is because of a LACK OF ADDRESS SPACE.
You could firewall *just as well* stuff NOT behind a NAT box.... original firewalls were *gasp*, filtering routers.
yes, there are lots of reasons to use nat in firewalls, for company networks.. but these are controlled, engineered situations where the admin (hopefully) understands all the implications. I know I do... I consciousoly accept the lack of incoming connections. I'm FINE with that. It's necessary for me to have a single choke point to prevent people on my network from violating my policies. The problem is with lots of people who don't want that.. they just want lots of hosts on the net, period.
They are trivial from the point of view of someone who may understand the details of tcp/ip; they are absolutely NOT trivial to someone who simply wants ot download and run software, and who uses NAT because he both doesn't know to do differently, and because his ISP charges 'per IP address', if in fact they offer additional ones at all!
We're out of address space. It's that simple. In a normal, proper arhitecture, old-school IP, every home would be a subnet. and YES, that's 'wasteful', but the idea is that there is supposed to be enough address space that it's okay to do so. This is the point of switching in ipv6 asap.
NAT isn't that bad. When I first set up a home NAT firewall, I suddenly noticed that many of my napster recieves weren't working anymore. Woe is me. However, it's a trivial matter to run napster on each individual computer set to listen/accept on a certain port, and configure forwarding of that port through the firewall.
For example, if I am running napster on default listen/accept of 6699..
ipmasqadm portfw -a -P tcp -L $EXT_IP_ADDR 6699 -R $INT_IP_ADDR 6699
And that's that. If another computer on the internal NAT segment wants to use napster, just set it up to use a nondefault [say, 9966] port. Most all NAT/masquerading issues can be resolved with a little elbow grease.
---
man sig
---
the pen is mightier then the sword. the sword is mightier then the court. the court is mightier then the pen.
The massive bandwidth requirements come from his example; Napster. Would you like to volunteer to pay for the bandwidth of hundreds of thousands of users downloads MP3s at ~700Kbps? :) Thought not.
Dave
Barclay family motto:
Aut agere aut mori.
(Either action or death.)
Barclay family motto:
Aut agere aut mori.
(Either action or death.)
Coming from the gaming industry (which has done P2P LONG before Napster), I can safely say that Proxys and NATs are the bane of a network programmer's existence. Often times it's difficult or impossible to detect them, and most of the time once detected there's nothing you can do about them.
l
NAT is certainly an improvement over application-specific proxies (like HTTP) - since you can usually make arbitrary outgoing connections, but the inability to allow incoming connections makes peer-to-peer gaming difficult or impossible.
However, there is a solution in the works, it's called Realm-Specific IP, here's the IETF working group that's working on it: http://www.ietf.org/html.charters/nat-charter.htm
Basically it allows a client behind a NAT to reserve a port on the NAT and forward all traffic from that port to the client. So different clients can open up different listening ports on the NAT, and it will forward them incoming connections. Since a NAT box has a good 65k ports to play with, you should easily be able to support several thousand clients on a NAT'd IP with virtually no loss in functionality - clients can make any outgoing connection they want, and can accept incoming connections after binding a port on the NAT.
I pray every day that this protocol will get finalized quickly and be implemented in all NAT products. Even better if it could be implemented in the client OSs at a low-level - so that when you do a bind() on a client, it automatically makes an RSIP request to your NAT to bind the port there as well. That way client applications can work transparently without having to add special code (like you do to support stuff like SOCKS) - although I expect there will be Winsock wrappers on Windows to support RSIP like there are SOCKS wrappers.
Maybe I'm falling for a troll here but...
I'm afraid that you are in danger of losing your job -- unless of course your job is to know how to manage networks but not necessarily to know how they work.
The author of the article knows exactly what he is talking about. The two modes he mentions would work as follows:
Brokering - Napster does this. It allows two independent peers to "find" each other and then establish a direct correction, much like DCC in IRC. This follows the definition of a "broker" very well.
Relaying - basically like proxying, except that it allows two "clients" to communicate with each other. Both clients connect to the same server, which establishes a "virtual" connection between them by storing and forwarding the data between them, sort of like a bridge. The reason why this would require huge amounts of bandwidth is that the server would have to be able to handle the traffic for both ends of all connections that it relayed in this way. Seems pretty obvious right?
The other technique that the author hints at is "connection splicing". This is a mechanism whereby an intermediate basically "joins" two TCP connections together. There are a number of difficulties in doing this -- mostly to do with the unpredictablity of TCP sequence numbers. It probably would not work in this scenario. You really have to be in the middle to rewrite all packets that go between the two parties - e.g. as a bridge. It's pretty impossible to switch the endpoint IP addresses of a TCP connection midstream.
Like I say, maybe you're just a troll, but I would say that the main lesson here is don't go shooting your mouth off unless you are pretty sure that you know what you're talking about.
It's generally recognized that NATs are a hack to get around the failing of the current IPv4 network. Even though I have written one of the first NATs before they became popular, it is widely agreed within the IETF that NATs present surmounatble problems. In adition to the inability to establish peer to peer TCP connections - the primary reason being that you can't determine both ends TCP ports until after the connection is established - there are also significant problems for network security mainly because you can't directly ties the end user's IP address to the security protocol. Also, IPsec won't work through NAT's particular well because the ESP protocol doesn't typically work through NATS. Also, I suspect that MTU discovery may not fully work through NATs if they haven't been correctly implemented - i.e. you also need to translate the ICMP messages related to the NAT - often these might not pass through.
This is one of the dominant reasons why IPv6 is needed. While there are many reasons that NAT is useful, the dominant one is the lack of IP addresses. Ipv6 certainly deals handsomely with that issue.
Another issue I have with NATs is that from an ISP point of view (we run one also) it is quite difficult to trace a rogue user that is on the inside of a NAT because usually a NAT will hide the identity of the customer, and you have to resort to other means to determine the identity of a user that may be launching an attack. This may be a good thing for some, but generally it makes life more difficult for the sysadmin.
There are other failings with NATs - for that reason they are generally frowned upon.
Time to rollout IPv6.
"Windows 2000: based on NT technology" ???
based on new technology technology ?
Zetetic
Seeking; proceeding by inquiry.
Elench
A specious but fallacious argument; a sophism.
Also reminds me of the way Kali works, wrap ipx packets with tcp/udp packets. You tell the client(or server) what you want. At the application level not the transport.
Currently, the only way to do it now is with Port mapping/routing. But maybe someone will come up with some cool gateway layer type program/protocol. The gateway layer program would route IP based on the content, and route internally on some realtime definition list.
Example.
Lets say 192.168.1.1 is our NAT/Application gateway router.
We load our P2P program, it then sends notification to 192.168.1.1, with the content it wants to accept on a port, and the some identification key. I think you could form tcp/udp packets with this information. Then after the first redirect, its all normally NAT traffic.
There must be dozens of ways to accomplish this.
-Brook
I was walking down the street wearing glasses when the prescription ran out.
- Steven Wright
If you hang your DSL or cable modem off of a linux box and do your NAT there then solutions to these little conundrums become fairly trivial. To accept external connections on a particular port of a machine behind the NAT box, all you need is a generic proxy, like the TIS Firewall Toolkit's plug-gw. And you get packet filtering capability thrown in as part of the bargain.
Naturally, this solution involves tradeoffs. Instead of a sleek little fanless box nestled somewhere in the vicinity of one of your computers, your stuck with a hulking rattle-trap of a 486 beast (in a butt ugly tower case, most likely). But on the bright side, you get to coo over your homemade router's uptime and you can set things up so you can SSH into your home network from the office. Works for me.
As an admin, I implore you: Don't piggyback on well-known ports. I've had to create a number of "exceptions" for lame applications that use HTTP, DNS and other well-known service ports because they're assuming that they'll be open. These apps choke because we use transparent proxying and their non-http traffic on port 80 dies. The stuff trying to use 53 dies because we don't allow end-user DNS queries to the outside.
I'd also implore you to add some kind of flexibility to the system to allow switching of port numbers or the use of a range of numbers. We haven't seen it with port numbers yet but we've gotten into pissing matches with application vendors who "assume" that they're the only one using 10.x.x.x or 192.168.x.x and what's the problem with us default-routing 10.0.0.0/24 to their network? It usally ends up in some weird dual-NAT situation that makes connections to their networks a nightmare. The same logic holds true for ports -- unless you've got an RFC or some IANA-reservation on your service/port combo, make it flexible -- someobody else may be using it!
And port/service blocking isn't necessarily BOFH in action, a lot of times you have "past experiences" with lusers. Besides, good security policy means you get to pass the traffic we pay you pass, and nothing else. I know this rankles the geeks, but for 99.95% of the working stiffs they don't need pass telnet data or the like.
Most firewalls will allow UDP replies for a certain period of time after an initial UDP request is sent. In this way, one side sends a UDP request (which gets thrown out on the other time). The other side then replies (presumably a central server is needed to note the initial request). That reply is received since it is a UDP reply. The two sides may now have a UDP conversation. This isn't completely decentralized, but only requires a couple of packets from an agreed upon server (you could even have this simply be an agreed upon peer with a less restrictive firewall).
ok then your [sic] infringing on my copyright! Could you as [sic] me next time before STEALING my comments for your own?
While I had a hard time understanding NAT, I'm beginning to learn that it is extremely versatile and a lot of times people, like the author, don't understand that it can be configurable in a lot of ways.
For our home connection, I set up a port for each of my roommates 4 computers and we use Napster through those.
What is even more interesting is that NAT will soon have unnoticed configuration itself. There has been work done to improve NAT translation so if a port is opened on an inside IP, a client can connect to the router and request that NAT redirect to that port.
I don't think IP masquerading is going to anything but get better over the next few years, and I trust it to be the best security with the most configuration in the future.
I don't believe the author of the article has realized that even with the Cisco 675, used for a large number of DSL connections, changes have been made to NAT such as one-time configuration of addresses.
What this new option allowed over previous versions of the bios was setting an inside NAT port and address and binding it to the routers IP. Before this, users would have to log in every time the routers IP had changed and continually change the NAT translation.
NAT is only going to get better folks. Don't worry about peer-to-peer sharing dying any time soon because of it.
I haven't read all the responses here yet (who ever does??), but I think it seems obvious that we need a new protocol definition: TCP over UDP. Any TCP client would be able to use it, and the TCP session would be established over UDP packets. TCP as a protocol can already handle this since it is built to work over IP, another unreliable transport. UDP becomes useful, however, for doing the NAT bypassing that is mentioned in the article. The protocol back-end wouldn't need to be too long, and could be added to most Linux/BSD machines as easily as IPX over TCP is.
...
Just my $0.02 worth
- Michael T. Babcock (Yes, I blog)
Well, for each network of computers behind a firewall sharing an IP address, there can be one computer that has access to incoming requests. Linksys refers to this as the DMZ (Demilitarized Zone). This one connection can be the representative for the entire network.
I know my apartment is behind a Linksys router, and we have 4 connections, however we have one computer that is the dedicated incoming access server. This doesn't really help the other computers on the network, but it is a partial solution to the problem.
..to peer-to-peer connection requests should be intellegence in the firewalls or routers. Once they're aware enough of the application to recognize a "requested" inbound connection that doesn't exactly match an "originated" connection, the problem goes away. Many firewalls already do this with outbound FTP access to eliminate the need for PASV transfers.
If a suitable peer-to-peer protocol were well-documented (read RFC) and widely implemented, it wouldn't take long before the vendors started picking up support for it. Problem solved.
_________________________________
Now!
I've always considered it more of a router. It's not like Napster stores anything on its own system. Rather, they allow the appearance of PTP connections through a pool of users.
Actually, I could consider it a completely connected graph, where every user is a point on the graph, connected by lines to every other user. It's just when you refuse to 'share', it's a directed graph. And considering that I'm not trying to traverse the graph completely, just search the data at each point, it still doesn't seem like a server.
Just my 2 shekels.
Kierthos
Mr. Hu is not a ninja.
Is that what NT stands for?
I always thought it was naked turkies. Go figure.
"I would kill everyone in this room for a drop of sweet beer."
Spoofing to NATted boxes into talking UDP is much easier than TCP 'cause of the lack of sequence numbers and other byproducts of guaranteed delivery. There' a great page about it at http://www.alumni.caltech.edu/ ~da nk/peer-nat.html.
--
If Microsoft didn't ship their systems with all those unwanted services turned on, this wouldn't be a problem.
...distribution of BSD
are you saying that it should be "distribution of BS"?
--
Second, it seems to me that the popularity of NAT is related to the infancy DSL is in right now; once serious competition between DSL providers sets in, I predict we'll see DSL modems that can easily hook several machines with real IP addresses to the net. We might have to use a better PPPoe, or wait for IPv6 to give us the address space, but then again we might not (if we can put a man on the moon...)
If I may rant for a moment, complaints about firewalled (non-NATed) machines just piss me off. If your sysadmin won't put a hole in the firewall for your favorite P2P application, it's because said sysadmin doesn't want any machine in the known universe to be able to communicate with your machine and possibly crack any insecure software you may be running -- like P2P software. That's the point; few crackers run servers and wait for crackable clients to connect, and so firewalled machines are reasonably safe from outside attack. P2P software that allows by-request outgoing connections opens a large and invisible hole in any firewall; worse, you don't need to do any detectable scanning to find out that machine X is running something crackable. NAT is an acceptible excuse for designing this kind of insecurity into a protocol, I guess, but I would raise hell if I were an admin and caught one of my users sneaking around my firewall.
Of course, if I were an admin, I'd forge email to users from their friends containing an attachment called NOEMAILFORYOU.EXE; I may be in the minority here. (Cut to big white letters on a black screen, alternating: "What did I tell you not to do?" "No email for you." "What did I tell you not to do?" "No email for you...")
This was covered recently (relatively speaking) in a very good article regardign transparency of the internet, and how it's been shot.
The general concept is that, originally, IP addresses were issued based on network size, *NOT* based on size of the pipes and who they were connected to. It was presumed there was space for everyone. Of course, today's restrictions have changed things, and are due to a lack of address space.
Originally, it was safe to assume that any app would work so long as it adhered to using tcp/ip. Period. Now.. you have to take into consideration taht different sides of a conversation may be unable to initiate a connection....
The only bad thing,I think, we find, is when protocols include their own IP information in packet payloads.. this defeats the purpose of layering, and causes confusion. This is why gnutella and other software aks you for your 'visible' IP address.
At the heart of the issue is how the internet has changed; it used to be that IP address assignment, and acutal links were not tied together. Heck, it used to be you could have a large block allocated even though you were only potentially going to hook up to the network at some undetermined point in the future; the point of having unique addresses was merely to make it possible for internetworking to occurr.
This has been lost now. Address space is at a premium, and it's being controlled more and more by big players. YOu can't even GET your own address space anymore unless you have fat pipes to multiple providers.
NOw.. granted, there is a finite amount of space, and it IS fair to put it where it's best used.. but it must be temporary. THe real freedom of the net to grow without inhibition comes from having unique address space freely available. (Of course, convincing others to route your traffic was *always* a separate issue, but at least everyone agreed on who had what)
Yeah, that was what I was saying to myself just this minute. I don't get the fucking problem, P2P not working through firewalls is NOT a bug, it's a feature.
It sounds like:
Duh, good firewalling/NAT allows only what the admin wants allowed.
(Please, I know that NAT!=Firewall, for me NAT is more or less a kind of "firewall" by accident).
Please, people, P2P is NOT a cool kind of "I can trade mp3s/porn with the world about my companies wires".
When the P2P people want to allow easy cooperation (and not circumvention) of firewalls and stuff, the ought to design their protocols in the direction of corporation. Not such a port whoring thingy like IIRC icq does (yeah, port 23 works, lets use that for inbound traffic).
For instance some kind of application proxy which can be dropped into the DMZ and configured properly to allow only wanted P2P traffic.
>Relay all the traffic between us, rather than just brokering the connection.
:) It's simple.
That 'relaying' would imply that all traffic between clients passes through the server. "Brokering" would refer to having the server simply instruct both sides as to how to communicate more directly.
>Broker the connection in some way that magically splices together two client-initiated TCP sessions.
No that's not somethign that's done now, and I agree it sounds impossible, but what the author is implying is that we should look at a hack to allow a server to instruct two hosts that are only capable of initiating (outgoing) tcp connections to communicate directly anyway. I agree I can't see how it would be done, but I can't argue with the idea being good.
>I was sure Napster didn't do relaying, that would require massive bandwidth
Please! Help me! I am *paid* to know about networking. What is this "relaying" thing that 'requires massive bandwidth'? Am I going to lose my job?
Perhaps. I'd probably fire you
Relaying is a common term in networking, especially on the internet, and in other forms of communication as well. You could look it up in teh dictionary. What he is suggesting is that napster relays all traffic between clients. I didn't think it did that (and still don't), but it's quite clear what he was talking about. IF you get paid to know this stuff, maybe you should start broadening your horizons a bit.
>Sorry, I am too scared to read further tosh like this. Either the author is a global telecoms guru, or he is a know-nothing fuckwit. If my diagnosis is wrong, then I have just lost my job.
Get off the high horse. He's a guy who has a decent understanding of how things work, but not a really low-level understanding. His ideas are correct, his motives are also correct. You are splitting hairs. He's not claiming to be an expert. Read between the lines. Just becuase he uses the word 'tcp' doesn't mean he understands it down to each bit of the conversation.
TCP allows a connection to be established if both sides simultaneously send eachother a SYN packet. This method requires a little NAT cooperation, but only a little. Here's how it could work:
This requires cooperation between the sources and their NATs. Specifically, it requires these three things from a NAT:
There is one non-problem I expect people to bring up. There seems to be an apparent race condition in step 11. This isn't really a race condition because of requirement 2 for NATs. Basically, the two sources can SYN eachother all day, and it won't matter until both NATs have performed the step required by requirement 3, at which point it will appear to both sources as if the SYNs were simultaneous.
It's a hack, but I think it'd work.
Need a Python, C++, Unix, Linux develop
heh. Still, no one else had yet posted about ipmasqadmin when I made that comment. It was meant to provider a hint to newbies; the article was afterall about the prevalence of firewalls in home networks.
Of course a masq_napster module would be nice, but there is no one to speak of that I know of right now.
---
the pen is mightier then the sword. the sword is mightier then the court. the court is mightier then the pen.
It isn't like people will ever quit accepting connections, the home user won't let it, I know people who have only gotten the internet because of napster. Also, if you were an ISP, and you took away Napster and the like, you would lose half your customers. (it isn't likely that all individual users would cut off incoming transmissions, so the ISP would have to do it for it to actually happen)
On top of that, it just doesn't make sense. This sounds like the rumor that the internet will die soon that always goes around. It could happen, but it won't.
In addition, once people quit doing it, someone would revive it. The Gopher article from yesterday says it all, you can't really destroy any kind of internet technology that could be considered cool to even a small group of people. They will revive it, and it will grow.
As an administrator, my advice is to write it with proxy support from the very beginning. If it can authenticate to an http proxy server it can almost always ride over that.. i.e. realaudio, windows media player, seti@home, etc. If you're dealing with simple packet filtering firewalls you can also probably get away with using any of the ephemeral TCP ports since they're probably wide open outbound to allow for passive FTP to work. We're facing that can of worms these days and are trying to close it up so that we can block all outbound connections and force everything through proxies for logging, auditing, and intrusion detection.
This IETF I-D includes a novel hack (see part 3) using https.
I agree totally with your "Bandwidth Management for Dummies" explanations.
The first point I was making was that, to achieve what the author was on about, you would need intermediate servers (with a very trusted, and trusting nature).
Your second point: Yes, yes yes. But where does this "massive bandwidth because it's relayed" requirement come from? Relaying/proxying should only ever require an O(1) signalling overhead. And O() is a kind function in this situation.
Ok, let's start off with the basics.
We have a peer-to-peer file sharing service, such as napster. Client A is trying to request a file from Client B, however, Client A can't connect to Client B to get the file because Client B is behind a firewall and incoming connections are disallowed. How do we approach this?
Well, the answer thus far is for the Server to tell Client B to connect to Client A and initiate the transfer from their end, but now what if Client A is behind a firewall as well!?!? Well, we have two options, although only one is even partially viable (can actually be accomplished with the TCP protocol definition in place today):
Relaying - this should be painfully obvious. They both already have connections open to the server, so the server requests the file from Client B, then sends it on to Client A. This is obviously a Bad Idea because of the massive amounts of bandwidth you would need to relay all of these file transfers.
Brokering or Splicing of two Client connections - the best example that I can think of to give here is that of a program called FlashFXP. It became a very helpful tool in transfering files from server to server when you were on a dialup, because you could in fact open a transfer from one server to the other without the bandwidth constraints of the dialup connection. However, this only worked because both of the servers you are connected to ALLOW incoming connections, allowing the software to broker the connections in this way.
So the main issue is if neither client in a peer-to-peer connection will allow a connection (because basically, the Napster Client is also a server in that it serves up file requests for MP3's that you have residing on your computer), how can we transfer files between the two? One interesting answer was the TCP over UDP approach, but this would not scale well at all (too much wasted bandwidth, you might want to read the article deeper if you'd like a better understanding), and beyond that, there is no approach to take with TCP (that I or any of those discussing it knew of) to broker a connection, only because of the manditory handshaking that the protocol requires. I hope that helps.
Revelations 0:0 - The beginning of the End
tunneling over port 80 breaks all kinds of standards... what we need to do is standardize the way hide NAT handles incoming traffic.
right now, the firewall keeps track of the state connection (usually via a high source port #) and lets the returning packet go to the correct internal host.
what needs to happen, is to create some type of standardized way of accepting incoming connections to a firewall, to route them to the correct interal host... unfortunatly, no matter what, this will be a security risk.
the quick fix, which seems to be the only way using current standards, when 2 hosts are firewalled, is to use a server of some type... no way around it, but bringing port 80 tunneling mainstream, will cause security headaches globally
Cybie! aka Ralph Bonnell
I believe you could trick a firewall into allowing the connection, by creating a simultaneous connection. Basically, both computers send a SYN packet simultaneously, using the appropriate source and destination ports. Both firewalls would see the SYN going out, and while they will deny the SYN coming in, they will allow the further ACKs going out. This is allowed in the TCP stack, though you might have to use raw IP packets to achieve it.
ok then your [sic] infringing on my copyright! Could you as [sic] me next time before STEALING my comments for your own?
It uses a server to do searches, and broker connections, but data transfers is peer to peer.
Both involve something going from point A to point B, with the interaction of a third point/party C
Relay: A sends something to B via C
Broker: C makes arrangements for A to send something to B directly.
Note that the negotiations to initiate all of the above would be a separate set communication packets.
as always, effective communications protocols means correct handling of the data packets sent and received.
Just like in any language.
"It is a greater offense to steal men's labor, than their clothes"