how do I prevent the machines on the inside of my firewall from being routable?
The same way you do that now: Using unroutable (i.e. private) addresses in your internal network instead of public ones.
I might not remember this correctly, but I think IPV6 had a large set of private addresses for use in internal networks.
Anyway, a firewall is always useful, because somebody at your USP could route to your internal network if you had forwarding enabled (which you have probably if you do NAT), and anyone at the internet can route you through source routing (although source routing can be disabled in Linux, and probably in any serious OS.)
Re:The characterization of abandonware seekers
on
The Abandonware Question
·
· Score: 3, Insightful
as merely cheap bastards is apparently self-abscription of game makers' own money-grubbing, greedy motives.
When Al Lowe characterized abandonware seekers as "cheap bastards", he was clearly joking. Read the article.
If that happens, then James Pirate will download the bnetd source, tweak the source to change authentication policy, and run a server where he can play with its ten illegal copies of starcraft.
The real problem here is that they (Blizzard) don't like the fact that other people can implement their protocol, but I still don't understand how the DMCA protects that; they're not doing anything to the battle.net server, they're just making a product that happens to be compatible.
...and the next Internet worm I write will have the following string "Made by JonKatz, Bill Gates, and George Bush".
Strings inside code could be used as evidence, but they are not very serious evidence, not more serious than a papernote left by a burglar saying "I wasn't!". After all, we don't want incrimination to be that easy.
Will the ants be transporting electronical little pieces of leaves to their ant-nest? Perhaps they could carry any kind of food too, or files, or MP3s...
In Ender's Game (1985) there's a worldwide computer network that allows access to news, research information, travel schedules [in the book Peter studied Russian troop movements analyzing movement of freight trains based on information from the Net], and discussion forums. It's true that in 1985 there was already a big IP-based network growing, but the books shows a Net that is a part of everyday's life for everyone, much like today's Internet.
It's not my page. I have contributed to the project, and done some documentation translation but I am not the author.
What you recommend works just for a particular case: resource allocation/deallocation. pre/post condition+invariants, combined with a proper exception handling mechanism, allow handling this and every error handling case I've met.
I have aversion to C++, not Eiffel;) But people (boss/professor/etc.) sometimes forces you to work in C/C++ so you need something like BetterC (or that provides similar capabilities) to do proper error-checking without throwing up and making your code a mess. (btw, BetterC works nicely with C++ too).
Check this thread I started here, and see what people usually does. At the end I posted a DBC solution that is simple, clean, and check a lots more than most people did WITHOUT doing almost anything special.
It is true that pre/post conditions can be implemented in C++. But it's hard to get the precise semantics, like:
* Invariant checks should be made only on calls external to the object, but not internal ones. They must be made on entry or exit
* pre/post must not be checked on function calls inside other pre/post checks.
* a precondition violation must raise an exception in the caller routine, not in the called one.
And several other things. That's why I advocate the use of a library or language facility that allows doing that with proper semantic. That's is not exclusive with standard error handling techniques like auto_ptr, which help a lot too.
If we want good error checking, it's necessary to provide programmers with tools that allow them to do error checking without shooting themselves in the foot
allocate_3 is
require
SOME_NUMBER>=0
local
p1,p2,p3: INT_POINTER
do
p1:= malloc(SOME_NUMBER*sizeof(int))
p2:= malloc(SOME_NUMBER*sizeof(int))
p3:= malloc(SOME_NUMBER*sizeof(int))
/* do something with p1,p2,p3*/
free(p1)
free(p2)
free(p3)
rescue
free(p1)
free(p2)
free(p3)
end
Notice how little changed from the original program. You can have a similar C solution and a discussion of the problem (as an example on error-handling) at this document.
Note that this solution does all this things (and compare with other solutions posted):
* frees all memory, no matter if things succeed or fail, and even if things fail in the do_something part
* checks that SOME_NUMBER is valid (non negative) and does not overflow when multiplied by sizeof(int)
* Has not a deeply nested structure
* Has an obvious and visible flow control* Works as a non-error when SOME_NUMBER is 0
* Allows calling routines to get the same kind of clean error-handling
* works robustly when other error conditions I haven't thought of happen.
Yes, C allows all this, but it is a pain in the neck, the code gets big and messy, and hard to mantain. So error-checking in C comes at a great cost...
wow, you got me! I've posted the problem and haven't thought about that.
I hope what has happened in this thread raises my point for exceptions. The only clean, not deeply nested solutions were using goto's in a form of exception handling. The "die if xxx"/"if (xxx) return -1" school is not enough for good error handling.
With exception handling and a good DBC mechanism, you would have:
* overflow raises exceptions, which would have caused an exception that would've been caught, and the memory freed. This is, I'm handling appropiately an error I hadn't thought of.
* not enough memory, or other possible errors also produce exceptions and are nicely cleaned up.
* using a different channel to report success/failure and to return results leads to less confusion:
consider the case SOME_NUMBER was 0. perhaps, if the "do something" part does a loop on the arrays form 0 to SOME_NUMBER -1, it is valid (it would do nothing). malloc(0) returns NULL (see ANSI standars), so we would have treated that as an error (by checking if (!malloc()){... ) when it is not.
> I just say "gee, I feel sorry for those C
> programmers." Of course, garbage collection
> (Java's garbage collection is not conservative...
> but do even conservative garbage collectors have
> problems with non-circular structures?)
There are complete garbage collectors that get anything that's not referenced directly or indirectly from the "roots" (global vars and stack).
Anyway, my do that again with an open/close on any resource... a GC works just for memory. Files usually are automatically closed at end. But open/close transactions with more complex objects, possibly externals would bring the same problem: nice error checking is very hard to do in C. It's possible, but the language make it lots harder than it should. So most people get lazy and don't do it at all. Given that C is one of the main languages in OSS, the title of this article didn't surprise me at all.
I have just read it... It is nice, but it implements only half of the functionality: Definition of axioms over the abstract type (pre/post conditions and invariants), and checking of that assertions.
But it lacks the exception mechanism that makes that checking useful for writing robust program. It is a tool just for correctness, and DBC works toward correctness and robustness.
The Arianne exploded because the "horizontal bias", a 64 bit floating point number, was converted to a 16 bit signed integer producing an exception, because the conversion overflowed.
That exception was CAUGHT BY A HANDLER. The program didn't stop. But the handler above the faulty routine had no information about how to correct the problem, and given that the rocket was going off course, it self-destroyed (yes, that's a security measure).
So, the exception handling was used, and served its purpose of error-handling. The error, was using a 16 bit integer, that was not enough (they used that because they reused the code that they had used for the Arianne 4, whose trajectory had a bias that fitted into a 16bit signed int). If the rocket program would have continued, the arianne could've have crushed over some population. killing a lot of people.
So:
1) The program didn't stop abruptly (that's what exceptions are for, controlling program stop)
2) The exception mechanism possibly saved a lot of lives
3) The program did a reasonable work and ended in an expected way very well for a program with critical bugs in it.
> The initializing of variables is required (except
> maybe p1). Otherwise if the p1 or p2 allocations
> fail, the program will pass an uninitialized
> variable to free().
They wouldn't be uninitialized. They would be NULL, because that's what malloc returns in case of failure, and you assign the result of a malloc to the 3 pointers (that means, you have valid pointers xor NULL).
The repetition is frequent, that's true. But it's a better solution than creating a language pseudostructure for using when I need the same code, and another for when I don't need different code.
One usual case of different code is object constructors. The constructor starts creating a structura, and if it fails in the middle, it has to free it all; but when it finishes correctly it has to free nothing. The approach above works. I've been using it for years and I don't use a debugger.
One note: your "Sanefree" is 100% equivalent to ANSI free() (whose standard behavior on a NULL pointer is to do nothing).
Another "goto" approach. Dijkstra would throw up here, but what are you doing is like a crude exception handling. And people said "checking return codes is enough"...
I like this one a lot more... A lot of people will think the macros/goto are dirty, but they are actually providing a little exception handling capabilities. what you've done is simmilar to BetterC (see here).
But that is for my point that some exception handling is needed to do clean error checking in almost all non-trivial cases.
I like the initializing of p1,p2,p3. Initializing all vars helps to avoid heisenbugs, at a minimal efficiency cost.
I would've done free(p1), without the if(); free(NULL) is perfectly valid. But that's hard to know without a DBC approach (where you have info on pre/postcondition of your functions).
> would probably be better off using a higher level
> language with exceptions and a GC or something.
That's right. That's why I started this thread as a critique to all the people that said "well, checking return codes is enough".
When you run out of memory, you probably will quit, but it would be nice to do some some cleanup, like closing connections and files, saving the user unsaved work (or doing a backup), removing locks, etc. A "if (broken) exit(1)"approach is terrible at this.
> Exceptions and Design By Contract are all very
> good, but they still are bandaids on the problem
Of course. they're just a tool, but in the end you need a good programmer. What I mean is: A good programmer gets a lot of help from DBC.
What would be really nice is an authomatic derivation tool, so you mostly write specifications (even that doesn't solve the problem of getting the specification right). But that is too far away from current programming technology, so we must work with best bandaids possible to get some decent quality in the software (OSS or not).
In the code example you present, I see three cases
1) You're quite sure that y is not 0. that doesn't mean an if, it could probably be a precondition of the routine with the division. This is by far the most common case.
2) The 0 case is possible, and must be handled. then you have 'if y=0 handle special case, else a=x/y'
3) 0 case is invalid, but you have no guarantee that it won't happen. This usually means bad design in DBC, but in the case you must do that, you can put an exception handler
The range/domain situation is helped by strong typing.
In short: there are a lot of tools to help error handling. They're not perfect, but by using it we can improve software quality. Then, why not?
(Hate subject clipping):
Is this an Acme Forced-Feedback Enemy-Denial Smackdown Ergonomic Game Chair?
In case you don't know what I am talking about, read these links.
The same way you do that now: Using unroutable (i.e. private) addresses in your internal network instead of public ones.
I might not remember this correctly, but I think IPV6 had a large set of private addresses for use in internal networks.
Anyway, a firewall is always useful, because somebody at your USP could route to your internal network if you had forwarding enabled (which you have probably if you do NAT), and anyone at the internet can route you through source routing (although source routing can be disabled in Linux, and probably in any serious OS.)
as merely cheap bastards is apparently self-abscription of game makers' own money-grubbing, greedy motives.
When Al Lowe characterized abandonware seekers as "cheap bastards", he was clearly joking. Read the article.
Not gonna work.
If that happens, then James Pirate will download the bnetd source, tweak the source to change authentication policy, and run a server where he can play with its ten illegal copies of starcraft.
The real problem here is that they (Blizzard) don't like the fact that other people can implement their protocol, but I still don't understand how the DMCA protects that; they're not doing anything to the battle.net server, they're just making a product that happens to be compatible.
This is the highest concentration of 'Funny' modded comments I've ever seen.
Am I Wrong?
...for the human race to enter the solar system. (As gwb said himself)
Also, Debian has the RPM tool available for installing. DPKG and RPM are not mutually exclusive, you can have both packaging systems at once.
...and the next Internet worm I write will have the following string "Made by JonKatz, Bill Gates, and George Bush".
Strings inside code could be used as evidence, but they are not very serious evidence, not more serious than a papernote left by a burglar saying "I wasn't!". After all, we don't want incrimination to be that easy.
now that this cat is out of the bag...what can we do to protect ourselves if we can't switch from Windows b/c our jobs won't let us?
Install Mozilla or Netscape to browse and read email. Don't use MS tools for accessing the Internet.
Isn't there a Changelog somewhere? links please?
Will the ants be transporting electronical little pieces of leaves to their ant-nest? Perhaps they could carry any kind of food too, or files, or MP3s...
All in the name of research, of course.
Secondly, I believe that your choice of Star Trek's communicator isn't actually a good example.
Specially because there is a much better model of mobile phone from the previous year (1965): Agent 86 and his shoe-phone.
In Ender's Game (1985) there's a worldwide computer network that allows access to news, research information, travel schedules [in the book Peter studied Russian troop movements analyzing movement of freight trains based on information from the Net], and discussion forums. It's true that in 1985 there was already a big IP-based network growing, but the books shows a Net that is a part of everyday's life for everyone, much like today's Internet.
It's not my page. I have contributed to the project, and done some documentation translation but I am not the author.
;) But people (boss/professor/etc.) sometimes forces you to work in C/C++ so you need something like BetterC (or that provides similar capabilities) to do proper error-checking without throwing up and making your code a mess. (btw, BetterC works nicely with C++ too).
What you recommend works just for a particular case: resource allocation/deallocation. pre/post condition+invariants, combined with a proper exception handling mechanism, allow handling this and every error handling case I've met.
I have aversion to C++, not Eiffel
Check this thread I started here, and see what people usually does. At the end I posted a DBC solution that is simple, clean, and check a lots more than most people did WITHOUT doing almost anything special.
It is true that pre/post conditions can be implemented in C++. But it's hard to get the precise semantics, like:
* Invariant checks should be made only on calls external to the object, but not internal ones. They must be made on entry or exit
* pre/post must not be checked on function calls inside other pre/post checks.
* a precondition violation must raise an exception in the caller routine, not in the called one.
And several other things. That's why I advocate the use of a library or language facility that allows doing that with proper semantic. That's is not exclusive with standard error handling techniques like auto_ptr, which help a lot too.
If we want good error checking, it's necessary to provide programmers with tools that allow them to do error checking without shooting themselves in the foot
in pseudo-Eiffel:
:= malloc(SOME_NUMBER*sizeof(int))
:= malloc(SOME_NUMBER*sizeof(int))
:= malloc(SOME_NUMBER*sizeof(int))
/* do something with p1,p2,p3*/
allocate_3 is
require
SOME_NUMBER>=0
local
p1,p2,p3: INT_POINTER
do
p1
p2
p3
free(p1)
free(p2)
free(p3)
rescue
free(p1)
free(p2)
free(p3)
end
Notice how little changed from the original program. You can have a similar C solution and a discussion of the problem (as an example on error-handling) at this document.
Note that this solution does all this things (and compare with other solutions posted):
* frees all memory, no matter if things succeed or fail, and even if things fail in the do_something part
* checks that SOME_NUMBER is valid (non negative) and does not overflow when multiplied by sizeof(int)
* Has not a deeply nested structure
* Has an obvious and visible flow control* Works as a non-error when SOME_NUMBER is 0
* Allows calling routines to get the same kind of clean error-handling
* works robustly when other error conditions I haven't thought of happen.
Yes, C allows all this, but it is a pain in the neck, the code gets big and messy, and hard to mantain. So error-checking in C comes at a great cost...
wow, you got me! I've posted the problem and haven't thought about that.
I hope what has happened in this thread raises my point for exceptions. The only clean, not deeply nested solutions were using goto's in a form of exception handling. The "die if xxx"/"if (xxx) return -1" school is not enough for good error handling.
With exception handling and a good DBC mechanism, you would have:
* overflow raises exceptions, which would have caused an exception that would've been caught, and the memory freed. This is, I'm handling appropiately an error I hadn't thought of.
* not enough memory, or other possible errors also produce exceptions and are nicely cleaned up.
* using a different channel to report success/failure and to return results leads to less confusion:
consider the case SOME_NUMBER was 0. perhaps, if the "do something" part does a loop on the arrays form 0 to SOME_NUMBER -1, it is valid (it would do nothing). malloc(0) returns NULL (see ANSI standars), so we would have treated that as an error (by checking if (!malloc()){... ) when it is not.
> I just say "gee, I feel sorry for those C
> programmers." Of course, garbage collection
> (Java's garbage collection is not conservative...
> but do even conservative garbage collectors have
> problems with non-circular structures?)
There are complete garbage collectors that get anything that's not referenced directly or indirectly from the "roots" (global vars and stack).
Anyway, my do that again with an open/close on any resource... a GC works just for memory. Files usually are automatically closed at end. But open/close transactions with more complex objects, possibly externals would bring the same problem: nice error checking is very hard to do in C. It's possible, but the language make it lots harder than it should. So most people get lazy and don't do it at all. Given that C is one of the main languages in OSS, the title of this article didn't surprise me at all.
I have just read it... It is nice, but it implements only half of the functionality: Definition of axioms over the abstract type (pre/post conditions and invariants), and checking of that assertions.
But it lacks the exception mechanism that makes that checking useful for writing robust program. It is a tool just for correctness, and DBC works toward correctness and robustness.
The Arianne exploded because the "horizontal bias", a 64 bit floating point number, was converted to a 16 bit signed integer producing an exception, because the conversion overflowed.
That exception was CAUGHT BY A HANDLER. The program didn't stop. But the handler above the faulty routine had no information about how to correct the problem, and given that the rocket was going off course, it self-destroyed (yes, that's a security measure).
So, the exception handling was used, and served its purpose of error-handling. The error, was using a 16 bit integer, that was not enough (they used that because they reused the code that they had used for the Arianne 4, whose trajectory had a bias that fitted into a 16bit signed int). If the rocket program would have continued, the arianne could've have crushed over some population. killing a lot of people.
So:
1) The program didn't stop abruptly (that's what exceptions are for, controlling program stop)
2) The exception mechanism possibly saved a lot of lives
3) The program did a reasonable work and ended in an expected way very well for a program with critical bugs in it.
> I've never had the opportunity to write any real
> software in Eiffel, but I always use a "poor man's
> DBC" in C++
Try BetterC (see my post above). You'll probably like it if you like Eiffel exception handling and DBC
> The initializing of variables is required (except
> maybe p1). Otherwise if the p1 or p2 allocations
> fail, the program will pass an uninitialized
> variable to free().
They wouldn't be uninitialized. They would be NULL, because that's what malloc returns in case of failure, and you assign the result of a malloc to the 3 pointers (that means, you have valid pointers xor NULL).
The repetition is frequent, that's true. But it's a better solution than creating a language pseudostructure for using when I need the same code, and another for when I don't need different code.
One usual case of different code is object constructors. The constructor starts creating a structura, and if it fails in the middle, it has to free it all; but when it finishes correctly it has to free nothing. The approach above works. I've been using it for years and I don't use a debugger.
One note: your "Sanefree" is 100% equivalent to ANSI free() (whose standard behavior on a NULL pointer is to do nothing).
Another "goto" approach. Dijkstra would throw up here, but what are you doing is like a crude exception handling. And people said "checking return codes is enough"...
I like this one a lot more... A lot of people will think the macros/goto are dirty, but they are actually providing a little exception handling capabilities. what you've done is simmilar to BetterC (see here).
But that is for my point that some exception handling is needed to do clean error checking in almost all non-trivial cases.
I like the initializing of p1,p2,p3. Initializing all vars helps to avoid heisenbugs, at a minimal efficiency cost.
I would've done free(p1), without the if(); free(NULL) is perfectly valid. But that's hard to know without a DBC approach (where you have info on pre/postcondition of your functions).
> would probably be better off using a higher level
> language with exceptions and a GC or something.
That's right. That's why I started this thread as a critique to all the people that said "well, checking return codes is enough".
When you run out of memory, you probably will quit, but it would be nice to do some some cleanup, like closing connections and files, saving the user unsaved work (or doing a backup), removing locks, etc. A "if (broken) exit(1)"approach is terrible at this.
> Exceptions and Design By Contract are all very
> good, but they still are bandaids on the problem
Of course. they're just a tool, but in the end you need a good programmer. What I mean is: A good programmer gets a lot of help from DBC.
What would be really nice is an authomatic derivation tool, so you mostly write specifications (even that doesn't solve the problem of getting the specification right). But that is too far away from current programming technology, so we must work with best bandaids possible to get some decent quality in the software (OSS or not).
In the code example you present, I see three cases
1) You're quite sure that y is not 0. that doesn't mean an if, it could probably be a precondition of the routine with the division. This is by far the most common case.
2) The 0 case is possible, and must be handled. then you have 'if y=0 handle special case, else a=x/y'
3) 0 case is invalid, but you have no guarantee that it won't happen. This usually means bad design in DBC, but in the case you must do that, you can put an exception handler
The range/domain situation is helped by strong typing.
In short: there are a lot of tools to help error handling. They're not perfect, but by using it we can improve software quality. Then, why not?